summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/com/android/gallery3d/ui/GLCanvas.java4
-rw-r--r--src/com/android/gallery3d/ui/GLCanvasImpl.java107
-rw-r--r--src/com/android/gallery3d/ui/Raw2DTexture.java169
-rw-r--r--src/com/android/gallery3d/ui/RawTexture.java91
-rw-r--r--tests/src/com/android/gallery3d/ui/GLCanvasStub.java2
5 files changed, 193 insertions, 180 deletions
diff --git a/src/com/android/gallery3d/ui/GLCanvas.java b/src/com/android/gallery3d/ui/GLCanvas.java
index 9b8053ffc..c12a9f78c 100644
--- a/src/com/android/gallery3d/ui/GLCanvas.java
+++ b/src/com/android/gallery3d/ui/GLCanvas.java
@@ -117,4 +117,8 @@ public interface GLCanvas {
// Dump statistics information and clear the counters. For debug only.
public void dumpStatisticsAndClear();
+
+ public void beginRenderTarget(RawTexture texture);
+
+ public void endRenderTarget();
}
diff --git a/src/com/android/gallery3d/ui/GLCanvasImpl.java b/src/com/android/gallery3d/ui/GLCanvasImpl.java
index 61238519b..1efe5af4e 100644
--- a/src/com/android/gallery3d/ui/GLCanvasImpl.java
+++ b/src/com/android/gallery3d/ui/GLCanvasImpl.java
@@ -16,7 +16,6 @@
package com.android.gallery3d.ui;
-import android.graphics.Rect;
import android.graphics.RectF;
import android.opengl.GLU;
import android.opengl.Matrix;
@@ -32,6 +31,7 @@ import java.util.ArrayList;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;
import javax.microedition.khronos.opengles.GL11Ext;
+import javax.microedition.khronos.opengles.GL11ExtensionPack;
public class GLCanvasImpl implements GLCanvas {
@SuppressWarnings("unused")
@@ -61,10 +61,10 @@ public class GLCanvasImpl implements GLCanvas {
private int mBoxCoords;
private final GLState mGLState;
+ private final ArrayList<RawTexture> mTargetStack = new ArrayList<RawTexture>();
private float mAlpha;
- private final ArrayList<ConfigState> mRestoreStack =
- new ArrayList<ConfigState>();
+ private final ArrayList<ConfigState> mRestoreStack = new ArrayList<ConfigState>();
private ConfigState mRecycledRestoreAction;
private final RectF mDrawTextureSourceRect = new RectF();
@@ -72,8 +72,12 @@ public class GLCanvasImpl implements GLCanvas {
private final float[] mTempMatrix = new float[32];
private final IntArray mUnboundTextures = new IntArray();
private final IntArray mDeleteBuffers = new IntArray();
- private int mHeight;
+ private int mScreenWidth;
+ private int mScreenHeight;
private boolean mBlendEnabled = true;
+ private int mFrameBuffer[] = new int[1];
+
+ private RawTexture mTargetTexture;
// Drawing statistics
int mCountDrawLine;
@@ -90,7 +94,12 @@ public class GLCanvasImpl implements GLCanvas {
public void setSize(int width, int height) {
Utils.assertTrue(width >= 0 && height >= 0);
- mHeight = height;
+
+ if (mTargetTexture == null) {
+ mScreenWidth = width;
+ mScreenHeight = height;
+ }
+ mAlpha = 1.0f;
GL11 gl = mGL;
gl.glViewport(0, 0, width, height);
@@ -100,11 +109,14 @@ public class GLCanvasImpl implements GLCanvas {
gl.glMatrixMode(GL11.GL_MODELVIEW);
gl.glLoadIdentity();
- float matrix[] = mMatrixValues;
+ float matrix[] = mMatrixValues;
Matrix.setIdentityM(matrix, 0);
- Matrix.translateM(matrix, 0, 0, mHeight, 0);
- Matrix.scaleM(matrix, 0, 1, -1, 1);
+ // to match the graphic coordinate system in android, we flip it vertically.
+ if (mTargetTexture == null) {
+ Matrix.translateM(matrix, 0, 0, height, 0);
+ Matrix.scaleM(matrix, 0, 1, -1, 1);
+ }
}
public void setAlpha(float alpha) {
@@ -151,8 +163,7 @@ public class GLCanvasImpl implements GLCanvas {
gl.glClientActiveTexture(GL11.GL_TEXTURE0);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
- // mMatrixValues will be initialized in setSize()
- mAlpha = 1.0f;
+ // mMatrixValues and mAlpha will be initialized in setSize()
}
public void drawRect(float x, float y, float width, float height, GLPaint paint) {
@@ -724,7 +735,6 @@ public class GLCanvasImpl implements GLCanvas {
private static class ConfigState {
float mAlpha;
- Rect mRect = new Rect();
float mMatrix[] = new float[16];
ConfigState mNextFree;
@@ -756,4 +766,79 @@ public class GLCanvasImpl implements GLCanvas {
private void restoreTransform() {
System.arraycopy(mTempMatrix, 0, mMatrixValues, 0, 16);
}
+
+ private void setRenderTarget(RawTexture texture) {
+ GL11ExtensionPack gl11ep = (GL11ExtensionPack) mGL;
+
+ if (mTargetTexture == null && texture != null) {
+ GLId.glGenBuffers(1, mFrameBuffer, 0);
+ gl11ep.glBindFramebufferOES(
+ GL11ExtensionPack.GL_FRAMEBUFFER_OES, mFrameBuffer[0]);
+ }
+ if (mTargetTexture != null && texture == null) {
+ gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, 0);
+ gl11ep.glDeleteFramebuffersOES(1, mFrameBuffer, 0);
+ }
+
+ mTargetTexture = texture;
+ if (texture == null) {
+ setSize(mScreenWidth, mScreenHeight);
+ } else {
+ setSize(texture.getWidth(), texture.getHeight());
+
+ if (!texture.isLoaded(this)) texture.prepare(this);
+
+ gl11ep.glFramebufferTexture2DOES(
+ GL11ExtensionPack.GL_FRAMEBUFFER_OES,
+ GL11ExtensionPack.GL_COLOR_ATTACHMENT0_OES,
+ GL11.GL_TEXTURE_2D, texture.getId(), 0);
+
+ checkFramebufferStatus(gl11ep);
+ }
+ }
+
+ @Override
+ public void endRenderTarget() {
+ RawTexture texture = mTargetStack.remove(mTargetStack.size() - 1);
+ setRenderTarget(texture);
+ restore(); // restore matrix and alpha
+ }
+
+ @Override
+ public void beginRenderTarget(RawTexture texture) {
+ save(); // save matrix and alpha
+ mTargetStack.add(mTargetTexture);
+ setRenderTarget(texture);
+ }
+
+ private static void checkFramebufferStatus(GL11ExtensionPack gl11ep) {
+ int status = gl11ep.glCheckFramebufferStatusOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES);
+ if (status != GL11ExtensionPack.GL_FRAMEBUFFER_COMPLETE_OES) {
+ String msg = "";
+ switch (status) {
+ case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES:
+ msg = "FRAMEBUFFER_FORMATS";
+ break;
+ case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES:
+ msg = "FRAMEBUFFER_ATTACHMENT";
+ break;
+ case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES:
+ msg = "FRAMEBUFFER_MISSING_ATTACHMENT";
+ break;
+ case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES:
+ msg = "FRAMEBUFFER_DRAW_BUFFER";
+ break;
+ case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES:
+ msg = "FRAMEBUFFER_READ_BUFFER";
+ break;
+ case GL11ExtensionPack.GL_FRAMEBUFFER_UNSUPPORTED_OES:
+ msg = "FRAMEBUFFER_UNSUPPORTED";
+ break;
+ case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES:
+ msg = "FRAMEBUFFER_INCOMPLETE_DIMENSIONS";
+ break;
+ }
+ throw new RuntimeException(msg + ":" + Integer.toHexString(status));
+ }
+ }
}
diff --git a/src/com/android/gallery3d/ui/Raw2DTexture.java b/src/com/android/gallery3d/ui/Raw2DTexture.java
deleted file mode 100644
index b7e4e6d59..000000000
--- a/src/com/android/gallery3d/ui/Raw2DTexture.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.gallery3d.ui;
-
-import android.opengl.GLU;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
-import javax.microedition.khronos.opengles.GL11;
-import javax.microedition.khronos.opengles.GL11Ext;
-import javax.microedition.khronos.opengles.GL11ExtensionPack;
-
-/**
- * A wrapper class of GL 2D texture.
- */
-public class Raw2DTexture extends BasicTexture {
- private static final int[] sTextureId = new int[1];
- // OpenGL related fields used when copy.
- private static final int[] sBufferName = new int[1];
- private int mFBO; // Frame buffer object.
-
- // We need copy from another texture when in camera capture animation.
- // The copy is done through a framebuffer object with an attached
- // destination texture. The source texture is rendered to the framebuffer
- // and the data will be stored in the destination texture.
- public static void copy(GLCanvas canvas, BasicTexture src, Raw2DTexture dst) {
- int[] viewPort = new int[4];
- GL11 gl11 = canvas.getGLInstance();
- GL11ExtensionPack gl11ep = (GL11ExtensionPack) gl11;
-
- if (!dst.isLoaded(canvas)) {
- dst.prepare(canvas.getGLInstance());
- }
-
- gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, dst.mFBO);
- gl11ep.glFramebufferTexture2DOES(
- GL11ExtensionPack.GL_FRAMEBUFFER_OES,
- GL11ExtensionPack.GL_COLOR_ATTACHMENT0_OES,
- GL11.GL_TEXTURE_2D,
- dst.getId(), 0);
- checkFramebufferStatus(gl11ep);
-
- // Draw the source onto our destination.
- // The texture coords and vertex pointer are already set properly. We don't
- // need to set again.
- gl11.glBindTexture(src.getTarget(), src.getId());
- boolean targetEnabled = gl11.glIsEnabled(src.getTarget());
- gl11.glEnable(src.getTarget());
-
- // Set the texture matrix.
- gl11.glMatrixMode(GL11.GL_TEXTURE);
- gl11.glPushMatrix();
- gl11.glLoadIdentity();
-
- // Set the view port.
- gl11.glGetIntegerv(GL11.GL_VIEWPORT, viewPort, 0);
- gl11.glViewport(0, 0, dst.getTextureWidth(), dst.getTextureHeight());
-
- // Set the projection matrix.
- gl11.glMatrixMode(GL11.GL_PROJECTION);
- gl11.glPushMatrix();
- gl11.glLoadIdentity();
- GLU.gluOrtho2D(gl11, 0, 1, 0, 1);
-
- // Set the modelview matrix.
- gl11.glMatrixMode(GL11.GL_MODELVIEW);
- gl11.glPushMatrix();
- gl11.glLoadIdentity();
-
- // Draw the texture.
- gl11.glDrawArrays(GL11.GL_TRIANGLE_STRIP, 0, 4);
-
- // Clear.
- if (!targetEnabled) gl11.glDisable(src.getTarget());
- gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, 0);
- gl11.glBindTexture(src.getTarget(), 0);
- gl11.glViewport(viewPort[0], viewPort[1], viewPort[2], viewPort[3]);
- gl11.glMatrixMode(GL11.GL_TEXTURE);
- gl11.glPopMatrix();
- gl11.glMatrixMode(GL11.GL_PROJECTION);
- gl11.glPopMatrix();
- gl11.glMatrixMode(GL11.GL_MODELVIEW);
- gl11.glPopMatrix();
- GLId.glDeleteFramebuffers(gl11ep, 1, dst.sBufferName, 0);
- }
-
- public Raw2DTexture(int w, int h) {
- setSize(w, h);
- GLId.glGenTextures(1, sTextureId, 0);
- mId = sTextureId[0];
- GLId.glGenBuffers(1, sBufferName, 0);
- mFBO = sBufferName[0];
- }
-
- private void prepare(GL11 gl11) {
- gl11.glBindTexture(GL11.GL_TEXTURE_2D, mId);
- gl11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP_TO_EDGE);
- gl11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP_TO_EDGE);
- gl11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
- gl11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
- gl11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA,
- getTextureWidth(), getTextureHeight(),
- 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, null);
- gl11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
- mState = UploadedTexture.STATE_LOADED;
- }
-
- @Override
- protected boolean onBind(GLCanvas canvas) {
- if (!isLoaded(canvas)) {
- return false;
- }
-
- return true;
- }
-
- @Override
- public int getTarget() {
- return GL11.GL_TEXTURE_2D;
- }
-
- public boolean isOpaque() {
- return true;
- }
-
- @Override
- public void yield() {
- // we cannot free the texture because we have no backup.
- }
-
- private static void checkFramebufferStatus(GL11ExtensionPack gl11ep) {
- int status = gl11ep.glCheckFramebufferStatusOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES);
- if (status != GL11ExtensionPack.GL_FRAMEBUFFER_COMPLETE_OES) {
- String msg = "";
- switch (status) {
- case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES:
- msg = "FRAMEBUFFER_FORMATS"; break;
- case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES:
- msg = "FRAMEBUFFER_ATTACHMENT"; break;
- case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES:
- msg = "FRAMEBUFFER_MISSING_ATTACHMENT"; break;
- case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES:
- msg = "FRAMEBUFFER_DRAW_BUFFER"; break;
- case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES:
- msg = "FRAMEBUFFER_READ_BUFFER"; break;
- case GL11ExtensionPack.GL_FRAMEBUFFER_UNSUPPORTED_OES:
- msg = "FRAMEBUFFER_UNSUPPORTED"; break;
- case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES:
- msg = "FRAMEBUFFER_INCOMPLETE_DIMENSIONS"; break;
- }
- throw new RuntimeException(msg + ":" + Integer.toHexString(status));
- }
- }
-}
diff --git a/src/com/android/gallery3d/ui/RawTexture.java b/src/com/android/gallery3d/ui/RawTexture.java
new file mode 100644
index 000000000..e1af7d209
--- /dev/null
+++ b/src/com/android/gallery3d/ui/RawTexture.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import javax.microedition.khronos.opengles.GL11;
+import javax.microedition.khronos.opengles.GL11Ext;
+
+public class RawTexture extends BasicTexture {
+ private static final String TAG = "RawTexture";
+
+ private final static int[] sTextureId = new int[1];
+ private final static float[] sCropRect = new float[4];
+
+ private final boolean mOpaque;
+
+ public RawTexture(int width, int height, boolean opaque) {
+ mOpaque = opaque;
+ setSize(width, height);
+ }
+
+ @Override
+ public boolean isOpaque() {
+ return mOpaque;
+ }
+
+ protected void prepare(GLCanvas canvas) {
+ GL11 gl = canvas.getGLInstance();
+
+ // Define a vertically flipped crop rectangle for
+ // OES_draw_texture.
+ // The four values in sCropRect are: left, bottom, width, and
+ // height. Negative value of width or height means flip.
+ sCropRect[0] = 0;
+ sCropRect[1] = mHeight;
+ sCropRect[2] = mWidth;
+ sCropRect[3] = -mHeight;
+
+ // Upload the bitmap to a new texture.
+ GLId.glGenTextures(1, sTextureId, 0);
+ gl.glBindTexture(GL11.GL_TEXTURE_2D, sTextureId[0]);
+ gl.glTexParameterfv(GL11.GL_TEXTURE_2D,
+ GL11Ext.GL_TEXTURE_CROP_RECT_OES, sCropRect, 0);
+ gl.glTexParameteri(GL11.GL_TEXTURE_2D,
+ GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP_TO_EDGE);
+ gl.glTexParameteri(GL11.GL_TEXTURE_2D,
+ GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP_TO_EDGE);
+ gl.glTexParameterf(GL11.GL_TEXTURE_2D,
+ GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
+ gl.glTexParameterf(GL11.GL_TEXTURE_2D,
+ GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
+
+ gl.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA,
+ getTextureWidth(), getTextureHeight(),
+ 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, null);
+
+ mId = sTextureId[0];
+ mState = UploadedTexture.STATE_LOADED;
+ setAssociatedCanvas(canvas);
+ }
+
+ @Override
+ protected boolean onBind(GLCanvas canvas) {
+ if (isLoaded(canvas)) return true;
+ Log.w(TAG, "lost the content due to context change");
+ return false;
+ }
+
+ @Override
+ public void yield() {
+ // we cannot free the texture because we have no backup.
+ }
+
+ @Override
+ protected int getTarget() {
+ return GL11.GL_TEXTURE_2D;
+ }
+}
diff --git a/tests/src/com/android/gallery3d/ui/GLCanvasStub.java b/tests/src/com/android/gallery3d/ui/GLCanvasStub.java
index ee43cb943..5f749d8fc 100644
--- a/tests/src/com/android/gallery3d/ui/GLCanvasStub.java
+++ b/tests/src/com/android/gallery3d/ui/GLCanvasStub.java
@@ -80,4 +80,6 @@ public class GLCanvasStub implements GLCanvas {
public void deleteRecycledResources() {}
public void multiplyMatrix(float[] mMatrix, int offset) {}
public void dumpStatisticsAndClear() {}
+ public void beginRenderTarget(RawTexture texture) {}
+ public void endRenderTarget() {}
}