PVR Textures Not Reloading After GL Context Lost

Greetings,

I’ve come across a problem with PVR and PVR.CCZ textures not reloading when the gl context is lost, however PNG textures reload fine. Please tell me if I’m doing something wrong. I have developed the following simple repro case to help illustrate the problem.

Repro Case:

  1. Add the following code to the end of the HelloWorld::init() function:
    @
    CCSpriteFrameCache **frameCache = CCSpriteFrameCache::sharedSpriteFrameCache;
    frameCache~~>addSpriteFramesWithFile;
    // frameCache~~>addSpriteFramesWithFile;
    // frameCache~~>addSpriteFramesWithFile;
    CCSprite* pngTestSprite = CCSprite::spriteWithSpriteFrame);
    this~~>addChild;
    pngTestSprite->setPosition);
    @
  2. Add the attached image and plist assets to the HelloWorld/Resource folder.
  3. Execute the program on android hardware. The normal HelloWorld background will be displayed and a reddish icon will show in the middle.
  4. Press HOME on the android device.
  5. Navigate back to the HelloWorld app by long-pressing the HOME button and selecting the app. When loading pngtest.plist the reddish icon is displayed as normal.
  6. Repeat the test by using either “pvrccztest.plist” or “pvrtest.plist”. If either the pvrccztest.plist or pvrtest.plist is loaded,**the reddish icon will be a white square* when returning from the background.

I also attached some images to further illustrate the problem.

I’m using Android 2.2.1 SDK API level 8.


imageAssets.zip (7.9 KB)


pvrStartUp.png (66.5 KB)


pvrReturnFromBackground.png (62.6 KB)

I tried this on the iOS simulator. The pvr textures reload as expected on the iOS simulator. So far I only see the problem on the android phone. I don’t have an iOS device to try.

I have absolutely the same problem. My game works perfectly on iOS, but on Android after restoring all pvr.ccz textures are not shown correctly - just some rubbish on the screen (some gradients, bits of labels, etc).

In my case the only textures that are not from pvr.ccz are labels and they are restored without problems.

Ok, I got it working - it is just a bug.

To fix it change the following in file CCTextureCache.cpp:

function CCTextureCache::addPVRImage(const char* path)
after if( tex~~>initWithPVRFile) ) {
add this
<pre>#if CC_ENABLE_CACHE_TEXTTURE_DATA
// cache the texture file name
VolatileTexture::addImageTexture, CCImage::kFmtRawData);
#endif</pre>
should be this:
<pre>
CCTexture2D * CCTextureCache::addPVRImage
{
CCAssert;
CCTexture2D * tex;
std::string key;
// remove possible~~HD suffix to prevent caching the same image twice (issue #1040)
CCFileUtils::ccRemoveHDSuffixFromFile(key);

if( (tex = m_pTextures~~>objectForKey) )
{
return tex;
}
// Split up directory and filename
std::string fullpath = CCFileUtils::fullPathFromRelativePath);
tex = new CCTexture2D;
if) )
{
#if CC_ENABLE_CACHE_TEXTTURE_DATA
// cache the texture file name
VolatileTexture::addImageTexture, CCImage::kFmtRawData);
#endif
m_pTextures~~>setObject(tex, key);
tex~~>autorelease;
}
else
{
CCLOG (“cocos2d: Couldn’t add PVRImage:%s in CCTextureCache”,key.c_str());
}
return tex;
}</pre>

in function void VolatileTexture::reloadAllTextures
case kImageFile should be changed to:
<pre>
case kImageFile:
{
CCImage image;
std::string lowerCase);
for ; ++i)
{
lowerCase[i] = tolower;
}
if ) {
CCTexture2DPixelFormat oldPixelFormat = CCTexture2D::defaultAlphaPixelFormat;
CCTexture2D::setDefaultAlphaPixelFormat;
vt~~>texture~~>initWithPVRFile);
CCTexture2D::setDefaultAlphaPixelFormat;
} else {
CCFileData data, “rb”);
unsigned long nSize = data.getSize;
unsigned char* pBuffer = data.getBuffer;

if pBuffer, nSize, vt~~>m_FmtImage))
{
CCTexture2DPixelFormat oldPixelFormat = CCTexture2D::defaultAlphaPixelFormat();
CCTexture2D::setDefaultAlphaPixelFormat(vt~~>m_PixelFormat);
vt~~>texture->initWithImage(&image);
CCTexture2D::setDefaultAlphaPixelFormat(oldPixelFormat);
}
}
}
break;

Thanks Dmitry Matyukhin. Bug #967 is created to trace this issue.

I have been thinking about using texture compression in Android.
If you are using PVR it shouldn’t work in devices with hardware which doesn’t support them. For example, the motorola xoom.

What are you doing with that?

This bug #967 is resolved on edge version.

If you have a lot of graphics that can’t fit into memory without PVR, then you can either limit your app by http://developer.android.com/guide/topics/manifest/supports-gl-texture-element.html

Or prepare several APKs - http://developer.android.com/training/multiple-apks/texture.html

but if the app has not too much of graphics, just use PNG files

Dmitry Matyukhin wrote:

If you have a lot of graphics that can’t fit into memory without PVR, then you can either limit your app by http://developer.android.com/guide/topics/manifest/supports-gl-texture-element.html
>
Or prepare several APKs - http://developer.android.com/training/multiple-apks/texture.html
>
but if the app has not too much of graphics, just use PNG files

So, you are using different textures for different devices or using PVR only when

http://developer.android.com/guide/topics/manifest/supports-gl-texture-element.html

I think I was wrong. PVR textures should work on all android devices (please, please correct me if I’m wrong) and GL_IMG_texture_compression_pvrtc says if PVRTC are supported or not.
For example, my game uses PVR textures (not PVRTC) and it works on Nexus One (http://www.glbenchmark.com/phonedetails.jsp?benchmark=glpro21&D=Google+Nexus+One&testgroup=gl - no GL_IMG_texture_compression_pvrtc)

No, PVR shouldn’t work in every device. The only texture format that should work in every device is ETC1.
The nexus one should use ATITC. http://developer.motorola.com/docstools/library/understanding-texture-compression/

mark ——

hello walzer!
i see the PVR texture has add to VolatileTexture for reloading, but ETC texture still not, is it a bug? or ETC texture won’t volatile?
i’m using cocos2dx-2.2.5.