|
|
|
/*
|
|
|
|
**
|
|
|
|
** Copyright 2009 Samsung Electronics Co, Ltd.
|
|
|
|
**
|
|
|
|
** Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
** you may not use this file except in compliance with the License.
|
|
|
|
** You may obtain a copy of the License at
|
|
|
|
**
|
|
|
|
** http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
**
|
|
|
|
** Unless required by applicable law or agreed to in writing, software
|
|
|
|
** distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
** See the License for the specific language governing permissions and
|
|
|
|
** limitations under the License.
|
|
|
|
**
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define LOG_NDEBUG 0
|
|
|
|
#define LOG_TAG "FimgExynos5"
|
|
|
|
#include <utils/Log.h>
|
|
|
|
|
|
|
|
#include "FimgExynos5.h"
|
|
|
|
|
|
|
|
namespace android
|
|
|
|
{
|
|
|
|
Mutex FimgV4x::m_instanceLock;
|
|
|
|
int FimgV4x::m_curFimgV4xIndex = 0;
|
|
|
|
int FimgV4x::m_numOfInstance = 0;
|
|
|
|
FimgApi * FimgV4x::m_ptrFimgApiList[NUMBER_FIMG_LIST] = {NULL, };
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------//
|
|
|
|
|
|
|
|
FimgV4x::FimgV4x()
|
|
|
|
: m_g2dFd(0),
|
|
|
|
m_g2dVirtAddr(NULL),
|
|
|
|
m_g2dSize(0),
|
|
|
|
m_g2dSrcVirtAddr(NULL),
|
|
|
|
m_g2dSrcSize(0),
|
|
|
|
m_g2dDstVirtAddr(NULL),
|
|
|
|
m_g2dDstSize(0)
|
|
|
|
{
|
|
|
|
m_lock = new Mutex(Mutex::SHARED, "FimgV4x");
|
|
|
|
}
|
|
|
|
|
|
|
|
FimgV4x::~FimgV4x()
|
|
|
|
{
|
|
|
|
delete m_lock;
|
|
|
|
}
|
|
|
|
|
|
|
|
FimgApi *FimgV4x::CreateInstance()
|
|
|
|
{
|
|
|
|
Mutex::Autolock autolock(m_instanceLock);
|
|
|
|
|
|
|
|
FimgApi *ptrFimg = NULL;
|
|
|
|
|
|
|
|
for(int i = m_curFimgV4xIndex; i < NUMBER_FIMG_LIST; i++) {
|
|
|
|
if (m_ptrFimgApiList[i] == NULL)
|
|
|
|
m_ptrFimgApiList[i] = new FimgV4x;
|
|
|
|
|
|
|
|
if (m_ptrFimgApiList[i]->FlagCreate() == false) {
|
|
|
|
if (m_ptrFimgApiList[i]->Create() == false) {
|
|
|
|
PRINT("%s::Create(%d) fail\n", __func__, i);
|
|
|
|
goto CreateInstance_End;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
m_numOfInstance++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i < NUMBER_FIMG_LIST - 1)
|
|
|
|
m_curFimgV4xIndex = i + 1;
|
|
|
|
else
|
|
|
|
m_curFimgV4xIndex = 0;
|
|
|
|
|
|
|
|
ptrFimg = m_ptrFimgApiList[i];
|
|
|
|
goto CreateInstance_End;
|
|
|
|
}
|
|
|
|
|
|
|
|
CreateInstance_End :
|
|
|
|
|
|
|
|
return ptrFimg;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FimgV4x::DestroyInstance(FimgApi * ptrFimgApi)
|
|
|
|
{
|
|
|
|
Mutex::Autolock autolock(m_instanceLock);
|
|
|
|
|
|
|
|
for(int i = 0; i < NUMBER_FIMG_LIST; i++) {
|
|
|
|
if (m_ptrFimgApiList[i] != NULL && m_ptrFimgApiList[i] == ptrFimgApi) {
|
|
|
|
if (m_ptrFimgApiList[i]->FlagCreate() == true && m_ptrFimgApiList[i]->Destroy() == false) {
|
|
|
|
PRINT("%s::Destroy() fail\n", __func__);
|
|
|
|
} else {
|
|
|
|
FimgV4x * tempFimgV4x = (FimgV4x *)m_ptrFimgApiList[i];
|
|
|
|
delete tempFimgV4x;
|
|
|
|
m_ptrFimgApiList[i] = NULL;
|
|
|
|
|
|
|
|
m_numOfInstance--;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void FimgV4x::DestroyAllInstance(void)
|
|
|
|
{
|
|
|
|
Mutex::Autolock autolock(m_instanceLock);
|
|
|
|
|
|
|
|
for(int i = 0; i < NUMBER_FIMG_LIST; i++) {
|
|
|
|
if (m_ptrFimgApiList[i] != NULL) {
|
|
|
|
if (m_ptrFimgApiList[i]->FlagCreate() == true
|
|
|
|
&& m_ptrFimgApiList[i]->Destroy() == false) {
|
|
|
|
PRINT("%s::Destroy() fail\n", __func__);
|
|
|
|
} else {
|
|
|
|
FimgV4x * tempFimgV4x = (FimgV4x *)m_ptrFimgApiList[i];
|
|
|
|
delete tempFimgV4x;
|
|
|
|
m_ptrFimgApiList[i] = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FimgV4x::t_Create(void)
|
|
|
|
{
|
|
|
|
bool ret = true;
|
|
|
|
|
|
|
|
if (m_CreateG2D() == false) {
|
|
|
|
PRINT("%s::m_CreateG2D() fail \n", __func__);
|
|
|
|
|
|
|
|
if (m_DestroyG2D() == false)
|
|
|
|
PRINT("%s::m_DestroyG2D() fail \n", __func__);
|
|
|
|
|
|
|
|
ret = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FimgV4x::t_Destroy(void)
|
|
|
|
{
|
|
|
|
bool ret = true;
|
|
|
|
|
|
|
|
if (m_DestroyG2D() == false) {
|
|
|
|
PRINT("%s::m_DestroyG2D() fail \n", __func__);
|
|
|
|
ret = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FimgV4x::t_Stretch(struct fimg2d_blit *cmd)
|
|
|
|
{
|
|
|
|
#ifdef CHECK_FIMGV4x_PERFORMANCE
|
|
|
|
#define NUM_OF_STEP (10)
|
|
|
|
StopWatch stopWatch("CHECK_FIMGV4x_PERFORMANCE");
|
|
|
|
const char *stopWatchName[NUM_OF_STEP];
|
|
|
|
nsecs_t stopWatchTime[NUM_OF_STEP];
|
|
|
|
int stopWatchIndex = 0;
|
|
|
|
#endif // CHECK_FIMGV4x_PERFORMANCE
|
|
|
|
|
|
|
|
if (m_DoG2D(cmd) == false) {
|
|
|
|
goto STRETCH_FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef G2D_NONE_BLOCKING_MODE
|
|
|
|
if (m_PollG2D(&m_g2dPoll) == false)
|
|
|
|
{
|
|
|
|
PRINT("%s::m_PollG2D() fail\n", __func__);
|
|
|
|
goto STRETCH_FAIL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef CHECK_FIMGV4x_PERFORMANCE
|
|
|
|
m_PrintFimgV4xPerformance(src, dst, stopWatchIndex, stopWatchName, stopWatchTime);
|
|
|
|
#endif // CHECK_FIMGV4x_PERFORMANCE
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
STRETCH_FAIL:
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FimgV4x::t_Sync(void)
|
|
|
|
{
|
|
|
|
if (m_PollG2D(&m_g2dPoll) == false)
|
|
|
|
{
|
|
|
|
PRINT("%s::m_PollG2D() fail\n", __func__);
|
|
|
|
goto SYNC_FAIL;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
|
|
|
|
SYNC_FAIL:
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FimgV4x::t_Lock(void)
|
|
|
|
{
|
|
|
|
m_lock->lock();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FimgV4x::t_UnLock(void)
|
|
|
|
{
|
|
|
|
m_lock->unlock();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FimgV4x::m_CreateG2D(void)
|
|
|
|
{
|
|
|
|
void * mmap_base;
|
|
|
|
|
|
|
|
if (m_g2dFd != 0) {
|
|
|
|
PRINT("%s::m_g2dFd(%d) is not 0 fail\n", __func__, m_g2dFd);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef G2D_NONE_BLOCKING_MODE
|
|
|
|
m_g2dFd = open(SEC_G2D_DEV_NAME, O_RDWR | O_NONBLOCK);
|
|
|
|
#else
|
|
|
|
m_g2dFd = open(SEC_G2D_DEV_NAME, O_RDWR);
|
|
|
|
#endif
|
|
|
|
if (m_g2dFd < 0) {
|
|
|
|
PRINT("%s::open(%s) fail(%s)\n", __func__, SEC_G2D_DEV_NAME, strerror(errno));
|
|
|
|
m_g2dFd = 0;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(&m_g2dPoll, 0, sizeof(m_g2dPoll));
|
|
|
|
m_g2dPoll.fd = m_g2dFd;
|
|
|
|
m_g2dPoll.events = POLLOUT | POLLERR;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FimgV4x::m_DestroyG2D(void)
|
|
|
|
{
|
|
|
|
if (m_g2dVirtAddr != NULL) {
|
|
|
|
munmap(m_g2dVirtAddr, m_g2dSize);
|
|
|
|
m_g2dVirtAddr = NULL;
|
|
|
|
m_g2dSize = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (0 < m_g2dFd) {
|
|
|
|
close(m_g2dFd);
|
|
|
|
}
|
|
|
|
m_g2dFd = 0;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FimgV4x::m_DoG2D(struct fimg2d_blit *cmd)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (ioctl(m_g2dFd, FIMG2D_BITBLT_BLIT, cmd) < 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool FimgV4x::m_PollG2D(struct pollfd * events)
|
|
|
|
{
|
|
|
|
#define G2D_POLL_TIME (1000)
|
|
|
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = poll(events, 1, G2D_POLL_TIME);
|
|
|
|
|
|
|
|
if (ret < 0) {
|
|
|
|
PRINT("%s::poll fail \n", __func__);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else if (ret == 0) {
|
|
|
|
PRINT("%s::No data in %d milli secs..\n", __func__, G2D_POLL_TIME);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------//
|
|
|
|
// extern function
|
|
|
|
//---------------------------------------------------------------------------//
|
|
|
|
extern "C" struct FimgApi * createFimgApi()
|
|
|
|
{
|
|
|
|
if (fimgApiAutoFreeThread == 0)
|
|
|
|
fimgApiAutoFreeThread = new FimgApiAutoFreeThread();
|
|
|
|
else
|
|
|
|
fimgApiAutoFreeThread->SetOneMoreSleep();
|
|
|
|
|
|
|
|
return FimgV4x::CreateInstance();
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void destroyFimgApi(FimgApi * ptrFimgApi)
|
|
|
|
{
|
|
|
|
// Dont' call DestroyInstance.
|
|
|
|
}
|
|
|
|
|
|
|
|
}; // namespace android
|