Author Topic: Error in live wallpaper  (Read 1380 times)

Offline kkl

  • float
  • ****
  • Posts: 291
    • View Profile
Error in live wallpaper
« on: April 29, 2013, 06:27:12 pm »
Hi Egon, I got strange error after I viewed my live wallpaper in live wallpaper settings. It seems like some objects are bound statically. After disposing frame and world (after quiting the settings), the running live wallpaper received an error like the following.

Code: [Select]
04-30 00:07:20.167: E/AndroidRuntime(13968): FATAL EXCEPTION: GLThread 31292
04-30 00:07:20.167: E/AndroidRuntime(13968): java.lang.NullPointerException
04-30 00:07:20.167: E/AndroidRuntime(13968): at com.threed.jpct.GLRenderer.drawVertexArray(GLRenderer.java:2169)
04-30 00:07:20.167: E/AndroidRuntime(13968): at com.threed.jpct.World.draw(World.java:1348)
04-30 00:07:20.167: E/AndroidRuntime(13968): at com.threed.jpct.World.draw(World.java:1089)
04-30 00:07:20.167: E/AndroidRuntime(13968): at com.kision.firefliesforest.MainRenderer.draw(MainRenderer.java:130)
04-30 00:07:20.167: E/AndroidRuntime(13968): at com.kision.firefliesforest.BasicRenderer.onDrawFrame(BasicRenderer.java:104)
04-30 00:07:20.167: E/AndroidRuntime(13968): at net.rbgrn.android.glwallpaperservice.GLThread.guardedRun(GLWallpaperService.java:669)
04-30 00:07:20.167: E/AndroidRuntime(13968): at net.rbgrn.android.glwallpaperservice.GLThread.run(GLWallpaperService.java:534)

Steps to reproduce:
1. Set my live wallpaper to phone.
2. Goto Live Wallpaper settings (the place where you select your live wallpaper), view the preview of my live wallpaper.
3. Quit the preview and then Live Wallpaper settings.
4. When screen goes back to home screen, the running live wallpaper in phone receives error.

Is it a bug or I did it wrong? Are JPCT objects created and disposed statically? 

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11744
    • View Profile
    • http://www.jpct.net
Re: Error in live wallpaper
« Reply #1 on: April 30, 2013, 07:00:31 pm »
No, they aren't static in any way. Might be related to the problem described in the other current thread about wallpapers...IIRC, the wallpaper runs in two different threads while switching between normal view and back. Try to synchronize both render methods so that only one can be active at a time and see if that helps.

Offline kkl

  • float
  • ****
  • Posts: 291
    • View Profile
Re: Error in live wallpaper
« Reply #2 on: May 03, 2013, 05:02:47 am »
I'm not sure how to synchronize both render as they are totally different instance, but I did find out what happened to the error after debugging for few days. The textures uploaded are static in gpu (I assume). If I don't flush the textures, it works perfectly. Probably because I'm re-using the textures from current wallpaper for the preview in settings (to avoid out-of-memory issue). So I can't flush the textures in wallpaper preview if my wallpaper's already running at home screen (but I do dispose frame buffer and world). However, if I open the wallpaper preview and set the wallpaper to the phone repeatedly (around 5 times), it shows out of memory error. I suspect the textures may be still referencing to frame buffer and world, even when disposing them, they are not collected by gc. Any idea how to solve it?

Code: [Select]
//GLEngine
                @Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
renderer.init();
setTouchEventsEnabled(true);
}

                @Override
public void onDestroy() {
WallpaperManager wpm = (WallpaperManager) getSystemService(WALLPAPER_SERVICE);
WallpaperInfo info = wpm.getWallpaperInfo();
if (info != null && info.getComponent().equals(new ComponentName(FireFliesForestWallpaperService.this,
FireFliesForestWallpaperService.this.getClass()))) {
    renderer.clearObjects();
} else {
    renderer.dispose();
}
Log.v("kkl", "Destroyed!");
setTouchEventsEnabled(false);
super.onDestroy();
}

//renderer
          public void init(){
world = new World();
world.setAmbientLight(50, 50, 220);

Camera cam = world.getCamera();
cam.moveCamera(Camera.CAMERA_MOVEOUT, 50f);
cam.lookAt(new SimpleVector(0, 0, 0));

safeCreateAllTextures();
createAllObjects(world); //creates all 3D objects and add them to world

world.setFogging(World.FOGGING_ENABLED);
world.setFogParameters(50f, 120f, 0, 0, 0);
MemoryHelper.compact();
}

public void safeCreateAllTextures() {
if (TextureManager.getInstance().containsTexture(TextureId.TREE_LEAF_1)) {
Log.v("kkl", "Textures exist. Not creating textures..");
return;
}
createAllTextures(); //adds textures to TextureManager and disposes the bitmaps
}

        //When renderer.dispose() is called
        public void onDisposed() {
clearObjects();
clearTextures();
System.gc();
}

public void clearObjects() {
if (world != null) {
world.dispose();
world = null;
}
if (frame != null) {
frame.dispose();
frame = null;
}
}

public void clearTextures(){
TextureManager.getInstance().flush();
}


Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11744
    • View Profile
    • http://www.jpct.net
Re: Error in live wallpaper
« Reply #3 on: May 03, 2013, 10:05:04 am »
Textures are not bound to world or framebuffer, but their copy on the gpu is bound to the GL context. flush() removes textures from the manager, it doesn't unload them from the gpu. In the normal case, there's no need to call flush. What you might want instead is unload().

Offline K24A3

  • long
  • ***
  • Posts: 231
    • View Profile
Re: Error in live wallpaper
« Reply #4 on: May 03, 2013, 10:38:02 am »
You should limit the number of renderers to 1 max, which means if the routine that creates the renderer is called, destroy the existing one and null the reference before creating the new one.

You should also create everything 3D related on the same thread, the main activity or wallpaper service thread.

Offline kkl

  • float
  • ****
  • Posts: 291
    • View Profile
Re: Error in live wallpaper
« Reply #5 on: May 05, 2013, 10:52:41 am »
Thanx Egon. I think unload() should help alot. However, I still hope that I could reuse the texture without unloading them, so the live wallpaper does not have to upload the texture again (Uploading texture might cause the livewallpaper freezes for awhile). Anyway, I'm suspecting if I don't unload the texture, the gl context might be still pointing to the texture and gl context cannot be collected by gc, then causes memory leak. Will find better solution if possible.

K24A3, thanx for the suggestion. BTW, if we destroy the existing one before creating one, the existing one might resume ( onResume() ) its own wallpaper after quitting the preview livewallpaper. Presumably, It might cause error as the existing one is destroyed after viewing the preview. Perhaps I still don't quite know very much about android wallpaper service behavior yet about destroying the previous livewallpaper. Hope you would explain more ;)
« Last Edit: May 05, 2013, 05:45:00 pm by kkl »