aboutsummaryrefslogtreecommitdiffstats
path: root/src/org/cyanogenmod/wallpapers/photophase
diff options
context:
space:
mode:
authorJorge Ruesga <jorge@ruesga.com>2013-08-20 17:53:42 +0200
committerJorge Ruesga <jorge@ruesga.com>2013-08-20 17:53:42 +0200
commit5fb7e63d506e8cdb351a67746add0fa7792d0ce9 (patch)
treec7978ccd38879e4b9bc3d5a172ab929a045c1473 /src/org/cyanogenmod/wallpapers/photophase
parent06a23e63bcfc88e81bea62b1c1858b8bdbfe794b (diff)
downloadandroid_packages_wallpapers_PhotoPhase-5fb7e63d506e8cdb351a67746add0fa7792d0ce9.tar.gz
android_packages_wallpapers_PhotoPhase-5fb7e63d506e8cdb351a67746add0fa7792d0ce9.tar.bz2
android_packages_wallpapers_PhotoPhase-5fb7e63d506e8cdb351a67746add0fa7792d0ce9.zip
Use the MCA private IdentityEffect to clone the textures (#27)
This avoid problems on tegra devices Save and restore the GLES context like MCA does Signed-off-by: Jorge Ruesga <jorge@ruesga.com>
Diffstat (limited to 'src/org/cyanogenmod/wallpapers/photophase')
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/effects/NullEffect.java7
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/effects/PhotoPhaseEffect.java105
2 files changed, 71 insertions, 41 deletions
diff --git a/src/org/cyanogenmod/wallpapers/photophase/effects/NullEffect.java b/src/org/cyanogenmod/wallpapers/photophase/effects/NullEffect.java
index ca53fe4..5a8b520 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/effects/NullEffect.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/effects/NullEffect.java
@@ -51,4 +51,11 @@ public class NullEffect extends PhotoPhaseEffect {
init(VERTEX_SHADER, FRAGMENT_SHADER);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ void apply(int inputTexId) {
+ // Nothing to draw
+ }
}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/effects/PhotoPhaseEffect.java b/src/org/cyanogenmod/wallpapers/photophase/effects/PhotoPhaseEffect.java
index 66f1f75..2fd0e2b 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/effects/PhotoPhaseEffect.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/effects/PhotoPhaseEffect.java
@@ -35,6 +35,8 @@ public abstract class PhotoPhaseEffect extends Effect {
private static final int FLOAT_SIZE_BYTES = 4;
+ private static final String MCA_IDENTITY_EFFECT = "IdentityEffect";
+
static final String VERTEX_SHADER =
"attribute vec4 a_position;\n" +
"attribute vec2 a_texcoord;\n" +
@@ -48,9 +50,18 @@ public abstract class PhotoPhaseEffect extends Effect {
private static final float[] TEX_VERTICES = {0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f};
private static final float[] POS_VERTICES = {-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f};
+ private final int GL_STATE_FBO = 0;
+ private final int GL_STATE_PROGRAM = 1;
+ private final int GL_STATE_ARRAYBUFFER = 2;
+ private final int GL_STATE_COUNT = 3;
+
+ private int[] mOldState = new int[GL_STATE_COUNT];
+
private final EffectContext mEffectContext;
private final String mName;
+ private Effect mIdentityEffect;
+
int mProgram;
int mTexSamplerHandle;
int mTexCoordHandle;
@@ -70,6 +81,10 @@ public abstract class PhotoPhaseEffect extends Effect {
super();
mEffectContext = ctx;
mName = name;
+
+ // Stand on MCA identity effect for the initialization work
+ EffectFactory effectFactory = mEffectContext.getFactory();
+ mIdentityEffect = effectFactory.createEffect(MCA_IDENTITY_EFFECT);
}
/**
@@ -120,49 +135,44 @@ public abstract class PhotoPhaseEffect extends Effect {
*/
@Override
public final synchronized void apply(int inputTexId, int width, int height, int outputTexId) {
- // 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");
- GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fb[0]);
- GLESUtil.glesCheckError("glBindFramebuffer");
-
- // Render on the whole framebuffer
- GLES20.glViewport(0, 0, width, height);
- GLESUtil.glesCheckError("glViewport");
-
- // Create a new output texture
- GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, outputTexId);
- GLESUtil.glesCheckError("glBindTexture");
- GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGB, width, height, 0, GLES20.GL_RGB, GLES20.GL_UNSIGNED_BYTE, null);
- GLESUtil.glesCheckError("glTexImage2D");
-
- // Set the parameters
- GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
- GLESUtil.glesCheckError("glTexParameteri");
- GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
- GLESUtil.glesCheckError("glTexParameteri");
-
- // Create the framebuffer
- GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20. GL_TEXTURE_2D, outputTexId, 0);
- GLESUtil.glesCheckError("glFramebufferTexture2D");
-
- // Check if the buffer was built successfully
- if (GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER) != GLES20.GL_FRAMEBUFFER_COMPLETE) {
- // Something when wrong. Throw an exception
- GLESUtil.glesCheckError("glCheckFramebufferStatus");
- int error = GLES20.glGetError();
- throw new android.opengl.GLException(error, GLUtils.getEGLErrorString(error));
+ // Save the GLES state
+ saveGLState();
+
+ 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");
+ GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fb[0]);
+ GLESUtil.glesCheckError("glBindFramebuffer");
+
+ // Render on the whole framebuffer
+ GLES20.glViewport(0, 0, width, height);
+ GLESUtil.glesCheckError("glViewport");
+
+ // Create a new output texture (Use the MCA identity to clone the input to the output)
+ mIdentityEffect.apply(inputTexId, width, height, outputTexId);
+
+ // Create the framebuffer
+ GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20. GL_TEXTURE_2D, outputTexId, 0);
+ GLESUtil.glesCheckError("glFramebufferTexture2D");
+
+ // Check if the buffer was built successfully
+ if (GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER) != GLES20.GL_FRAMEBUFFER_COMPLETE) {
+ // Something when wrong. Throw an exception
+ GLESUtil.glesCheckError("glCheckFramebufferStatus");
+ int error = GLES20.glGetError();
+ throw new android.opengl.GLException(error, GLUtils.getEGLErrorString(error));
+ }
+
+ // Apply the effect
+ apply(inputTexId);
+
+ } finally {
+ // Restore the GLES state
+ restoreGLState();
}
- // Bind the framebuffer
- GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fb[0]);
-
- // Apply the effect
- apply(inputTexId);
-
- // Unbind the framebuffer
- GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
}
/**
@@ -242,4 +252,17 @@ public abstract class PhotoPhaseEffect extends Effect {
void applyParameters() {
// Do nothing
}
+
+
+ private final void saveGLState() {
+ GLES20.glGetIntegerv(GLES20.GL_FRAMEBUFFER_BINDING, mOldState, GL_STATE_FBO);
+ GLES20.glGetIntegerv(GLES20.GL_CURRENT_PROGRAM, mOldState, GL_STATE_PROGRAM);
+ GLES20.glGetIntegerv(GLES20.GL_ARRAY_BUFFER_BINDING, mOldState, GL_STATE_ARRAYBUFFER);
+ }
+
+ private final void restoreGLState() {
+ GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mOldState[GL_STATE_FBO]);
+ GLES20.glUseProgram(mOldState[GL_STATE_PROGRAM]);
+ GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mOldState[GL_STATE_ARRAYBUFFER]);
+ }
}