aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJorge Ruesga <jorge@ruesga.com>2014-08-31 14:44:41 (GMT)
committerJorge Ruesga <jorge@ruesga.com>2014-08-31 14:44:41 (GMT)
commitc8d004f3be2bc071184dd32e17b87efccb3aca38 (patch)
treea500c6260b77454bf7a07b36dc14695d3c8770f2
parenta523e7f3384fbab9cc398e2fd398bda8fc13663b (diff)
downloadandroid_packages_wallpapers_PhotoPhase-c8d004f3be2bc071184dd32e17b87efccb3aca38.zip
android_packages_wallpapers_PhotoPhase-c8d004f3be2bc071184dd32e17b87efccb3aca38.tar.gz
android_packages_wallpapers_PhotoPhase-c8d004f3be2bc071184dd32e17b87efccb3aca38.tar.bz2
photophase: fix memory leaks
* Fix memory leak caused by unreleased of framebuffers new refs * pre-cache Roboto typeface * trace allocations/deallocations GL's resources Change-Id: Ib1ca22aae7ba90c4282f91dcef69a5fe274017a8 Signed-off-by: Jorge Ruesga <jorge@ruesga.com>
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/PhotoFrame.java9
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/TextureManager.java8
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/effects/PhotoPhaseEffect.java16
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/shapes/ColorShape.java4
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/shapes/OopsShape.java21
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/transitions/Transition.java5
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/utils/GLESUtil.java25
7 files changed, 85 insertions, 3 deletions
diff --git a/src/org/cyanogenmod/wallpapers/photophase/PhotoFrame.java b/src/org/cyanogenmod/wallpapers/photophase/PhotoFrame.java
index 25b2734..57fd98a 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/PhotoFrame.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/PhotoFrame.java
@@ -19,6 +19,7 @@ package org.cyanogenmod.wallpapers.photophase;
import android.content.Context;
import android.graphics.RectF;
import android.opengl.GLES20;
+import android.util.Log;
import org.cyanogenmod.wallpapers.photophase.utils.GLESUtil;
import org.cyanogenmod.wallpapers.photophase.utils.GLESUtil.GLColor;
@@ -139,6 +140,10 @@ public class PhotoFrame implements TextureRequestor {
if (mTextureInfo != null) {
if (GLES20.glIsTexture(mTextureInfo.handle)) {
int[] textures = new int[]{mTextureInfo.handle};
+ if (GLESUtil.DEBUG_GL_MEMOBJS) {
+ Log.d(GLESUtil.DEBUG_GL_MEMOBJS_DEL_TAG, "glDeleteTextures: ["
+ + mTextureInfo.handle + "]");
+ }
GLES20.glDeleteTextures(1, textures, 0);
GLESUtil.glesCheckError("glDeleteTextures");
}
@@ -279,6 +284,10 @@ public class PhotoFrame implements TextureRequestor {
public void recycle() {
if (mTextureInfo != null && mTextureInfo.handle != 0) {
int[] textures = new int[]{mTextureInfo.handle};
+ if (GLESUtil.DEBUG_GL_MEMOBJS) {
+ Log.d(GLESUtil.DEBUG_GL_MEMOBJS_DEL_TAG, "glDeleteTextures: ["
+ + mTextureInfo.handle + "]");
+ }
GLES20.glDeleteTextures(1, textures, 0);
GLESUtil.glesCheckError("glDeleteTextures");
}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/TextureManager.java b/src/org/cyanogenmod/wallpapers/photophase/TextureManager.java
index 104db0d..417cfb9 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/TextureManager.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/TextureManager.java
@@ -281,6 +281,10 @@ public class TextureManager implements OnMediaPictureDiscoveredListener {
for (GLESTextureInfo info : all) {
if (GLES20.glIsTexture(info.handle)) {
int[] textures = new int[] {info.handle};
+ if (GLESUtil.DEBUG_GL_MEMOBJS) {
+ Log.d(GLESUtil.DEBUG_GL_MEMOBJS_DEL_TAG, "glDeleteTextures: ["
+ + info.handle + "]");
+ }
GLES20.glDeleteTextures(1, textures, 0);
GLESUtil.glesCheckError("glDeleteTextures");
}
@@ -449,6 +453,10 @@ public class TextureManager implements OnMediaPictureDiscoveredListener {
// Destroy references
int[] textures = new int[]{ti.handle};
+ if (GLESUtil.DEBUG_GL_MEMOBJS) {
+ Log.d(GLESUtil.DEBUG_GL_MEMOBJS_DEL_TAG, "glDeleteTextures: ["
+ + ti.handle + "]");
+ }
GLES20.glDeleteTextures(1, textures, 0);
GLESUtil.glesCheckError("glDeleteTextures");
if (ti.bitmap != null) {
diff --git a/src/org/cyanogenmod/wallpapers/photophase/effects/PhotoPhaseEffect.java b/src/org/cyanogenmod/wallpapers/photophase/effects/PhotoPhaseEffect.java
index 0b3c5fc..0900322 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/effects/PhotoPhaseEffect.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/effects/PhotoPhaseEffect.java
@@ -21,6 +21,7 @@ import android.media.effect.EffectContext;
import android.media.effect.EffectFactory;
import android.opengl.GLES20;
import android.opengl.GLUtils;
+import android.util.Log;
import org.cyanogenmod.wallpapers.photophase.utils.GLESUtil;
@@ -138,11 +139,14 @@ public abstract class PhotoPhaseEffect extends Effect {
// Save the GLES state
saveGLState();
+ int[] fb = new int[1];
try {
// Create a framebuffer object and call the effect apply method to draw the effect
- int[] fb = new int[1];
GLES20.glGenFramebuffers(1, fb, 0);
GLESUtil.glesCheckError("glGenFramebuffers");
+ if (GLESUtil.DEBUG_GL_MEMOBJS) {
+ Log.d(GLESUtil.DEBUG_GL_MEMOBJS_NEW_TAG, "glGenFramebuffers: " + fb[0]);
+ }
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fb[0]);
GLESUtil.glesCheckError("glBindFramebuffer");
@@ -171,6 +175,13 @@ public abstract class PhotoPhaseEffect extends Effect {
} finally {
// Restore the GLES state
restoreGLState();
+
+ // Clean framebuffer memory
+ if (GLESUtil.DEBUG_GL_MEMOBJS) {
+ Log.d(GLESUtil.DEBUG_GL_MEMOBJS_DEL_TAG, "glDeleteFramebuffers: " + fb[0]);
+ }
+ GLES20.glDeleteFramebuffers(1, fb, 0);
+ GLESUtil.glesCheckError("glDeleteFramebuffers");
}
}
@@ -189,6 +200,9 @@ public abstract class PhotoPhaseEffect extends Effect {
@Override
public void release() {
if (GLES20.glIsProgram(mProgram)) {
+ if (GLESUtil.DEBUG_GL_MEMOBJS) {
+ Log.d(GLESUtil.DEBUG_GL_MEMOBJS_DEL_TAG, "glDeleteProgram: " + mProgram);
+ }
GLES20.glDeleteProgram(mProgram);
GLESUtil.glesCheckError("glDeleteProgram");
}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/shapes/ColorShape.java b/src/org/cyanogenmod/wallpapers/photophase/shapes/ColorShape.java
index ceb7ec4..c05836f 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/shapes/ColorShape.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/shapes/ColorShape.java
@@ -18,6 +18,7 @@ package org.cyanogenmod.wallpapers.photophase.shapes;
import android.content.Context;
import android.opengl.GLES20;
+import android.util.Log;
import org.cyanogenmod.wallpapers.photophase.utils.GLESUtil;
import org.cyanogenmod.wallpapers.photophase.utils.GLESUtil.GLColor;
@@ -137,6 +138,9 @@ public class ColorShape implements DrawableShape {
*/
public void recycle() {
if (GLES20.glIsProgram(mProgramHandler)) {
+ if (GLESUtil.DEBUG_GL_MEMOBJS) {
+ Log.d(GLESUtil.DEBUG_GL_MEMOBJS_DEL_TAG, "glDeleteProgram: " + mProgramHandler);
+ }
GLES20.glDeleteProgram(mProgramHandler);
GLESUtil.glesCheckError("glDeleteProgram");
}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/shapes/OopsShape.java b/src/org/cyanogenmod/wallpapers/photophase/shapes/OopsShape.java
index d7b3e89..195a1e4 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/shapes/OopsShape.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/shapes/OopsShape.java
@@ -24,6 +24,7 @@ import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.opengl.GLES20;
+import android.util.Log;
import org.cyanogenmod.wallpapers.photophase.Colors;
import org.cyanogenmod.wallpapers.photophase.utils.GLESUtil;
@@ -65,6 +66,8 @@ public class OopsShape implements DrawableShape {
0.5f, 0.75f
};
+ private static Typeface sRobotoFont;
+
private FloatBuffer mPositionBuffer;
private FloatBuffer mTextureBuffer;
@@ -87,6 +90,9 @@ public class OopsShape implements DrawableShape {
*/
public OopsShape(Context ctx, int resourceMessageId) {
super();
+ if (sRobotoFont == null) {
+ sRobotoFont = Typeface.createFromAsset(ctx.getAssets(), "fonts/Roboto-Bold.ttf");
+ }
int orientation = ctx.getResources().getConfiguration().orientation;
float[] vertex = VERTEX_COORDS_PORTRAIT;
@@ -233,12 +239,20 @@ public class OopsShape implements DrawableShape {
public void recycle() {
// Remove textures
if (mOopsImageTexture != null && mOopsImageTexture.handle != 0) {
+ if (GLESUtil.DEBUG_GL_MEMOBJS) {
+ Log.d(GLESUtil.DEBUG_GL_MEMOBJS_DEL_TAG, "glDeleteTextures: ["
+ + mOopsImageTexture.handle + "]");
+ }
int[] textures = new int[]{mOopsImageTexture.handle};
GLES20.glDeleteTextures(1, textures, 0);
GLESUtil.glesCheckError("glDeleteTextures");
}
mOopsImageTexture = null;
if (mOopsTextTexture != null && mOopsTextTexture.handle != 0) {
+ if (GLESUtil.DEBUG_GL_MEMOBJS) {
+ Log.d(GLESUtil.DEBUG_GL_MEMOBJS_DEL_TAG, "glDeleteTextures: ["
+ + mOopsTextTexture.handle + "]");
+ }
int[] textures = new int[]{mOopsTextTexture.handle};
GLES20.glDeleteTextures(1, textures, 0);
GLESUtil.glesCheckError("glDeleteTextures");
@@ -257,6 +271,10 @@ public class OopsShape implements DrawableShape {
for (int i = 0; i < 2; i++) {
if (GLES20.glIsProgram(mProgramHandlers[i])) {
+ if (GLESUtil.DEBUG_GL_MEMOBJS) {
+ Log.d(GLESUtil.DEBUG_GL_MEMOBJS_DEL_TAG, "glDeleteProgram: "
+ + mProgramHandlers[i]);
+ }
GLES20.glDeleteProgram(mProgramHandlers[i]);
GLESUtil.glesCheckError("glDeleteProgram(" + i + ")");
}
@@ -277,8 +295,7 @@ public class OopsShape implements DrawableShape {
*/
public Bitmap text2Bitmap(Context ctx, String text) {
Paint paint = new Paint();
- Typeface font = Typeface.createFromAsset(ctx.getAssets(), "fonts/Roboto-Bold.ttf");
- paint.setTypeface(font);
+ paint.setTypeface(sRobotoFont);
paint.setColor(Color.WHITE);
paint.setTextSize(24.0f);
paint.setAntiAlias(true);
diff --git a/src/org/cyanogenmod/wallpapers/photophase/transitions/Transition.java b/src/org/cyanogenmod/wallpapers/photophase/transitions/Transition.java
index bae0399..c82323d 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/transitions/Transition.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/transitions/Transition.java
@@ -18,6 +18,7 @@ package org.cyanogenmod.wallpapers.photophase.transitions;
import android.content.Context;
import android.opengl.GLES20;
+import android.util.Log;
import org.cyanogenmod.wallpapers.photophase.utils.GLESUtil;
import org.cyanogenmod.wallpapers.photophase.PhotoFrame;
@@ -192,6 +193,10 @@ public abstract class Transition {
int cc = mProgramHandlers.length;
for (int i = 0; i < cc; i++) {
if (GLES20.glIsProgram(mProgramHandlers[i])) {
+ if (GLESUtil.DEBUG_GL_MEMOBJS) {
+ Log.d(GLESUtil.DEBUG_GL_MEMOBJS_DEL_TAG, "glDeleteProgram: "
+ + mProgramHandlers[i]);
+ }
GLES20.glDeleteProgram(mProgramHandlers[i]);
GLESUtil.glesCheckError("glDeleteProgram");
}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/utils/GLESUtil.java b/src/org/cyanogenmod/wallpapers/photophase/utils/GLESUtil.java
index 0078ea6..8b34601 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/utils/GLESUtil.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/utils/GLESUtil.java
@@ -42,6 +42,10 @@ public final class GLESUtil {
private static final boolean DEBUG = false;
+ public static final boolean DEBUG_GL_MEMOBJS = false;
+ public static final String DEBUG_GL_MEMOBJS_NEW_TAG = "MEMOBJS_NEW";
+ public static final String DEBUG_GL_MEMOBJS_DEL_TAG = "MEMOBJS_DEL";
+
private static final Object sSync = new Object();
/**
@@ -207,6 +211,9 @@ public final class GLESUtil {
int[] compiled = new int[1];
// Create, load and compile the shader
int shader = GLES20.glCreateShader(type);
+ if (GLESUtil.DEBUG_GL_MEMOBJS) {
+ Log.d(GLESUtil.DEBUG_GL_MEMOBJS_NEW_TAG, "glCreateShader (" + type + "): " + shader);
+ }
GLESUtil.glesCheckError("glCreateShader");
if (shader <= 0) {
Log.e(TAG, "Cannot create a shader");
@@ -265,6 +272,9 @@ public final class GLESUtil {
// Create the programa ref
progid = GLES20.glCreateProgram();
+ if (GLESUtil.DEBUG_GL_MEMOBJS) {
+ Log.d(GLESUtil.DEBUG_GL_MEMOBJS_NEW_TAG, "glCreateProgram: " + progid);
+ }
GLESUtil.glesCheckError("glCreateProgram");
if (progid <= 0) {
String msg = "Cannot create a program";
@@ -296,10 +306,16 @@ public final class GLESUtil {
} finally {
// Delete the shaders
if (vshader != 0) {
+ if (GLESUtil.DEBUG_GL_MEMOBJS) {
+ Log.d(GLESUtil.DEBUG_GL_MEMOBJS_DEL_TAG, "glDeleteShader (v): " + vshader);
+ }
GLES20.glDeleteShader(vshader);
GLESUtil.glesCheckError("glDeleteShader");
}
if (fshader != 0) {
+ if (GLESUtil.DEBUG_GL_MEMOBJS) {
+ Log.d(GLESUtil.DEBUG_GL_MEMOBJS_DEL_TAG, "glDeleteShader (f): " + fshader);
+ }
GLES20.glDeleteShader(fshader);
GLESUtil.glesCheckError("glDeleteShader");
}
@@ -415,6 +431,11 @@ public final class GLESUtil {
int[] textureHandles = new int[num];
GLES20.glGenTextures(num, textureHandles, 0);
GLESUtil.glesCheckError("glGenTextures");
+ for (int i = 0; i < num; i++) {
+ if (GLESUtil.DEBUG_GL_MEMOBJS) {
+ Log.d(GLESUtil.DEBUG_GL_MEMOBJS_NEW_TAG, "glGenTextures: " + textureHandles[i]);
+ }
+ }
if (textureHandles[0] <= 0 || (effect != null && textureHandles[1] <= 0)) {
Log.e(TAG, "Failed to generate a valid texture");
return new GLESTextureInfo();
@@ -455,6 +476,10 @@ public final class GLESUtil {
// Delete the unused texture
int[] textures = {textureHandles[0]};
+ if (GLESUtil.DEBUG_GL_MEMOBJS) {
+ Log.d(GLESUtil.DEBUG_GL_MEMOBJS_DEL_TAG, "glDeleteTextures: ["
+ + textureHandles[0] + "]");
+ }
GLES20.glDeleteTextures(1, textures, 0);
GLESUtil.glesCheckError("glDeleteTextures");
}