open source
This commit is contained in:
@@ -0,0 +1,440 @@
|
||||
/**
|
||||
@file JSImage.cpp
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2014_11_17
|
||||
*/
|
||||
|
||||
//包含头文件
|
||||
#include "JSImage.h"
|
||||
#include <util/Log.h>
|
||||
#ifndef WEBASM
|
||||
#include <util/JCMemorySurvey.h>
|
||||
#include "../JSInterface/JSInterface.h"
|
||||
#include "../../JCScriptRuntime.h"
|
||||
#include <downloadCache/JCFileSource.h>
|
||||
#include <resource/JCFileResManager.h>
|
||||
|
||||
#include "JSRuntime.h"
|
||||
#include <fileSystem/JCFileSystem.h>
|
||||
#else
|
||||
#include "../../JCScrpitRuntimeWASM.h"
|
||||
#endif
|
||||
|
||||
#include "../../JCConch.h"
|
||||
#include "../../JCSystemConfig.h"
|
||||
|
||||
#include <LayaGL/JCLayaGLDispatch.h>
|
||||
#include <util/JCCrypto.h>
|
||||
|
||||
namespace laya
|
||||
{
|
||||
#ifndef WEBASM
|
||||
ADDJSCLSINFO(JSImage, JSObjNode);
|
||||
#endif
|
||||
JSImage::JSImage()
|
||||
{
|
||||
m_pImage = new JCImage();
|
||||
m_nID = JCConch::s_pConchRender->m_pImageManager->getImageID();
|
||||
#ifndef WEBASM
|
||||
m_pImage->setManager(JCConch::s_pConchRender->m_pFileResManager, JCConch::s_pConchRender->m_pImageManager);
|
||||
m_CallbackRef.reset(new int(1));
|
||||
m_bComplete = false;
|
||||
m_pClsInfo = &JSImage::JSCLSINFO;
|
||||
m_nDownloadState = 0;
|
||||
#else
|
||||
m_pImage->setManager(JCConch::s_pConchRender->m_pAtlasManager, JCConch::s_pConchRender->m_pTextureManager, NULL, JCConch::s_pConchRender->m_pImageManager);
|
||||
#endif
|
||||
}
|
||||
JSImage::~JSImage()
|
||||
{
|
||||
#ifndef WEBASM
|
||||
m_pOnLoad.Reset();
|
||||
m_pOnError.Reset();
|
||||
m_pObj.Reset();
|
||||
JCMemorySurvey::GetInstance()->releaseClass( "image",this );
|
||||
#endif
|
||||
destroy();
|
||||
}
|
||||
void JSImage::destroy()
|
||||
{
|
||||
if (m_pImage)
|
||||
{
|
||||
//通知渲染线程
|
||||
deleteImageOnRenderThread(m_nID);
|
||||
}
|
||||
}
|
||||
void JSImage::releaseTexture()
|
||||
{
|
||||
if (m_pImage)
|
||||
{
|
||||
releaseImageOnRenderThread(m_nID);
|
||||
}
|
||||
}
|
||||
#ifndef WEBASM
|
||||
void JSImage::onLoaded(std::weak_ptr<int> callbackref)
|
||||
{
|
||||
std::function<void(void)> pFunction = std::bind(&JSImage::onLoadedCallJSFunction,this, callbackref);
|
||||
JCScriptRuntime::s_JSRT->m_pPoster->postToJS(pFunction);
|
||||
}
|
||||
void JSImage::onError( int p_nError,std::weak_ptr<int> callbackref )
|
||||
{
|
||||
std::function<void(void)> pFunction = std::bind(&JSImage::onErrorCallJSFunction,this,p_nError, callbackref);
|
||||
JCScriptRuntime::s_JSRT->m_pPoster->postToJS( pFunction );
|
||||
}
|
||||
void JSImage::onLoadedCallJSFunction(std::weak_ptr<int> callbackref)
|
||||
{
|
||||
if (!callbackref.lock()) return;
|
||||
if (JCScriptRuntime::s_JSRT->m_bIsExit == true)return;
|
||||
if (!IsMyJsEnv()) return;
|
||||
|
||||
if (GetWidth() <= 0 || GetHeight() <= 0|| m_pImage->m_kBitmapData.m_pImageData==NULL) {
|
||||
m_pOnError.Call(500);
|
||||
}
|
||||
else {
|
||||
int nMemSize = GetWidth() * GetHeight() * 4 + 272;
|
||||
AdjustAmountOfExternalAllocatedMemory(nMemSize);
|
||||
JCMemorySurvey::GetInstance()->newClass("image", 1024, this);
|
||||
m_pImage->m_sUrl = m_sUrl;
|
||||
//通知渲染线程
|
||||
createImageOnRenderThread(m_nID, m_pImage);
|
||||
m_bComplete = true;
|
||||
m_pOnLoad.Call();
|
||||
}
|
||||
}
|
||||
void JSImage::onErrorCallJSFunction( int p_nError,std::weak_ptr<int> callbackref )
|
||||
{
|
||||
if (!callbackref.lock())return;
|
||||
if (JCScriptRuntime::s_JSRT->m_bIsExit == true)return;
|
||||
if (!IsMyJsEnv())return;
|
||||
LOGW("download image file error! %s\n", m_sUrl.c_str());
|
||||
m_pOnError.Call(p_nError);
|
||||
}
|
||||
bool JSImage::getComplete()
|
||||
{
|
||||
return m_bComplete;
|
||||
}
|
||||
void JSImage::SetOnload(JSValueAsParam p_pFunction )
|
||||
{
|
||||
m_pOnLoad.set(onloadid,this,p_pFunction);
|
||||
}
|
||||
JsValue JSImage::GetOnload()
|
||||
{
|
||||
return m_pOnLoad.getJsObj();
|
||||
}
|
||||
void JSImage::SetOnError(JSValueAsParam p_pFunction )
|
||||
{
|
||||
m_pOnError.set(onerrorid,this,p_pFunction);
|
||||
}
|
||||
JsValue JSImage::GetOnError()
|
||||
{
|
||||
return m_pOnError.getJsObj();
|
||||
}
|
||||
JsValue JSImage::getObj()
|
||||
{
|
||||
return m_pObj.getJsObj();
|
||||
}
|
||||
void JSImage::setObj(JSValueAsParam obj)
|
||||
{
|
||||
m_pObj.set(objid,this,obj);
|
||||
}
|
||||
const char* JSImage::getSrc()
|
||||
{
|
||||
return m_sUrl.c_str();
|
||||
}
|
||||
bool JSImage::syncRestoreResource()
|
||||
{
|
||||
//if (!m_pImage || !m_pImage->m_pImageFile ) return false;
|
||||
//return m_pImage->m_pImageFile->downloadImage(true);
|
||||
return false;
|
||||
}
|
||||
void JSImage::setSrc( const char* p_sSrc )
|
||||
{
|
||||
if (!p_sSrc) return;
|
||||
m_sUrl = p_sSrc;
|
||||
std::weak_ptr<int> cbref(m_CallbackRef);
|
||||
downloadImage( false );
|
||||
}
|
||||
void JSImage::onDecodeEnd(BitmapData& p_bmp, std::weak_ptr<int>& callbackref)
|
||||
{
|
||||
if (!callbackref.lock())
|
||||
{
|
||||
if (p_bmp.m_pImageData)
|
||||
{
|
||||
delete[] p_bmp.m_pImageData;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (m_pImage && m_pImage->m_kBitmapData.m_pImageData)
|
||||
{
|
||||
m_pImage->m_kBitmapData.releaseData();
|
||||
m_pImage->m_kBitmapData.m_pImageData = NULL;
|
||||
}
|
||||
m_pImage->m_kBitmapData = p_bmp;
|
||||
onLoaded(callbackref);
|
||||
}
|
||||
void JSImage::onDecodeEndDecThread(BitmapData p_bmp, std::weak_ptr<int>& callbackref)
|
||||
{
|
||||
JCScriptRuntime::s_JSRT->m_pPoster->postToJS(std::bind(&JSImage::onDecodeEnd, this, p_bmp, callbackref));
|
||||
}
|
||||
void JSImage::onDownloadOK(JCResStateDispatcher* p_pRes, bool p_bDecodeSync, std::weak_ptr<int>& callbackref)
|
||||
{
|
||||
m_nDownloadState = 0;
|
||||
JCFileRes* pFileRes = (JCFileRes*)p_pRes;
|
||||
if (pFileRes->m_pBuffer.get())
|
||||
{
|
||||
releaseThis();
|
||||
//同步加载
|
||||
if (p_bDecodeSync)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
imgDecodeCB cb = std::bind(&JSImage::onDecodeEndDecThread, this, std::placeholders::_1, callbackref);
|
||||
loadImageMemASync(pFileRes->m_pBuffer, pFileRes->m_nLength, cb);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
onDownloadError(p_pRes, 1, callbackref);
|
||||
}
|
||||
}
|
||||
void JSImage::onDownloadError(JCResStateDispatcher*, int e, std::weak_ptr<int>& callbackref)
|
||||
{
|
||||
if (!callbackref.lock())return;
|
||||
releaseThis();
|
||||
m_nDownloadState = 0;
|
||||
onError(e,callbackref);
|
||||
}
|
||||
bool JSImage::downloadImage(bool p_bSyncDecode)
|
||||
{
|
||||
if (m_nDownloadState == 1)return false;
|
||||
m_nDownloadState = 1;
|
||||
//TODO 要处理本地文件的情况
|
||||
std::weak_ptr<int> cbref(m_CallbackRef);
|
||||
JCFileRes* pRes = JCScriptRuntime::s_JSRT->m_pFileResMgr->getRes(m_sUrl);
|
||||
pRes->setOnReadyCB(std::bind(&JSImage::onDownloadOK, this, std::placeholders::_1, false, cbref));
|
||||
pRes->setOnErrorCB(std::bind(&JSImage::onDownloadError, this, std::placeholders::_1, std::placeholders::_2, cbref));
|
||||
retainThis();
|
||||
return true;
|
||||
}
|
||||
int JSImage::GetWidth()
|
||||
{
|
||||
return m_pImage->getWidth();
|
||||
}
|
||||
int JSImage::GetHeight()
|
||||
{
|
||||
return m_pImage->getHeight();
|
||||
}
|
||||
void JSImage::setPremultiplyAlpha(bool bPremultiplyAlpha)
|
||||
{
|
||||
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_DOUBLE)
|
||||
{
|
||||
JCScriptRuntime::s_JSRT->flushSharedCmdBuffer();
|
||||
JCCommandEncoderBuffer* pCmd = JCScriptRuntime::s_JSRT->m_pRenderCmd;
|
||||
pCmd->append(LAYA_SET_PREMULTIPLY_ALPHA);
|
||||
pCmd->append(m_nID);
|
||||
pCmd->append((int)bPremultiplyAlpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
JCImage* pImage = JCConch::s_pConchRender->m_pImageManager->getImage(m_nID);
|
||||
if (pImage)
|
||||
{
|
||||
pImage->setPremultiplyAlpha(bPremultiplyAlpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
void JSImage::putBitmapDataJS(JSValueAsParam pArrayBuffer, int width, int height)
|
||||
{
|
||||
char* pArrayBufferPtr = NULL;
|
||||
int nABLen = 0;
|
||||
bool bIsArrayBuffer = extractJSAB(pArrayBuffer, pArrayBufferPtr, nABLen);
|
||||
if (bIsArrayBuffer)
|
||||
{
|
||||
if (nABLen >= width * height * 4)
|
||||
{
|
||||
putBitmapData(pArrayBufferPtr,width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGE("JSImage::pushBitmapData array buffer size < width * height * 4");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGE("JSImage::pushBitmapData param is not an ArrayBuffer!");
|
||||
}
|
||||
}
|
||||
|
||||
static void deleter(char* p)
|
||||
{
|
||||
//不删除 JS保证在onDecodeEndDecThread前pArrayBuffer不垃圾回收
|
||||
}
|
||||
|
||||
void JSImage::putDataJS(JSValueAsParam pArrayBuffer)
|
||||
{
|
||||
char* pArrayBufferPtr = NULL;
|
||||
int nABLen = 0;
|
||||
bool bIsArrayBuffer = extractJSAB(pArrayBuffer, pArrayBufferPtr, nABLen);
|
||||
if (bIsArrayBuffer)
|
||||
{
|
||||
if (nABLen <= 0)
|
||||
return;
|
||||
//设置url的名字
|
||||
char sCachePath[1024];
|
||||
memset(sCachePath, 0, 1024);
|
||||
sprintf(sCachePath, "%s/%d.LayaBoxImg", JCConch::s_pConch->m_sCachePath.c_str(), m_nID);
|
||||
m_sUrl = sCachePath;
|
||||
std::weak_ptr<int> cbref(m_CallbackRef);
|
||||
imgDecodeCB cb = std::bind(&JSImage::onDecodeEndDecThread, this, std::placeholders::_1, cbref);
|
||||
std::shared_ptr<char> pBuffer(pArrayBufferPtr, deleter);
|
||||
loadImageMemASync(pBuffer, nABLen, cb);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGE("JSImage::putData param is not an ArrayBuffer!");
|
||||
}
|
||||
}
|
||||
void JSImage::setBase64(char* base64)
|
||||
{
|
||||
if (!base64)
|
||||
return;
|
||||
//设置url的名字
|
||||
char sCachePath[1024];
|
||||
memset(sCachePath, 0, 1024);
|
||||
sprintf(sCachePath, "%s/%d.LayaBoxImg", JCConch::s_pConch->m_sCachePath.c_str(), m_nID);
|
||||
m_sUrl = sCachePath;
|
||||
std::weak_ptr<int> cbref(m_CallbackRef);
|
||||
imgDecodeCB cb = std::bind(&JSImage::onDecodeEndDecThread, this, std::placeholders::_1, cbref);
|
||||
int length = 0;
|
||||
std::shared_ptr<char> pBuffer(base64_decode((const unsigned char*)base64, strlen(base64), &length));
|
||||
loadImageMemASync(pBuffer, length, cb);
|
||||
}
|
||||
void JSImage::putBitmapData(char* pData, int width, int height )
|
||||
{
|
||||
if (m_pImage && m_pImage->m_kBitmapData.m_pImageData)
|
||||
{
|
||||
m_pImage->m_kBitmapData.releaseData();
|
||||
m_pImage->m_kBitmapData.m_pImageData = NULL;
|
||||
}
|
||||
m_pImage->m_kBitmapData.m_nWidth = width;
|
||||
m_pImage->m_kBitmapData.m_nHeight = height;
|
||||
m_pImage->m_kBitmapData.m_pImageData = new char[width * height * 4];
|
||||
memcpy(m_pImage->m_kBitmapData.m_pImageData, pData, width*height * 4);
|
||||
//设置url的名字
|
||||
char sCachePath[1024];
|
||||
memset(sCachePath, 0, 1024);
|
||||
sprintf(sCachePath,"%s/%d.LayaBoxImg", JCConch::s_pConch->m_sCachePath.c_str(),m_nID);
|
||||
//写入文件
|
||||
writeFileSync1(sCachePath, pData, width*height * 4);
|
||||
m_sUrl = sCachePath;
|
||||
m_pImage->m_bPushBitmapData = true;
|
||||
onLoaded(m_CallbackRef);
|
||||
}
|
||||
JsValue JSImage::getImageData( int p_nX,int p_nY,int p_nW,int p_nH )
|
||||
{
|
||||
if( m_bComplete == false ) return JSP_TO_JS_NULL;
|
||||
if( m_pImage == NULL ) return JSP_TO_JS_NULL;
|
||||
BitmapData* pImg = &(m_pImage->m_kBitmapData);
|
||||
if( pImg )
|
||||
{
|
||||
if( p_nX < 0 || p_nY < 0 || p_nX >= pImg->m_nWidth || p_nY >= pImg->m_nHeight )return JSP_TO_JS_NULL;
|
||||
if( ( p_nX + p_nW ) > pImg->m_nWidth || ( p_nY + p_nH ) > pImg->m_nHeight )return JSP_TO_JS_NULL;
|
||||
|
||||
if (pImg->m_pImageData != NULL || (pImg->m_pImageData == NULL && m_pImage->enableImage()))
|
||||
{
|
||||
if( p_nX == 0 && p_nY == 0 && p_nW == pImg->m_nWidth && p_nH == pImg->m_nHeight )
|
||||
{
|
||||
return createJSAB( (char *)(pImg->m_pImageData),pImg->m_nWidth * pImg->m_nHeight * 4 );
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char* pTemp = (unsigned char *)(pImg->m_pImageData);
|
||||
int nSize = p_nH * p_nW * 4;
|
||||
int nDstLine = p_nW*4;
|
||||
int nSrcLine = pImg->m_nWidth*4;
|
||||
unsigned char* pBuffer = new unsigned char[nSize];
|
||||
for( int i = 0; i < p_nH; i++ )
|
||||
{
|
||||
memcpy(&pBuffer[nDstLine*i],&pTemp[nSrcLine*(i+p_nY)+p_nX*4],nDstLine);
|
||||
}
|
||||
return createJSAB( (char*)pBuffer,nSize );
|
||||
}
|
||||
}
|
||||
}
|
||||
return JSP_TO_JS_NULL;
|
||||
}
|
||||
#endif
|
||||
void JSImage::setImageInfo(const char* sUrl, int w, int h)
|
||||
{
|
||||
#ifdef WEBASM
|
||||
if(sUrl)m_pImage->m_sUrl = sUrl;
|
||||
m_pImage->m_kBitmapData.m_nWidth = w;
|
||||
m_pImage->m_kBitmapData.m_nHeight = h;
|
||||
createImageOnRenderThread(m_nID, m_pImage);
|
||||
#endif
|
||||
}
|
||||
int JSImage::getImageID()
|
||||
{
|
||||
return m_nID;
|
||||
}
|
||||
#ifndef WEBASM
|
||||
void JSImage::exportJS()
|
||||
{
|
||||
JSP_CLASS("conchImage", JSImage);
|
||||
JSP_ADD_PROPERTY_RO(conchImgId, JSImage, getImageID);
|
||||
JSP_ADD_PROPERTY_RO(width, JSImage, GetWidth);
|
||||
JSP_ADD_PROPERTY_RO(height, JSImage, GetHeight);
|
||||
JSP_ADD_METHOD("setBase64", JSImage::setBase64);
|
||||
JSP_ADD_PROPERTY(src, JSImage, getSrc, setSrc);
|
||||
JSP_ADD_PROPERTY(_onload, JSImage, GetOnload, SetOnload);
|
||||
JSP_ADD_PROPERTY(onload, JSImage, GetOnload, SetOnload);
|
||||
JSP_ADD_PROPERTY(onerror, JSImage, GetOnError, SetOnError);
|
||||
JSP_ADD_PROPERTY(obj, JSImage, getObj, setObj);
|
||||
JSP_ADD_PROPERTY_RO(complete, JSImage, getComplete);
|
||||
JSP_ADD_METHOD("getImageID", JSImage::getImageID);
|
||||
JSP_ADD_METHOD("setSrc", JSImage::setSrc);
|
||||
JSP_ADD_METHOD("getImageData", JSImage::getImageData);
|
||||
JSP_ADD_METHOD("putBitmapData", JSImage::putBitmapDataJS);
|
||||
JSP_ADD_METHOD("putData", JSImage::putDataJS);
|
||||
JSP_ADD_METHOD("setPremultiplyAlpha", JSImage::setPremultiplyAlpha);
|
||||
JSP_ADD_METHOD("syncRestoreResource", JSImage::syncRestoreResource);
|
||||
JSP_ADD_METHOD("destroy", JSImage::destroy);
|
||||
JSP_INSTALL_CLASS("conchImage", JSImage);
|
||||
}
|
||||
#endif
|
||||
void JSImage::createImageOnRenderThread(int nID, JCImage* pImage)
|
||||
{
|
||||
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_DOUBLE)
|
||||
{
|
||||
JCScriptRuntime::s_JSRT->flushSharedCmdBuffer();
|
||||
JCCommandEncoderBuffer* pCmd = JCScriptRuntime::s_JSRT->m_pRenderCmd;
|
||||
pCmd->append(LAYA_CREATE_IMAGE_ON_RENDER_THREAD);
|
||||
pCmd->append(nID);
|
||||
pCmd->append((long)(pImage));
|
||||
}
|
||||
else
|
||||
{
|
||||
JCConch::s_pConchRender->m_pImageManager->setImage(nID, pImage);
|
||||
}
|
||||
}
|
||||
void JSImage::deleteImageOnRenderThread(int nID)
|
||||
{
|
||||
JCCommandEncoderBuffer* pCmd = JCScriptRuntime::s_JSRT->m_pGCCmd;
|
||||
pCmd->append(LAYA_DELETE_IMAGE_ON_RENDER_THREAD);
|
||||
pCmd->append(nID);
|
||||
}
|
||||
void JSImage::releaseImageOnRenderThread(int nID)
|
||||
{
|
||||
JCCommandEncoderBuffer* pCmd = JCScriptRuntime::s_JSRT->m_pGCCmd;
|
||||
pCmd->append(LAYA_RELEASE_IMAGE_ON_RENDER_THREAD);
|
||||
pCmd->append(nID);
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
Reference in New Issue
Block a user