| /* |
| ** |
| ** 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 "FimgExynos4" |
| #include <utils/Log.h> |
| |
| #include "FimgExynos4.h" |
| |
| namespace android |
| { |
| Mutex FimgV4x::m_instanceLock; |
| unsigned 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) |
| { |
| memset(&(m_g2dPoll), 0, sizeof(struct pollfd)); |
| m_lock = new Mutex(Mutex::SHARED, "FimgV4x"); |
| } |
| |
| FimgV4x::~FimgV4x() |
| { |
| delete m_lock; |
| } |
| |
| FimgApi *FimgV4x::CreateInstance() |
| { |
| Mutex::Autolock autolock(m_instanceLock); |
| |
| FimgApi *ptrFimg = NULL; |
| |
| for(unsigned 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 |