From 1af4aa1138290626283892eaac76f754fd81b0e9 Mon Sep 17 00:00:00 2001 From: natural-law Date: Wed, 6 Apr 2011 16:29:58 +0800 Subject: [PATCH] [android] fixed #374,Modify the approach of cache the textures when EGL rendering context lost. --- HelloWorld/android/jni/helloworld/main.cpp | 2 +- cocos2dx/include/CCTexture2D.h | 5 - cocos2dx/include/CCTextureCache.h | 46 +++++++ cocos2dx/textures/CCTexture2D.cpp | 137 +------------------ cocos2dx/textures/CCTextureCache.cpp | 149 ++++++++++++++++++++- tests/test.android/jni/tests/main.cpp | 2 +- 6 files changed, 197 insertions(+), 144 deletions(-) diff --git a/HelloWorld/android/jni/helloworld/main.cpp b/HelloWorld/android/jni/helloworld/main.cpp index 7ba7a1093a..515442c874 100644 --- a/HelloWorld/android/jni/helloworld/main.cpp +++ b/HelloWorld/android/jni/helloworld/main.cpp @@ -30,7 +30,7 @@ void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv* env, jobject thi } else { - cocos2d::CCTexture2D::reloadAllTextures(); + cocos2d::CCTextureCache::reloadAllTextures(); cocos2d::CCDirector::sharedDirector()->setGLDefaultValues(); } } diff --git a/cocos2dx/include/CCTexture2D.h b/cocos2dx/include/CCTexture2D.h index 3a39952f32..19d5c94a42 100644 --- a/cocos2dx/include/CCTexture2D.h +++ b/cocos2dx/include/CCTexture2D.h @@ -212,11 +212,6 @@ public: */ static CCTexture2DPixelFormat defaultAlphaPixelFormat(); - /** Reload all textures - It's only useful when the value of CC_ENABLE_CACHE_TEXTTURE_DATA is 1 - */ - static void reloadAllTextures(); - private: bool initPremultipliedATextureWithImage(CCImage * image, unsigned int pixelsWide, unsigned int pixelsHigh); diff --git a/cocos2dx/include/CCTextureCache.h b/cocos2dx/include/CCTextureCache.h index 4cfc0cef0b..3ca010b90f 100644 --- a/cocos2dx/include/CCTextureCache.h +++ b/cocos2dx/include/CCTextureCache.h @@ -30,6 +30,11 @@ THE SOFTWARE. #include "CCObject.h" #include "CCMutableDictionary.h" +#if CC_ENABLE_CACHE_TEXTTURE_DATA + #include "CCImage.h" + #include +#endif + namespace cocos2d { class CCTexture2D; class CCAsyncObject; @@ -146,7 +151,48 @@ public: */ CCTexture2D* addPVRTCImage(const char* fileimage); #endif + + /** Reload all textures + It's only useful when the value of CC_ENABLE_CACHE_TEXTTURE_DATA is 1 + */ + static void reloadAllTextures(); }; + +#if CC_ENABLE_CACHE_TEXTTURE_DATA + +class VolatileTexture +{ +public: + VolatileTexture(CCTexture2D *t); + ~VolatileTexture(); + + static void addImageTexture(CCTexture2D *tt, const char* imageFileName, CCImage::EImageFormat format); + static void addStringTexture(CCTexture2D *tt, const char* text, CCSize dimensions, CCTextAlignment alignment, const char *fontName, float fontSize); + + static void removeTexture(CCTexture2D *t); + static void reloadAllTextures(); + +public: + static std::list textures; + static bool isReloading; + +protected: + CCTexture2D *texture; + + bool m_bIsString; + + std::string m_strFileName; + CCImage::EImageFormat m_FmtImage; + + CCSize m_size; + CCTextAlignment m_alignment; + std::string m_strFontName; + std::string m_strText; + float m_fFontSize; +}; + +#endif + }//namespace cocos2d #endif //__CCTEXTURE_CACHE_H__ diff --git a/cocos2dx/textures/CCTexture2D.cpp b/cocos2dx/textures/CCTexture2D.cpp index e7e9ee951a..4cf611ca81 100644 --- a/cocos2dx/textures/CCTexture2D.cpp +++ b/cocos2dx/textures/CCTexture2D.cpp @@ -34,7 +34,6 @@ THE SOFTWARE. #include "ccConfig.h" #include "ccMacros.h" -#include "CCTexture2D.h" #include "CCConfiguration.h" #include "platform/platform.h" #include "CCImage.h" @@ -47,7 +46,7 @@ THE SOFTWARE. #endif #if CC_ENABLE_CACHE_TEXTTURE_DATA - #include + #include "CCTextureCache.h" #endif namespace cocos2d { @@ -58,122 +57,6 @@ namespace cocos2d { //CLASS IMPLEMENTATIONS: -#if CC_ENABLE_CACHE_TEXTTURE_DATA - class VolatileTexture - { - protected: - CCTexture2D *texture; - unsigned char *data; - CCTexture2DPixelFormat pixelFormat; - unsigned int pixelsWide; - unsigned int pixelsHigh; - CCSize contentSize; - - public: - - static std::list textures; - static bool isReloading; - - VolatileTexture(CCTexture2D *t) : texture(t), data(0) - { - textures.push_back(this); - } - - ~VolatileTexture() - { - if (data) - delete [] data; - textures.remove(this); - } - - static void addTextureWithData(CCTexture2D *tt, - const void *d, - CCTexture2DPixelFormat f, - unsigned int w, - unsigned int h, - CCSize s) - { - if (isReloading) - return; - - VolatileTexture *vt = 0; - std::list::iterator i = textures.begin(); - while( i != textures.end() ) - { - VolatileTexture *v = *i++; - if (v->texture == tt) { - vt = v; - break; - } - } - - if (!vt) - vt = new VolatileTexture(tt); - - vt->pixelFormat = f; - vt->pixelsWide = w; - vt->pixelsHigh = h; - vt->contentSize = s; - - //CCLOGINFO("added volatile %d", textures.size()); - - if (vt->data) { - delete [] vt->data; - vt->data = 0; - } - - switch(f) { - case kCCTexture2DPixelFormat_RGBA8888: - case kCCTexture2DPixelFormat_RGBA4444: - case kCCTexture2DPixelFormat_RGB5A1: - case kCCTexture2DPixelFormat_RGB565: - case kCCTexture2DPixelFormat_A8: - vt->data = new unsigned char[w * h * 4]; - memcpy(vt->data, d, w * h * 4); - break; - case kCCTexture2DPixelFormat_RGB888: - vt->data = new unsigned char[w * h * 3]; - memcpy(vt->data, d, w * h * 3); - break; - } - } - - static void removeTexture(CCTexture2D *t) { - - std::list::iterator i = textures.begin(); - while( i != textures.end() ) - { - VolatileTexture *vt = *i++; - if (vt->texture == t) { - delete vt; - break; - } - } - } - - static void reloadAllTextures() - { - isReloading = true; - - CCLOG("reload all texture"); - std::list::iterator i = textures.begin(); - - while( i != textures.end() ) - { - VolatileTexture *vt = *i++; - if (vt->data) { - vt->texture->initWithData((const void *)vt->data, vt->pixelFormat, vt->pixelsWide, vt->pixelsHigh, vt->contentSize); - } - } - - isReloading = false; - } - }; - - std::list VolatileTexture::textures; - bool VolatileTexture::isReloading = false; -#endif // CC_ENABLE_CACHE_TEXTTURE_DATA - // If the image has alpha, you can create RGBA8 (32-bit) or RGBA4 (16-bit) or RGB5A1 (16-bit) // Default is: RGBA8888 (32-bit textures) static CCTexture2DPixelFormat g_defaultAlphaPixelFormat = kCCTexture2DPixelFormat_Default; @@ -273,12 +156,6 @@ bool CCTexture2D::getHasPremultipliedAlpha() bool CCTexture2D::initWithData(const void *data, CCTexture2DPixelFormat pixelFormat, unsigned int pixelsWide, unsigned int pixelsHigh, CCSize contentSize) { - -#if CC_ENABLE_CACHE_TEXTTURE_DATA - // cache the texture data - VolatileTexture::addTextureWithData(this, data, pixelFormat, pixelsWide, pixelsHigh, contentSize); -#endif - glGenTextures(1, &m_uName); glBindTexture(GL_TEXTURE_2D, m_uName); @@ -559,6 +436,11 @@ bool CCTexture2D::initWithString(const char *text, const char *fontName, float f } bool CCTexture2D::initWithString(const char *text, CCSize dimensions, CCTextAlignment alignment, const char *fontName, float fontSize) { +#if CC_ENABLE_CACHE_TEXTTURE_DATA + // cache the texture data + VolatileTexture::addStringTexture(this, text, dimensions, alignment, fontName, fontSize); +#endif + CCImage image; CCImage::ETextAlign eAlign = (CCTextAlignmentCenter == alignment) ? CCImage::kAlignCenter : (CCTextAlignmentLeft == alignment) ? CCImage::kAlignLeft : CCImage::kAlignRight; @@ -742,11 +624,4 @@ CCTexture2DPixelFormat CCTexture2D::defaultAlphaPixelFormat() return g_defaultAlphaPixelFormat; } -void CCTexture2D::reloadAllTextures() -{ -#if CC_ENABLE_CACHE_TEXTTURE_DATA - VolatileTexture::reloadAllTextures(); -#endif -} - }//namespace cocos2d diff --git a/cocos2dx/textures/CCTextureCache.cpp b/cocos2dx/textures/CCTextureCache.cpp index 64c8d2f72c..23223f285d 100644 --- a/cocos2dx/textures/CCTextureCache.cpp +++ b/cocos2dx/textures/CCTextureCache.cpp @@ -219,6 +219,11 @@ CCTexture2D * CCTextureCache::addImage(const char * path) if( texture ) { +#if CC_ENABLE_CACHE_TEXTTURE_DATA + // cache the texture file name + VolatileTexture::addImageTexture(texture, fullpath.c_str(), CCImage::kFmtJpg); +#endif + m_pTextures->setObject(texture, pathKey); texture->release(); } @@ -229,11 +234,6 @@ CCTexture2D * CCTextureCache::addImage(const char * path) } else { - //# work around for issue #910 -#if 0 - UIImage *image = [UIImage imageNamed:path]; - tex = [ [CCTexture2D alloc] initWithImage: image ]; -#else // prevents overloading the autorelease pool CCImage image; CCFileData data(fullpath.c_str(), "rb"); @@ -243,9 +243,14 @@ CCTexture2D * CCTextureCache::addImage(const char * path) texture = new CCTexture2D(); texture->initWithImage(&image); -#endif + if( texture ) { +#if CC_ENABLE_CACHE_TEXTTURE_DATA + // cache the texture file name + VolatileTexture::addImageTexture(texture, fullpath.c_str(), CCImage::kFmtPng); +#endif + m_pTextures->setObject(texture, pathKey); texture->release(); } @@ -434,5 +439,137 @@ CCTexture2D* CCTextureCache::textureForKey(const char* key) return m_pTextures->objectForKey(string(key)); } +void CCTextureCache::reloadAllTextures() +{ +#if CC_ENABLE_CACHE_TEXTTURE_DATA + VolatileTexture::reloadAllTextures(); +#endif +} + +#if CC_ENABLE_CACHE_TEXTTURE_DATA + +std::list VolatileTexture::textures; +bool VolatileTexture::isReloading = false; + +VolatileTexture::VolatileTexture(CCTexture2D *t) +: texture(t) +, m_bIsString(false) +, m_strFileName("") +, m_FmtImage(CCImage::kFmtPng) +, m_strFontName("") +, m_strText("") +, m_fFontSize(0.0f) +, m_alignment(CCTextAlignmentCenter) +{ + m_size = CCSizeMake(0, 0); + textures.push_back(this); +} + +VolatileTexture::~VolatileTexture() +{ + textures.remove(this); +} + +void VolatileTexture::addImageTexture(CCTexture2D *tt, const char* imageFileName, CCImage::EImageFormat format) +{ + if (isReloading) + return; + + VolatileTexture *vt = 0; + std::list::iterator i = textures.begin(); + while( i != textures.end() ) + { + VolatileTexture *v = *i++; + if (v->texture == tt) { + vt = v; + break; + } + } + + if (!vt) + vt = new VolatileTexture(tt); + + vt->m_bIsString = false; + vt->m_strFileName = imageFileName; + vt->m_FmtImage = format; +} + +void VolatileTexture::addStringTexture(CCTexture2D *tt, const char* text, CCSize dimensions, CCTextAlignment alignment, const char *fontName, float fontSize) +{ + if (isReloading) + return; + + VolatileTexture *vt = 0; + std::list::iterator i = textures.begin(); + while( i != textures.end() ) + { + VolatileTexture *v = *i++; + if (v->texture == tt) { + vt = v; + break; + } + } + + if (!vt) + vt = new VolatileTexture(tt); + + vt->m_bIsString = true; + vt->m_size = dimensions; + vt->m_strFontName = fontName; + vt->m_alignment = alignment; + vt->m_fFontSize = fontSize; + vt->m_strText = text; +} + +void VolatileTexture::removeTexture(CCTexture2D *t) { + + std::list::iterator i = textures.begin(); + while( i != textures.end() ) + { + VolatileTexture *vt = *i++; + if (vt->texture == t) { + delete vt; + break; + } + } +} + +void VolatileTexture::reloadAllTextures() +{ + isReloading = true; + + CCLOG("reload all texture"); + std::list::iterator i = textures.begin(); + + while( i != textures.end() ) + { + VolatileTexture *vt = *i++; + if (vt->m_bIsString) + { + vt->texture->initWithString(vt->m_strText.c_str(), + vt->m_size, + vt->m_alignment, + vt->m_strFontName.c_str(), + vt->m_fFontSize); + } + else + { + CCImage image; + CCFileData data(vt->m_strFileName.c_str(), "rb"); + unsigned long nSize = data.getSize(); + unsigned char* pBuffer = data.getBuffer(); + + if (image.initWithImageData((void*)pBuffer, nSize, vt->m_FmtImage)) + { + vt->texture->initWithImage(&image); + } + } + } + + isReloading = false; +} + +#endif // CC_ENABLE_CACHE_TEXTTURE_DATA + }//namespace cocos2d diff --git a/tests/test.android/jni/tests/main.cpp b/tests/test.android/jni/tests/main.cpp index 7ba7a1093a..515442c874 100644 --- a/tests/test.android/jni/tests/main.cpp +++ b/tests/test.android/jni/tests/main.cpp @@ -30,7 +30,7 @@ void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv* env, jobject thi } else { - cocos2d::CCTexture2D::reloadAllTextures(); + cocos2d::CCTextureCache::reloadAllTextures(); cocos2d::CCDirector::sharedDirector()->setGLDefaultValues(); } }