open source
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
/**
|
||||
@file JCImage.cpp
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2016_5_13
|
||||
*/
|
||||
|
||||
#include "JCImage.h"
|
||||
#include <util/Log.h>
|
||||
#include "JCImageManager.h"
|
||||
#include <util/JCCommonMethod.h>
|
||||
|
||||
namespace laya
|
||||
{
|
||||
JCImage::JCImage()
|
||||
{
|
||||
m_pFileResManager = NULL;
|
||||
m_pImageManager = NULL;
|
||||
m_nID = 0;
|
||||
m_nTouchTime = 0;
|
||||
m_bPushBitmapData = false;
|
||||
m_bPremultiplyAlpha = false;
|
||||
}
|
||||
JCImage::~JCImage()
|
||||
{
|
||||
m_kBitmapData.releaseData();
|
||||
}
|
||||
void JCImage::setManager(void* pFileResManager, JCImageManager* pImageManager)
|
||||
{
|
||||
m_pFileResManager = (JCFileResManager*)pFileResManager;
|
||||
m_pImageManager = pImageManager;
|
||||
}
|
||||
void JCImage::setPremultiplyAlpha(bool bPremultiplyAlpha)
|
||||
{
|
||||
m_bPremultiplyAlpha = bPremultiplyAlpha;
|
||||
}
|
||||
int JCImage::getWidth()
|
||||
{
|
||||
return m_kBitmapData.m_nWidth;
|
||||
}
|
||||
int JCImage::getHeight()
|
||||
{
|
||||
return m_kBitmapData.m_nHeight;
|
||||
}
|
||||
char* JCImage::getImageData()
|
||||
{
|
||||
return m_kBitmapData.m_pImageData;
|
||||
}
|
||||
void JCImage::setImageID(int nID)
|
||||
{
|
||||
m_nID = nID;
|
||||
m_kBitmapData.m_nImageID = nID;
|
||||
}
|
||||
bool JCImage::premultiplyAlpha(BitmapData* pBitmapData)
|
||||
{
|
||||
if (pBitmapData == NULL)return false;
|
||||
if (pBitmapData->m_nImageType != ImgType_png && pBitmapData->m_nImageType != ImgType_gif)return false;
|
||||
int w = pBitmapData->m_nWidth*4;
|
||||
int h = pBitmapData->m_nHeight;
|
||||
for (int i = 0; i < h; i++)
|
||||
{
|
||||
for (int j = 0; j < w; j+=4)
|
||||
{
|
||||
int n = i*w + j;
|
||||
unsigned char* base = (unsigned char*)(pBitmapData->m_pImageData+n);
|
||||
unsigned char alpha = base[3];
|
||||
if (alpha != 0xFF)
|
||||
{
|
||||
unsigned int red = base[0];
|
||||
unsigned int green = base[1];
|
||||
unsigned int blue = base[2];
|
||||
red = red * alpha / 255;
|
||||
green = green * alpha / 255;
|
||||
blue = blue * alpha / 255;
|
||||
base[0] = (unsigned char)red;
|
||||
base[1] = (unsigned char)green;
|
||||
base[2] = (unsigned char)blue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void JCImage::releaseBitmapData()
|
||||
{
|
||||
m_kBitmapData.releaseData();
|
||||
}
|
||||
bool JCImage::enableImage()
|
||||
{
|
||||
if (m_kBitmapData.m_pImageData == NULL)
|
||||
{
|
||||
if (m_pFileResManager)
|
||||
{
|
||||
JCFileRes* pRes = m_pFileResManager->getRes(m_sUrl);
|
||||
JCBuffer kBuffer;
|
||||
if (pRes && pRes->loadFromCache(kBuffer, false))
|
||||
{
|
||||
if (m_bPushBitmapData == false)
|
||||
{
|
||||
if (loadImageMemSync(kBuffer.m_pPtr, kBuffer.m_nLen, m_kBitmapData) == false)
|
||||
{
|
||||
LOGE("JCImage::gpuRestoreRes decode image error url=%s", m_sUrl.c_str());
|
||||
m_kBitmapData.releaseData();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int nImageLenght = m_kBitmapData.m_nWidth * m_kBitmapData.m_nHeight * 4;
|
||||
if (kBuffer.m_nLen == nImageLenght)
|
||||
{
|
||||
m_kBitmapData.m_pImageData = new char[nImageLenght];
|
||||
memcpy(m_kBitmapData.m_pImageData, kBuffer.m_pPtr, nImageLenght);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGE("JCImage::gpuRestoreRes image lenght != buffer.lenght");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGE("JCImage::gpuRestoreRes load file error url=%s", m_sUrl.c_str());
|
||||
m_kBitmapData.releaseData();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(m_bPremultiplyAlpha)
|
||||
{
|
||||
premultiplyAlpha(&m_kBitmapData);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
@file JCImage.h
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2016_5_13
|
||||
*/
|
||||
|
||||
#ifndef __JCImage_H__
|
||||
#define __JCImage_H__
|
||||
|
||||
#include <resource/JCFileResManager.h>
|
||||
#include <imageLib/JCImageRW.h>
|
||||
|
||||
namespace laya
|
||||
{
|
||||
class JCImageManager;
|
||||
/**
|
||||
* @brief
|
||||
*/
|
||||
class JCImage
|
||||
{
|
||||
public:
|
||||
|
||||
/** @brief构造函数
|
||||
*/
|
||||
JCImage();
|
||||
|
||||
/** @brief析构函数
|
||||
*/
|
||||
virtual ~JCImage();
|
||||
|
||||
void setManager(void* pFileResManager, JCImageManager* pImageManager);
|
||||
|
||||
int getWidth();
|
||||
|
||||
int getHeight();
|
||||
|
||||
void setImageID(int nID);
|
||||
|
||||
char* getImageData();
|
||||
|
||||
virtual bool enableImage();
|
||||
|
||||
void releaseBitmapData();
|
||||
|
||||
void setPremultiplyAlpha(bool bPremultiplyAlpha);
|
||||
|
||||
virtual void updateTexImage() {}
|
||||
|
||||
virtual bool isVideo() const { return false; }
|
||||
|
||||
public:
|
||||
|
||||
static bool premultiplyAlpha( BitmapData* pBitmapData );
|
||||
|
||||
public:
|
||||
double m_nTouchTime;
|
||||
BitmapData m_kBitmapData;
|
||||
std::string m_sUrl;
|
||||
JCFileResManager* m_pFileResManager;
|
||||
JCImageManager* m_pImageManager;
|
||||
bool m_bPushBitmapData; //是否为pushBitmapData的,正常的url为false,如果是js调用的pushBitmapData为true
|
||||
private:
|
||||
int m_nID;
|
||||
bool m_bPremultiplyAlpha;
|
||||
};
|
||||
}
|
||||
#endif //__JCImage_H__
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,244 @@
|
||||
/**
|
||||
@file JCImageManager.cpp
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2016_5_13
|
||||
*/
|
||||
|
||||
//包含头文件
|
||||
#include "JCImageManager.h"
|
||||
#include <util/Log.h>
|
||||
#include <util/JCCommonMethod.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
namespace laya
|
||||
{
|
||||
JCImageManager::JCImageManager( )
|
||||
{
|
||||
m_nDeleteMaxNum = 0;
|
||||
m_nCountImageID = 0;
|
||||
m_nReleaseSpaceTime = 20000;
|
||||
}
|
||||
JCImageManager::~JCImageManager()
|
||||
{
|
||||
clearAllImage();
|
||||
clearImageIDs();
|
||||
}
|
||||
void JCImageManager::setReleaseSpaceTime(int nTime)
|
||||
{
|
||||
m_nReleaseSpaceTime = nTime;
|
||||
LOGI("JCImageManager::setReleaseSpaceTime=%d",nTime);
|
||||
}
|
||||
void JCImageManager::setImage(int nID, JCImage* pImage)
|
||||
{
|
||||
bool bSucess = true;
|
||||
int nSize = (int)m_vImages.size();
|
||||
if (nID == nSize)
|
||||
{
|
||||
m_vImages.push_back( pImage );
|
||||
}
|
||||
else if( nID < nSize )
|
||||
{
|
||||
if (m_vImages[nID] == NULL)
|
||||
{
|
||||
m_vImages[nID] = pImage;
|
||||
}
|
||||
else
|
||||
{
|
||||
bSucess = false;
|
||||
LOGE("JCImageManager::setImage error m_vImages[%d] != NULL",nID );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int nOldSize = m_vImages.size();
|
||||
m_vImages.resize( nID + 1 );
|
||||
m_vImages[nID] = pImage;
|
||||
}
|
||||
if (bSucess)
|
||||
{
|
||||
pImage->setImageID(nID);
|
||||
pImage->m_nTouchTime = tmGetCurms();
|
||||
m_vOccupiedMemImages[nID] = pImage;
|
||||
}
|
||||
}
|
||||
JCImage* JCImageManager::getImage(int nID)
|
||||
{
|
||||
if ((size_t)nID < m_vImages.size())
|
||||
{
|
||||
return m_vImages[nID];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
bool JCImageManager::deleteImage(int nID)
|
||||
{
|
||||
if (nID == -1) return false;
|
||||
m_vDeleteList.push_back(nID);
|
||||
return true;
|
||||
}
|
||||
bool JCImageManager::_deleteImage(int nID)
|
||||
{
|
||||
if (nID == -1) return false;
|
||||
if (nID < (int)m_vImages.size())
|
||||
{
|
||||
if (m_vImages[nID])
|
||||
{
|
||||
removeImageFromMap(nID);
|
||||
delete m_vImages[nID];
|
||||
m_vImages[nID] = NULL;
|
||||
}
|
||||
}
|
||||
removeImageID(nID);
|
||||
return true;
|
||||
}
|
||||
void JCImageManager::removeImageFromMap(int nID)
|
||||
{
|
||||
MapImageIter iter = m_vOccupiedMemImages.find(nID);
|
||||
if (iter != m_vOccupiedMemImages.end())
|
||||
{
|
||||
iter = m_vOccupiedMemImages.erase(iter);
|
||||
}
|
||||
}
|
||||
void JCImageManager::clearAllImage()
|
||||
{
|
||||
for (VectorImageIter iter = m_vImages.begin(); iter != m_vImages.end(); iter++)
|
||||
{
|
||||
JCImage* pImage = *iter;
|
||||
if (pImage)
|
||||
{
|
||||
delete pImage;
|
||||
pImage = NULL;
|
||||
}
|
||||
}
|
||||
m_vImages.clear();
|
||||
m_vOccupiedMemImages.clear();
|
||||
}
|
||||
void JCImageManager::resetRenderThread()
|
||||
{
|
||||
clearAllImage();
|
||||
}
|
||||
void JCImageManager::removeImageID(int nID)
|
||||
{
|
||||
m_kMutex.lock();
|
||||
if (nID >= 0 && (size_t)nID < m_vImageIDs.size())
|
||||
{
|
||||
m_vImageIDs[nID] = -1;
|
||||
}
|
||||
m_kMutex.unlock();
|
||||
}
|
||||
void JCImageManager::clearImageIDs()
|
||||
{
|
||||
m_kMutex.lock();
|
||||
m_vImageIDs.clear();
|
||||
m_kMutex.unlock();
|
||||
}
|
||||
int JCImageManager::getImageID()
|
||||
{
|
||||
m_kMutex.lock();
|
||||
for (int i = 0,n = m_vImageIDs.size(); i < n; i++ )
|
||||
{
|
||||
if (m_vImageIDs[i] == -1)
|
||||
{
|
||||
m_vImageIDs[i] = i;
|
||||
m_kMutex.unlock();
|
||||
return i;
|
||||
}
|
||||
}
|
||||
m_vImageIDs.push_back(m_nCountImageID);
|
||||
m_kMutex.unlock();
|
||||
return m_nCountImageID++;
|
||||
}
|
||||
void JCImageManager::resetJSThread()
|
||||
{
|
||||
clearImageIDs();
|
||||
m_nCountImageID = 0;
|
||||
}
|
||||
void JCImageManager::_batchHandleDeleteImage()
|
||||
{
|
||||
if (m_vDeleteList.size() <= 0)return;
|
||||
int n = m_vDeleteList.size();
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
_deleteImage(m_vDeleteList[i]);
|
||||
}
|
||||
if (n > m_nDeleteMaxNum)
|
||||
{
|
||||
m_nDeleteMaxNum = n;
|
||||
m_vDeleteList.reserve(m_nDeleteMaxNum);
|
||||
}
|
||||
m_vDeleteList.clear();
|
||||
}
|
||||
void JCImageManager::update(int nFrameCount)
|
||||
{
|
||||
_batchHandleDeleteImage();
|
||||
if (nFrameCount % 5 == 0)
|
||||
{
|
||||
if (m_vOccupiedMemImages.size() > 0)
|
||||
{
|
||||
double nCurentTime = tmGetCurms();
|
||||
for (MapImageIter iter = m_vOccupiedMemImages.begin(); iter != m_vOccupiedMemImages.end(); )
|
||||
{
|
||||
JCImage* pImage = iter->second;
|
||||
if (pImage && (nCurentTime - pImage->m_nTouchTime) > m_nReleaseSpaceTime)
|
||||
{
|
||||
pImage->releaseBitmapData();
|
||||
iter = m_vOccupiedMemImages.erase(iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void JCImageManager::printCorpseImages(const char* sFileName)
|
||||
{
|
||||
#ifdef WIN32
|
||||
FILE* fp = fopen(sFileName, "w");
|
||||
char sBuffer[2048] = { 0 };
|
||||
int nSizeCount = 0;
|
||||
for (int i = 0, n = m_vImages.size(); i < n; i++ )
|
||||
{
|
||||
JCImage* pImage = m_vImages[i];
|
||||
if (pImage && pImage->m_kBitmapData.m_pImageData )
|
||||
{
|
||||
int nCurrentSize = pImage->m_kBitmapData.m_nHeight*pImage->m_kBitmapData.m_nWidth * 4;
|
||||
nSizeCount += nCurrentSize;
|
||||
sprintf(sBuffer, "image id=%d,memorySize=%d,url=%s\n", i, nCurrentSize,pImage->m_sUrl.c_str());
|
||||
LOGI(sBuffer);
|
||||
if (fp)
|
||||
{
|
||||
fputs(sBuffer, fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
sprintf(sBuffer, "memory size count=%d", nSizeCount);
|
||||
LOGI(sBuffer);
|
||||
if (fp)
|
||||
{
|
||||
fputs(sBuffer, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
#else
|
||||
char sBuffer[2048] = { 0 };
|
||||
int nSizeCount = 0;
|
||||
for (int i = 0, n = m_vImages.size(); i < n; i++)
|
||||
{
|
||||
JCImage* pImage = m_vImages[i];
|
||||
if (pImage && pImage->m_kBitmapData.m_pImageData)
|
||||
{
|
||||
int nCurrentSize = pImage->m_kBitmapData.m_nHeight*pImage->m_kBitmapData.m_nWidth * 4;
|
||||
nSizeCount += nCurrentSize;
|
||||
LOGI("image id=%d,memorySize=%d,url=%s\n", i, nCurrentSize, pImage->m_sUrl.c_str());
|
||||
}
|
||||
}
|
||||
LOGI(sBuffer, "memory size count=%d", nSizeCount);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
@file JCImageManager.h
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2016_5_13
|
||||
*/
|
||||
|
||||
#ifndef __JCImageManager_H__
|
||||
#define __JCImageManager_H__
|
||||
|
||||
#include "../Image/JCImage.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*/
|
||||
namespace laya
|
||||
{
|
||||
class JCImageManager
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::vector<JCImage*> VectorImage;
|
||||
typedef VectorImage::iterator VectorImageIter;
|
||||
|
||||
typedef std::vector<int> VectorImageID;
|
||||
typedef VectorImageID::iterator VectorImageIDIter;
|
||||
|
||||
typedef std::map<int, JCImage*> MapImage;
|
||||
typedef MapImage::iterator MapImageIter;
|
||||
|
||||
public:
|
||||
|
||||
/** @brief构造函数
|
||||
*/
|
||||
JCImageManager();
|
||||
|
||||
/** @brief析构函数
|
||||
*/
|
||||
~JCImageManager();
|
||||
|
||||
void setImage( int nID,JCImage* pImage );
|
||||
|
||||
bool deleteImage( int nID );
|
||||
|
||||
void clearAllImage();
|
||||
|
||||
JCImage* getImage( int nID );
|
||||
|
||||
void resetRenderThread();
|
||||
|
||||
void printCorpseImages( const char* sFileName );
|
||||
|
||||
public:
|
||||
|
||||
int getImageID();
|
||||
|
||||
void resetJSThread();
|
||||
|
||||
void removeImageID(int nID);
|
||||
|
||||
void clearImageIDs();
|
||||
|
||||
void removeImageFromMap( int nID );
|
||||
|
||||
void update(int nFrameCount);
|
||||
|
||||
void setReleaseSpaceTime(int nTime);
|
||||
|
||||
private:
|
||||
|
||||
void _batchHandleDeleteImage();
|
||||
|
||||
bool _deleteImage(int nID);
|
||||
|
||||
public:
|
||||
|
||||
VectorImageID m_vImageIDs; ///<imageID
|
||||
|
||||
VectorImage m_vImages; ///<完整的Image的容器
|
||||
|
||||
//当Image把数据merge到显卡上,Image的内存数据就会删除掉,如果迟迟没有merge到显卡,这部分数据只会保留一段时间
|
||||
MapImage m_vOccupiedMemImages; ///<占用内存的Image容器
|
||||
|
||||
int m_nCountImageID; ///<imageID
|
||||
|
||||
int m_nReleaseSpaceTime; ///<删除的间隔时间
|
||||
|
||||
std::recursive_mutex m_kMutex; ///<线程锁
|
||||
|
||||
private:
|
||||
|
||||
int m_nDeleteMaxNum; ///<为了效率保存最大的值
|
||||
std::vector<int> m_vDeleteList; ///<删除列表
|
||||
|
||||
};
|
||||
}
|
||||
#endif //__JCImageManager_H__
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
@file JCImage.cpp
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2016_5_13
|
||||
*/
|
||||
|
||||
#include "JCVideo.h"
|
||||
#include <util/Log.h>
|
||||
#include "JCImageManager.h"
|
||||
#include <util/JCCommonMethod.h>
|
||||
|
||||
namespace laya
|
||||
{
|
||||
JCVideo::JCVideo() : JCImage()
|
||||
{
|
||||
m_kBitmapData.m_pImageData = 0;
|
||||
m_videoHandler = nullptr;
|
||||
}
|
||||
JCVideo::~JCVideo()
|
||||
{
|
||||
if(m_videoHandler)
|
||||
{
|
||||
delete m_videoHandler;
|
||||
m_videoHandler = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void JCVideo::setVideoHandler(IVideoHandler* handler)
|
||||
{
|
||||
m_videoHandler = handler;
|
||||
}
|
||||
|
||||
void JCVideo::updateTexImage()
|
||||
{
|
||||
if (m_videoHandler && m_videoHandler->isFrameUpdated())
|
||||
{
|
||||
m_videoHandler->updateBitmapData(&m_kBitmapData);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
@file JCImage.h
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2016_5_13
|
||||
*/
|
||||
|
||||
#ifndef __JCVideo_H__
|
||||
#define __JCVideo_H__
|
||||
|
||||
#include <resource/JCFileResManager.h>
|
||||
#include <imageLib/JCImageRW.h>
|
||||
#include "JCImage.h"
|
||||
|
||||
namespace laya
|
||||
{
|
||||
class JCImageManager;
|
||||
/**
|
||||
* @brief
|
||||
*/
|
||||
|
||||
class IVideoHandler
|
||||
{
|
||||
public:
|
||||
virtual ~IVideoHandler() {}
|
||||
|
||||
virtual bool isFrameUpdated() = 0;
|
||||
virtual void updateBitmapData(BitmapData* bitmapData) = 0;
|
||||
};
|
||||
|
||||
|
||||
class JCVideo : public JCImage
|
||||
{
|
||||
public:
|
||||
|
||||
/** @brief构造函数
|
||||
*/
|
||||
JCVideo();
|
||||
|
||||
/** @brief析构函数
|
||||
*/
|
||||
~JCVideo();
|
||||
|
||||
void setVideoHandler(IVideoHandler* handler);
|
||||
|
||||
virtual bool isVideo() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void updateTexImage();
|
||||
virtual bool enableImage() override { return true; }
|
||||
|
||||
private:
|
||||
IVideoHandler* m_videoHandler;
|
||||
};
|
||||
}
|
||||
#endif //__JCVideo_H__
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
Reference in New Issue
Block a user