/* ** ** 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 ALOG_NDEBUG 0 #define ALOG_TAG "FimgExynos5" #include #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