You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
479 lines
12 KiB
479 lines
12 KiB
13 years ago
|
/*
|
||
|
**
|
||
|
** 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.
|
||
|
**
|
||
|
**
|
||
|
*/
|
||
|
|
||
|
///////////////////////////////////////////////////
|
||
|
// include
|
||
|
///////////////////////////////////////////////////
|
||
|
#define LOG_NDEBUG 0
|
||
|
#define LOG_TAG "FimgC210"
|
||
|
#include <utils/Log.h>
|
||
|
|
||
|
#include "FimgC210.h"
|
||
|
|
||
|
namespace android
|
||
|
{
|
||
|
|
||
|
//---------------------------------------------------------------------------//
|
||
|
// FimgC210
|
||
|
//---------------------------------------------------------------------------//
|
||
|
|
||
|
Mutex FimgC210::m_instanceLock;
|
||
|
int FimgC210::m_curFimgC210Index = 0;
|
||
|
int FimgC210::m_numOfInstance = 0;
|
||
|
FimgApi * FimgC210::m_ptrFimgApiList[NUMBER_FIMG_LIST] = {NULL, };
|
||
|
|
||
|
//---------------------------------------------------------------------------//
|
||
|
|
||
|
FimgC210::FimgC210()
|
||
|
: 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, "FimgC210");
|
||
|
}
|
||
|
|
||
|
FimgC210::~FimgC210()
|
||
|
{
|
||
|
delete m_lock;
|
||
|
}
|
||
|
|
||
|
FimgApi * FimgC210::CreateInstance()
|
||
|
{
|
||
|
Mutex::Autolock autolock(m_instanceLock);
|
||
|
|
||
|
FimgApi * ptrFimg = NULL;
|
||
|
|
||
|
// Using List like RingBuffer...
|
||
|
for(int i = m_curFimgC210Index; i < NUMBER_FIMG_LIST; i++) {
|
||
|
if(m_ptrFimgApiList[i] == NULL)
|
||
|
m_ptrFimgApiList[i] = new FimgC210;
|
||
|
|
||
|
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_curFimgC210Index = i + 1;
|
||
|
else
|
||
|
m_curFimgC210Index = 0;
|
||
|
|
||
|
ptrFimg = m_ptrFimgApiList[i];
|
||
|
goto CreateInstance_End;
|
||
|
}
|
||
|
|
||
|
CreateInstance_End :
|
||
|
|
||
|
return ptrFimg;
|
||
|
}
|
||
|
|
||
|
void FimgC210::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 {
|
||
|
FimgC210 * tempFimgC210 = (FimgC210 *)m_ptrFimgApiList[i];
|
||
|
delete tempFimgC210;
|
||
|
m_ptrFimgApiList[i] = NULL;
|
||
|
|
||
|
m_numOfInstance--;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void FimgC210::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 {
|
||
|
FimgC210 * tempFimgC210 = (FimgC210 *)m_ptrFimgApiList[i];
|
||
|
delete tempFimgC210;
|
||
|
m_ptrFimgApiList[i] = NULL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
bool FimgC210::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 FimgC210::t_Destroy(void)
|
||
|
{
|
||
|
bool ret = true;
|
||
|
|
||
|
if(m_DestroyG2D() == false) {
|
||
|
PRINT("%s::m_DestroyG2D() fail \n", __func__);
|
||
|
ret = false;
|
||
|
}
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
bool FimgC210::t_Stretch(FimgRect * src, FimgRect * dst, FimgClip * clip, FimgFlag * flag)
|
||
|
{
|
||
|
#ifdef CHECK_FIMGC210_PERFORMANCE
|
||
|
#define NUM_OF_STEP (10)
|
||
|
StopWatch stopWatch("CHECK_FIMGC210_PERFORMANCE");
|
||
|
const char * stopWatchName[NUM_OF_STEP];
|
||
|
nsecs_t stopWatchTime[NUM_OF_STEP];
|
||
|
int stopWatchIndex = 0;
|
||
|
#endif // CHECK_FIMGC210_PERFORMANCE
|
||
|
|
||
|
if(m_DoG2D(src, dst, clip, flag) == 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_FIMGC210_PERFORMANCE
|
||
|
m_PrintFimgC210Performance(src, dst, stopWatchIndex, stopWatchName, stopWatchTime);
|
||
|
#endif // CHECK_FIMGC210_PERFORMANCE
|
||
|
|
||
|
return true;
|
||
|
|
||
|
STRETCH_FAIL:
|
||
|
return false;
|
||
|
|
||
|
}
|
||
|
|
||
|
bool FimgC210::t_Sync(void)
|
||
|
{
|
||
|
#if 0
|
||
|
if(ioctl(m_g2dFd, G2D_SYNC) < 0) {
|
||
|
PRINT("%s::G2D_Sync fail\n", __func__);
|
||
|
goto SYNC_FAIL;
|
||
|
}
|
||
|
#else
|
||
|
if(m_PollG2D(&m_g2dPoll) == false)
|
||
|
{
|
||
|
PRINT("%s::m_PollG2D() fail\n", __func__);
|
||
|
goto SYNC_FAIL;
|
||
|
}
|
||
|
#endif
|
||
|
return true;
|
||
|
|
||
|
SYNC_FAIL:
|
||
|
return false;
|
||
|
|
||
|
}
|
||
|
|
||
|
bool FimgC210::t_Lock(void)
|
||
|
{
|
||
|
m_lock->lock();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool FimgC210::t_UnLock(void)
|
||
|
{
|
||
|
m_lock->unlock();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool FimgC210::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 FimgC210::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 FimgC210::m_DoG2D(FimgRect * src, FimgRect * dst, int rotateValue, int alphaValue, int colorKey)
|
||
|
bool FimgC210::m_DoG2D(FimgRect * src, FimgRect * dst, FimgClip * clip, FimgFlag * flag)
|
||
|
{
|
||
|
g2d_params params;
|
||
|
|
||
|
memcpy(¶ms.src_rect, src, sizeof(FimgRect));
|
||
|
memcpy(¶ms.dst_rect, dst, sizeof(FimgRect));
|
||
|
memcpy(¶ms.clip, clip, sizeof(FimgClip));
|
||
|
memcpy(¶ms.flag, flag, sizeof(FimgFlag));
|
||
|
|
||
|
if(ioctl(m_g2dFd, G2D_BLIT, ¶ms) < 0) {
|
||
|
#if 0
|
||
|
{
|
||
|
PRINT("---------------------------------------\n");
|
||
|
PRINT("src.color_format : %d \n", src->color_format);
|
||
|
PRINT("src.full_w : %d \n", src->full_w);
|
||
|
PRINT("src.full_h : %d \n", src->full_h);
|
||
|
PRINT("src.x : %d \n", src->x);
|
||
|
PRINT("src.y : %d \n", src->y);
|
||
|
PRINT("src.w : %d \n", src->w);
|
||
|
PRINT("src.h : %d \n", src->h);
|
||
|
|
||
|
PRINT("dst.color_format : %d \n", dst->color_format);
|
||
|
PRINT("dst.full_w : %d \n", dst->full_w);
|
||
|
PRINT("dst.full_h : %d \n", dst->full_h);
|
||
|
PRINT("dst.x : %d \n", dst->x);
|
||
|
PRINT("dst.y : %d \n", dst->y);
|
||
|
PRINT("dst.w : %d \n", dst->w);
|
||
|
PRINT("dst.h : %d \n", dst->h);
|
||
|
|
||
|
PRINT("flag.rotate_val : %d \n", flag->rotate_val);
|
||
|
PRINT("flag.alpha_val : %d(%d) \n", flag->alpha_val);
|
||
|
PRINT("flag.color_key_mode : %d(%d) \n", flag->color_key_mode, flag->color_key_val);
|
||
|
PRINT("---------------------------------------\n");
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
inline bool FimgC210::m_PollG2D(struct pollfd * events)
|
||
|
{
|
||
|
#define G2D_POLL_TIME (1000)
|
||
|
|
||
|
int ret;
|
||
|
|
||
|
ret = poll(events, 1, G2D_POLL_TIME);
|
||
|
|
||
|
if (ret < 0) {
|
||
|
if(ioctl(m_g2dFd, G2D_RESET) < 0) {
|
||
|
PRINT("%s::G2D_RESET fail\n", __func__);
|
||
|
}
|
||
|
PRINT("%s::poll fail \n", __func__);
|
||
|
return false;
|
||
|
}
|
||
|
else if (ret == 0) {
|
||
|
if(ioctl(m_g2dFd, G2D_RESET) < 0) {
|
||
|
PRINT("%s::G2D_RESET fail\n", __func__);
|
||
|
}
|
||
|
PRINT("%s::No data in %d milli secs..\n", __func__, G2D_POLL_TIME);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
inline bool FimgC210::m_CleanG2D(unsigned int virtAddr, unsigned int size)
|
||
|
{
|
||
|
g2d_dma_info dma_info = { virtAddr, size };
|
||
|
|
||
|
if(ioctl(m_g2dFd, G2D_DMA_CACHE_CLEAN, &dma_info) < 0) {
|
||
|
PRINT("%s::G2D_DMA_CACHE_CLEAN(%d, %d) fail\n", __func__, virtAddr, size);
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
inline bool FimgC210::m_FlushG2D (unsigned int virtAddr, unsigned int size)
|
||
|
{
|
||
|
g2d_dma_info dma_info = { virtAddr, size };
|
||
|
|
||
|
if(ioctl(m_g2dFd, G2D_DMA_CACHE_FLUSH, &dma_info) < 0) {
|
||
|
PRINT("%s::G2D_DMA_CACHE_FLUSH(%d, %d) fail\n", __func__, virtAddr, size);
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
inline int FimgC210::m_RotateValueFimgApi2FimgHw(int rotateValue)
|
||
|
{
|
||
|
switch (rotateValue) {
|
||
|
case ROTATE_0: return G2D_ROT_0;
|
||
|
case ROTATE_90: return G2D_ROT_90;
|
||
|
case ROTATE_180: return G2D_ROT_180;
|
||
|
case ROTATE_270: return G2D_ROT_270;
|
||
|
case ROTATE_X_FLIP: return G2D_ROT_X_FLIP;
|
||
|
case ROTATE_Y_FLIP: return G2D_ROT_Y_FLIP;
|
||
|
}
|
||
|
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
|
||
|
#ifdef CHECK_FIMGC210_PERFORMANCE
|
||
|
void FimgC210::m_PrintFimgC210Performance(FimgRect * src,
|
||
|
FimgRect * dst,
|
||
|
int stopWatchIndex,
|
||
|
const char * stopWatchName[],
|
||
|
nsecs_t stopWatchTime[])
|
||
|
{
|
||
|
char * srcColorFormat = "UNKNOW_COLOR_FORMAT";
|
||
|
char * dstColorFormat = "UNKNOW_COLOR_FORMAT";
|
||
|
|
||
|
switch(src->color_format)
|
||
|
{
|
||
|
case COLOR_FORMAT_RGB_565 :
|
||
|
srcColorFormat = "RGB_565";
|
||
|
break;
|
||
|
case COLOR_FORMAT_RGBA_8888 :
|
||
|
srcColorFormat = "RGBA_8888";
|
||
|
break;
|
||
|
case COLOR_FORMAT_RGBX_8888 :
|
||
|
srcColorFormat = "RGBX_8888";
|
||
|
break;
|
||
|
default :
|
||
|
srcColorFormat = "UNKNOW_COLOR_FORMAT";
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
switch(dst->color_format)
|
||
|
{
|
||
|
case COLOR_FORMAT_RGB_565 :
|
||
|
dstColorFormat = "RGB_565";
|
||
|
break;
|
||
|
case COLOR_FORMAT_RGBA_8888 :
|
||
|
dstColorFormat = "RGBA_8888";
|
||
|
break;
|
||
|
case COLOR_FORMAT_RGBX_8888 :
|
||
|
dstColorFormat = "RGBX_8888";
|
||
|
break;
|
||
|
default :
|
||
|
dstColorFormat = "UNKNOW_COLOR_FORMAT";
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
#ifdef CHECK_FIMGC210_CRITICAL_PERFORMANCE
|
||
|
#else
|
||
|
PRINT("===============================================\n");
|
||
|
PRINT("src[%3d, %3d | %10s] -> dst[%3d, %3d | %10s]\n",
|
||
|
src->w, src->h, srcColorFormat,
|
||
|
dst->w, dst->h, dstColorFormat);
|
||
|
#endif
|
||
|
|
||
|
nsecs_t totalTime = stopWatchTime[stopWatchIndex - 1];
|
||
|
|
||
|
for(int i = 0 ; i < stopWatchIndex; i++) {
|
||
|
nsecs_t sectionTime;
|
||
|
|
||
|
if(i != 0)
|
||
|
sectionTime = stopWatchTime[i] - stopWatchTime[i-1];
|
||
|
else
|
||
|
sectionTime = stopWatchTime[i];
|
||
|
|
||
|
#ifdef CHECK_FIMGC210_CRITICAL_PERFORMANCE
|
||
|
if(1500 < (sectionTime / 1000)) // check 1.5 mille second..
|
||
|
#endif
|
||
|
{
|
||
|
PRINT("===============================================\n");
|
||
|
PRINT("src[%3d, %3d | %10s] -> dst[%3d, %3d | %10s]\n",
|
||
|
src->w, src->h, srcColorFormat,
|
||
|
dst->w, dst->h, dstColorFormat);
|
||
|
|
||
|
PRINT("%20s : %5lld msec(%5.2f %%)\n",
|
||
|
stopWatchName[i],
|
||
|
sectionTime / 1000,
|
||
|
((float)sectionTime / (float)totalTime) * 100.0f);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
#endif // CHECK_FIMGC210_PERFORMANCE
|
||
|
|
||
|
//---------------------------------------------------------------------------//
|
||
|
// extern function
|
||
|
//---------------------------------------------------------------------------//
|
||
|
extern "C" struct FimgApi * createFimgApi()
|
||
|
{
|
||
|
if (fimgApiAutoFreeThread == 0)
|
||
|
fimgApiAutoFreeThread = new FimgApiAutoFreeThread();
|
||
|
else
|
||
|
fimgApiAutoFreeThread->SetOneMoreSleep();
|
||
|
|
||
|
return FimgC210::CreateInstance();
|
||
|
}
|
||
|
|
||
|
extern "C" void destroyFimgApi(FimgApi * ptrFimgApi)
|
||
|
{
|
||
|
// Dont' call DestrotInstance..
|
||
|
// return FimgC210::DestroyInstance(ptrFimgApi);
|
||
|
}
|
||
|
|
||
|
}; // namespace android
|