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?
//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();
}