Change canvas interface and add more tests.

- How color is sepcified for drawLine and fillRect.
- onBind instead of bindTexture.
- Fix drawLine in MenuBar.
- Add tests for drawMixed.

Change-Id: I1ff8305baf44d2d622c1bb40e636f53934f1d6b5
diff --git a/new3d/src/com/android/gallery3d/ui/BasicTexture.java b/new3d/src/com/android/gallery3d/ui/BasicTexture.java
index 83cf10f..e3dccec 100644
--- a/new3d/src/com/android/gallery3d/ui/BasicTexture.java
+++ b/new3d/src/com/android/gallery3d/ui/BasicTexture.java
@@ -73,7 +73,7 @@
         canvas.drawTexture(this, x, y, w, h);
     }
 
-    abstract protected void bind(GLCanvas canvas);
+    abstract protected void onBind(GLCanvas canvas);
 
     public boolean isLoaded(GLCanvas canvas) {
         return mState == STATE_LOADED && mGL == canvas.getGLInstance();
diff --git a/new3d/src/com/android/gallery3d/ui/ColorTexture.java b/new3d/src/com/android/gallery3d/ui/ColorTexture.java
index 19d886a..3386737 100644
--- a/new3d/src/com/android/gallery3d/ui/ColorTexture.java
+++ b/new3d/src/com/android/gallery3d/ui/ColorTexture.java
@@ -33,8 +33,7 @@
     }
 
     public void draw(GLCanvas canvas, int x, int y, int w, int h) {
-        canvas.bindColor(mColor);
-        canvas.fillRect(x, y, w, h);
+        canvas.fillRect(x, y, w, h, mColor);
     }
 
     public boolean isOpaque() {
diff --git a/new3d/src/com/android/gallery3d/ui/GLCanvas.java b/new3d/src/com/android/gallery3d/ui/GLCanvas.java
index eb63a7c..bf72845 100644
--- a/new3d/src/com/android/gallery3d/ui/GLCanvas.java
+++ b/new3d/src/com/android/gallery3d/ui/GLCanvas.java
@@ -63,16 +63,12 @@
     // last save call.
     public void restore();
 
-    // Binds the current drawing color to the canvas. It will be used for
-    // drawLine and fillRect. The format is 0xaarrggbb.
-    public void bindColor(int color);
-
-    // Draws a line using current drawing color from (x1, y1) to (x2, y2).
+    // Draws a line using the specified color from (x1, y1) to (x2, y2).
     // (Both end points are included).
-    public void drawLine(int x1, int y1, int x2, int y2);
+    public void drawLine(int x1, int y1, int x2, int y2, int color);
 
-    // Fills the specified rectange with the current drawing color.
-    public void fillRect(float x, float y, float width, float height);
+    // Fills the specified rectange with the specified color.
+    public void fillRect(float x, float y, float width, float height, int color);
 
     // Draws a texture to the specified rectangle.
     public void drawTexture(
@@ -103,10 +99,6 @@
     // GL is needed.
     public GL11 getGLInstance();
 
-    // Binds the texture to the canvas for the following drawing calls. This
-    // function should only be called in Texture.
-    public void bindTexture(int id);
-
     // Unloads the specified texture from the canvas. The resource allocated
     // to draw the texture will be released. The specified texture will return
     // to the unloaded state.
diff --git a/new3d/src/com/android/gallery3d/ui/GLCanvasImp.java b/new3d/src/com/android/gallery3d/ui/GLCanvasImp.java
index fe02bd3..820c1e7 100644
--- a/new3d/src/com/android/gallery3d/ui/GLCanvasImp.java
+++ b/new3d/src/com/android/gallery3d/ui/GLCanvasImp.java
@@ -50,7 +50,6 @@
     private long mAnimationTime;
 
     private float mAlpha;
-    private int mBoundColor;
     private final Rect mClipRect = new Rect();
     private final Stack<ConfigState> mRestoreStack =
             new Stack<ConfigState>();
@@ -148,13 +147,8 @@
         pointer.put(buffer, 0, 8).position(0);
     }
 
-    public void bindColor(int color) {
-        mBoundColor = color;
-        mGLState.setTexture2DEnabled(false);
-    }
-
-    public void drawLine(int x1, int y1, int x2, int y2) {
-        mGLState.setColorAlpha(mBoundColor, mAlpha);
+    public void drawLine(int x1, int y1, int x2, int y2, int color) {
+        mGLState.setColorMode(color, mAlpha);
         GL11 gl = mGL;
         gl.glLoadMatrixf(mMatrixValues, 0);
         float buffer[] = mXyBuffer;
@@ -166,6 +160,14 @@
         gl.glDrawArrays(GL11.GL_LINE_STRIP, 0, 2);
     }
 
+    public void fillRect(float x, float y, float width, float height, int color) {
+        mGLState.setColorMode(color, mAlpha);
+        GL11 gl = mGL;
+        gl.glLoadMatrixf(mMatrixValues, 0);
+        putRectangle(x, y, width, height, mXyBuffer, mXyPointer);
+        gl.glDrawArrays(GL11.GL_TRIANGLE_STRIP, 0, 4);
+    }
+
     public void translate(float x, float y, float z) {
         Matrix.translateM(mMatrixValues, 0, x, y, z);
     }
@@ -181,8 +183,8 @@
         System.arraycopy(temp, 16, mMatrixValues, 0, 16);
     }
 
-    public void fillRect(float x, float y, float width, float height) {
-        mGLState.setColorAlpha(mBoundColor, mAlpha);
+    private void textureRect(float x, float y, float width, float height, float alpha) {
+        mGLState.setTextureAlpha(alpha);
         GL11 gl = mGL;
         gl.glLoadMatrixf(mMatrixValues, 0);
         putRectangle(x, y, width, height, mXyBuffer, mXyPointer);
@@ -200,7 +202,7 @@
         if (chunk.mDivX.length != 2 || chunk.mDivY.length != 2) {
             throw new RuntimeException("unsupported nine patch");
         }
-        tex.bind(this);
+        bindTexture(tex);
         if (width <= 0 || height <= 0) return;
 
         int divX[] = mNinePatchX;
@@ -422,7 +424,7 @@
                     (texture.mWidth - 0.5f) / texture.mTextureWidth,
                     (texture.mHeight - 0.5f) / texture.mTextureHeight,
                     mUvBuffer, mUvPointer);
-            fillRect(x, y, width, height);
+            textureRect(x, y, width, height, alpha);
         } else {
             // draw the rect from bottom-left to top-right
             float points[] = mapPoints(
@@ -449,7 +451,7 @@
         if (width <= 0 || height <= 0) return;
 
         mGLState.setBlendEnabled(!texture.isOpaque() || alpha < OPAQUE_ALPHA);
-        texture.bind(this);
+        bindTexture(texture);
         drawBoundTexture(texture, x, y, width, height, alpha);
     }
 
@@ -463,11 +465,11 @@
         target = mDrawTextureTargetRect;
 
         mGLState.setBlendEnabled(!texture.isOpaque() || mAlpha < OPAQUE_ALPHA);
-        texture.bind(this);
+        bindTexture(texture);
         convertCoordinate(source, target, texture);
         setTextureCoords(source);
-        fillRect(target.left, target.top, target.right - target.left,
-                target.bottom - target.top);
+        textureRect(target.left, target.top, target.right - target.left,
+                target.bottom - target.top, mAlpha);
     }
 
     // This function changes the source coordinate to the texture coordinates.
@@ -506,9 +508,10 @@
         drawMixed(from, to, ratio, x, y, w, h, mAlpha);
     }
 
-    public void bindTexture(int id) {
+    private void bindTexture(BasicTexture texture) {
+        texture.onBind(this);
         mGLState.setTexture2DEnabled(true);
-        mGL.glBindTexture(GL11.GL_TEXTURE_2D, id);
+        mGL.glBindTexture(GL11.GL_TEXTURE_2D, texture.mId);
     }
 
     private void setTextureColor(float r, float g, float b, float alpha) {
@@ -530,10 +533,10 @@
         mGLState.setBlendEnabled(!from.isOpaque() || !to.isOpaque());
 
         final GL11 gl = mGL;
-        from.bind(this);
+        bindTexture(from);
 
         gl.glActiveTexture(GL11.GL_TEXTURE1);
-        to.bind(this);
+        bindTexture(to);
         gl.glEnable(GL11.GL_TEXTURE_2D);
 
         // Interpolate the RGB and alpha values between both textures.
@@ -542,7 +545,7 @@
         gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_COMBINE_ALPHA, GL11.GL_INTERPOLATE);
 
         // Specify the interpolation factor via the alpha component of
-        // GL_TEXTURE_ENV_COLORes.
+        // GL_TEXTURE_ENV_COLORs.
         setTextureColor(ratio, ratio, ratio, ratio);
         gl.glTexEnvfv(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_COLOR, mTextureColor, 0);
 
@@ -555,7 +558,7 @@
         gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND2_ALPHA, GL11.GL_SRC_ALPHA);
 
         // Draw the combined texture.
-        drawBoundTexture(to, x, y, width, height, mAlpha);
+        drawBoundTexture(to, x, y, width, height, alpha);
 
         // Disable TEXTURE1.
         gl.glDisable(GL11.GL_TEXTURE_2D);
@@ -667,15 +670,6 @@
             mGL.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, mode);
         }
 
-        public void setColorAlpha(int color, float alpha) {
-            if (mTexture2DEnabled) {
-                setTextureAlpha(alpha);
-            } else {
-                setBlendEnabled(!Util.isOpaque(color) || alpha < OPAQUE_ALPHA);
-                setFragmentColor(color, alpha);
-            }
-        }
-
         public void setTextureAlpha(float alpha) {
             if (mTextureAlpha == alpha) return;
             mTextureAlpha = alpha;
@@ -689,7 +683,9 @@
             }
         }
 
-        public void setFragmentColor(int color, float alpha) {
+        public void setColorMode(int color, float alpha) {
+            setBlendEnabled(!Util.isOpaque(color) || alpha < OPAQUE_ALPHA);
+
             // Set mTextureAlpha to an invalid value, so that it will reset
             // again in setTextureAlpha(float) later.
             mTextureAlpha = -1.0f;
diff --git a/new3d/src/com/android/gallery3d/ui/MenuBar.java b/new3d/src/com/android/gallery3d/ui/MenuBar.java
index 19558bb..2a40b07 100644
--- a/new3d/src/com/android/gallery3d/ui/MenuBar.java
+++ b/new3d/src/com/android/gallery3d/ui/MenuBar.java
@@ -104,12 +104,11 @@
         int left = p.left;
         int right = left + width;
 
-        canvas.bindColor(BORDER_COLOR);
-        canvas.drawLine(left, top, right, top);
-        canvas.drawLine(left, bottom - 1, right, bottom -1);
+        canvas.drawLine(left, top, right, top, BORDER_COLOR);
+        canvas.drawLine(left, bottom - 1, right, bottom - 1, BORDER_COLOR);
         for (int i = 0, n = getComponentCount() - 1; i < n; ++i) {
             Rect bounds = getComponent(i).mBounds;
-            canvas.drawLine(bounds.right, top, bounds.right, bottom);
+            canvas.drawLine(bounds.right, top + 1, bounds.right, bottom - 2, BORDER_COLOR);
         }
     }
 }
diff --git a/new3d/src/com/android/gallery3d/ui/RawTexture.java b/new3d/src/com/android/gallery3d/ui/RawTexture.java
index e7eaafb..f440d0b 100644
--- a/new3d/src/com/android/gallery3d/ui/RawTexture.java
+++ b/new3d/src/com/android/gallery3d/ui/RawTexture.java
@@ -36,12 +36,11 @@
     }
 
     @Override
-    protected void bind(GLCanvas canvas) {
+    protected void onBind(GLCanvas canvas) {
         GL11 gl = canvas.getGLInstance();
         if (mGL != gl) {
             throw new RuntimeException("cannot bind to different GL");
         }
-        canvas.bindTexture(mId);
     }
 
     public boolean isOpaque() {
diff --git a/new3d/src/com/android/gallery3d/ui/UploadedTexture.java b/new3d/src/com/android/gallery3d/ui/UploadedTexture.java
index bb2e462..d0073a7 100644
--- a/new3d/src/com/android/gallery3d/ui/UploadedTexture.java
+++ b/new3d/src/com/android/gallery3d/ui/UploadedTexture.java
@@ -153,9 +153,8 @@
     }
 
     @Override
-    protected void bind(GLCanvas canvas) {
+    protected void onBind(GLCanvas canvas) {
         updateContent(canvas);
-        canvas.bindTexture(mId);
     }
 
     public boolean isOpaque() {
diff --git a/new3d/tests/src/com/android/gallery3d/ui/GLCanvasTest.java b/new3d/tests/src/com/android/gallery3d/ui/GLCanvasTest.java
index 5287083..020f5e9 100644
--- a/new3d/tests/src/com/android/gallery3d/ui/GLCanvasTest.java
+++ b/new3d/tests/src/com/android/gallery3d/ui/GLCanvasTest.java
@@ -82,8 +82,7 @@
             canvas.setSize(400, 300);
             // Test one color to make sure blend function is set.
             assertEquals(0, mGLColorCalled);
-            canvas.bindColor(0x7F804020);
-            canvas.drawLine(0, 0, 1, 1);
+            canvas.drawLine(0, 0, 1, 1, 0x7F804020);
             assertEquals(1, mGLColorCalled);
             assertEquals(0x7F402010, mGLColor);
             assertPremultipliedBlending(this);
@@ -97,8 +96,7 @@
                 int pre = makeColor4f(a * r, a * g, a * b, a);
 
                 mGLColorCalled = 0;
-                canvas.bindColor(c);
-                canvas.drawLine(0, 0, 1, 1);
+                canvas.drawLine(0, 0, 1, 1, c);
                 assertEquals(1, mGLColorCalled);
                 assertEquals(pre, mGLColor);
             }
@@ -151,9 +149,8 @@
             canvas.setSize(400, 300);
 
             assertEquals(0, mGLColorCalled);
-            canvas.bindColor(0xFF804020);
             canvas.setAlpha(0.48f);
-            canvas.drawLine(0, 0, 1, 1);
+            canvas.drawLine(0, 0, 1, 1, 0xFF804020);
             assertPremultipliedBlending(this);
             assertEquals(1, mGLColorCalled);
             assertEquals(0x7A3D1F0F, mGLColor);
@@ -192,7 +189,7 @@
         void run() {
             GLCanvas canvas = new GLCanvasImp(this);
             canvas.setSize(400, 300);
-            canvas.drawLine(2, 7, 1, 8);
+            canvas.drawLine(2, 7, 1, 8, 0 /* color */);
             assertTrue(mGLVertexArrayEnabled);
             assertEquals(1, mDrawArrayCalled);
 
@@ -236,7 +233,7 @@
         void run() {
             GLCanvas canvas = new GLCanvasImp(this);
             canvas.setSize(400, 300);
-            canvas.fillRect(2, 7, 1, 8);
+            canvas.fillRect(2, 7, 1, 8, 0 /* color */);
             assertTrue(mGLVertexArrayEnabled);
             assertEquals(1, mDrawArrayCalled);
             Log.v(TAG, "result = " + Arrays.toString(mResult));
@@ -298,9 +295,10 @@
         void run() {
             GLCanvas canvas = new GLCanvasImp(this);
             canvas.setSize(40, 50);
+            int color = 0;
 
             // Initial matrix
-            canvas.drawLine(0, 0, 1, 1);
+            canvas.drawLine(0, 0, 1, 1, color);
             assertMatrixEq(new float[] {
                     1,  0, 0, 0,
                     0, -1, 0, 0,
@@ -317,7 +315,7 @@
 
             // Translation
             canvas.translate(3, 4, 5);
-            canvas.drawLine(0, 0, 1, 1);
+            canvas.drawLine(0, 0, 1, 1, color);
             assertMatrixEq(new float[] {
                     1,  0, 0, 0,
                     0, -1, 0, 0,
@@ -328,7 +326,7 @@
 
             // Scaling
             canvas.scale(0.7f, 0.6f, 0.5f);
-            canvas.drawLine(0, 0, 1, 1);
+            canvas.drawLine(0, 0, 1, 1, color);
             assertMatrixEq(new float[] {
                     0.7f,     0,    0, 0,
                     0,    -0.6f,    0, 0,
@@ -338,7 +336,7 @@
 
             // Rotation
             canvas.rotate(90, 0, 0, 1);
-            canvas.drawLine(0, 0, 1, 1);
+            canvas.drawLine(0, 0, 1, 1, color);
             assertMatrixEq(new float[] {
                         0, -0.6f,    0, 0,
                     -0.7f,     0,    0, 0,
@@ -350,7 +348,7 @@
             // After restoring to the point just after translation,
             // do rotation again.
             canvas.rotate(180, 1, 0, 0);
-            canvas.drawLine(0, 0, 1, 1);
+            canvas.drawLine(0, 0, 1, 1, color);
             assertMatrixEq(new float[] {
                     1,  0,  0, 0,
                     0,  1,  0, 0,
@@ -487,6 +485,7 @@
     @SmallTest
     public void testDrawTexture() {
         new DrawTextureTest().run();
+        new DrawTextureMixedTest().run();
     }
 
     private static class MyTexture extends BasicTexture {
@@ -499,9 +498,8 @@
             mIsOpaque = isOpaque;
         }
 
-        protected void bind(GLCanvas canvas) {
+        protected void onBind(GLCanvas canvas) {
             mBindCalled++;
-            canvas.bindTexture(mId);
         }
 
         public boolean isOpaque() {
@@ -546,13 +544,13 @@
             // Draw a non-opaque texture
             canvas.drawTexture(texture, 100, 200, 300, 400);
             assertEquals(42, mGLBindTextureId);
-            assertEquals(GL11.GL_REPLACE, mGLEnvMode);
+            assertEquals(GL_REPLACE, getTexEnvi(GL_TEXTURE_ENV_MODE));
             assertPremultipliedBlending(this);
 
             // Draw an opaque texture
             canvas.drawTexture(texture_o, 100, 200, 300, 400);
             assertEquals(47, mGLBindTextureId);
-            assertEquals(GL11.GL_REPLACE, mGLEnvMode);
+            assertEquals(GL_REPLACE, getTexEnvi(GL_TEXTURE_ENV_MODE));
             assertFalse(mGLBlendEnabled);
 
             // Draw a non-opaque texture with alpha = 0.5
@@ -560,30 +558,41 @@
             canvas.drawTexture(texture, 100, 200, 300, 400);
             assertEquals(42, mGLBindTextureId);
             assertEquals(0x80808080, mGLColor);
-            assertEquals(GL11.GL_MODULATE, mGLEnvMode);
+            assertEquals(GL_MODULATE, getTexEnvi(GL_TEXTURE_ENV_MODE));
             assertPremultipliedBlending(this);
 
             // Draw an non-opaque texture with overriden alpha = 1
             canvas.drawTexture(texture, 100, 200, 300, 400, 1f);
             assertEquals(42, mGLBindTextureId);
-            assertEquals(GL11.GL_REPLACE, mGLEnvMode);
+            assertEquals(GL_REPLACE, getTexEnvi(GL_TEXTURE_ENV_MODE));
             assertPremultipliedBlending(this);
 
             // Draw an opaque texture with overriden alpha = 1
             canvas.drawTexture(texture_o, 100, 200, 300, 400, 1f);
             assertEquals(47, mGLBindTextureId);
-            assertEquals(GL11.GL_REPLACE, mGLEnvMode);
+            assertEquals(GL_REPLACE, getTexEnvi(GL_TEXTURE_ENV_MODE));
             assertFalse(mGLBlendEnabled);
 
             // Draw an opaque texture with overridden alpha = 0.25
             canvas.drawTexture(texture_o, 100, 200, 300, 400, 0.25f);
             assertEquals(47, mGLBindTextureId);
             assertEquals(0x40404040, mGLColor);
-            assertEquals(GL11.GL_MODULATE, mGLEnvMode);
+            assertEquals(GL_MODULATE, getTexEnvi(GL_TEXTURE_ENV_MODE));
             assertPremultipliedBlending(this);
 
-            // We have drawn six textures above.
-            assertEquals(0, mDrawArrayCalled);
+            // Draw an opaque texture with overridden alpha = 0.125
+            // but with some rotation so it will use DrawArray.
+            canvas.save();
+            canvas.rotate(30, 0, 0, 1);
+            canvas.drawTexture(texture_o, 100, 200, 300, 400, 0.125f);
+            canvas.restore();
+            assertEquals(47, mGLBindTextureId);
+            assertEquals(0x20202020, mGLColor);
+            assertEquals(GL_MODULATE, getTexEnvi(GL_TEXTURE_ENV_MODE));
+            assertPremultipliedBlending(this);
+
+            // We have drawn seven textures above.
+            assertEquals(1, mDrawArrayCalled);
             assertEquals(6, mDrawTexiOESCalled);
 
             // translate and scale does not affect whether we
@@ -612,7 +621,89 @@
             canvas.drawTexture(texture, 100, 200, 300, 400);
             assertEquals(10, mDrawTexiOESCalled);
 
-            assertEquals(2, mDrawArrayCalled);
+            assertEquals(3, mDrawArrayCalled);
+
+            assertTrue(texture.isLoaded(canvas));
+            assertTrue(canvas.unloadTexture(texture));
+            assertFalse(texture.isLoaded(canvas));
+            canvas.deleteRecycledTextures();
+
+            assertTrue(texture_o.isLoaded(canvas));
+            assertTrue(canvas.unloadTexture(texture_o));
+            assertFalse(texture_o.isLoaded(canvas));
+        }
+    }
+
+    private static class DrawTextureMixedTest extends GLMock {
+
+        boolean mTexture2DEnabled0, mTexture2DEnabled1;
+        @Override
+        public void glEnable(int cap) {
+            if (cap == GL_TEXTURE_2D) {
+                texture2DEnable(true);
+            }
+        }
+
+        @Override
+        public void glDisable(int cap) {
+            if (cap == GL_TEXTURE_2D) {
+                texture2DEnable(false);
+            }
+        }
+
+        private void texture2DEnable(boolean enable) {
+            if (mGLActiveTexture == GL_TEXTURE0) {
+                mTexture2DEnabled0 = enable;
+            } else if (mGLActiveTexture == GL_TEXTURE1) {
+                mTexture2DEnabled1 = enable;
+            } else {
+                fail();
+            }
+        }
+
+        @Override
+        public void glTexEnvfv(int target, int pname, float[] params, int offset) {
+            if (target == GL_TEXTURE_ENV && pname == GL_TEXTURE_ENV_COLOR) {
+                for (int i = 0; i < 4; i++) {
+                    assertEquals(0.5f, params[offset + i]);
+                }
+            }
+        }
+
+        @Override
+        public void glBindTexture(int target, int texture) {
+            if (target == GL_TEXTURE_2D) {
+                if (mGLActiveTexture == GL_TEXTURE0) {
+                    assertEquals(42, texture);
+                } else if (mGLActiveTexture == GL_TEXTURE1) {
+                    assertEquals(47, texture);
+                } else {
+                    fail();
+                }
+            }
+        }
+
+        void run() {
+            GLCanvas canvas = new GLCanvasImp(this);
+            canvas.setSize(400, 300);
+            MyTexture from = new MyTexture(this, 42, false);  // non-opaque
+            MyTexture to = new MyTexture(this, 47, true);  // opaque
+
+            canvas.drawMixed(from, to, 0.5f, 100, 200, 300, 400, 1.0f);
+            assertEquals(GL_COMBINE, getTexEnvi(GL_TEXTURE_ENV_MODE));
+            assertEquals(GL_INTERPOLATE, getTexEnvi(GL_COMBINE_RGB));
+            assertEquals(GL_INTERPOLATE, getTexEnvi(GL_COMBINE_ALPHA));
+            assertEquals(GL_CONSTANT, getTexEnvi(GL_SRC2_RGB));
+            assertEquals(GL_CONSTANT, getTexEnvi(GL_SRC2_ALPHA));
+            assertEquals(GL_SRC_ALPHA, getTexEnvi(GL_OPERAND2_RGB));
+            assertEquals(GL_SRC_ALPHA, getTexEnvi(GL_OPERAND2_ALPHA));
+            assertTrue(mTexture2DEnabled0);
+            assertFalse(mTexture2DEnabled1);
+
+            // The test is currently broken, waiting for the fix
+            //canvas.setAlpha(0.3f);
+            //canvas.drawMixed(from, to, 0.5f, 100, 200, 300, 400, 1.0f);
+            //assertEquals(GL_COMBINE, getTexEnvi(GL_TEXTURE_ENV_MODE));
         }
     }
 
diff --git a/new3d/tests/src/com/android/gallery3d/ui/GLMock.java b/new3d/tests/src/com/android/gallery3d/ui/GLMock.java
index a3e893e..c15c500 100644
--- a/new3d/tests/src/com/android/gallery3d/ui/GLMock.java
+++ b/new3d/tests/src/com/android/gallery3d/ui/GLMock.java
@@ -3,6 +3,7 @@
 import android.util.Log;
 
 import java.nio.Buffer;
+import java.util.HashMap;
 
 import javax.microedition.khronos.opengles.GL;
 import javax.microedition.khronos.opengles.GL10;
@@ -38,7 +39,9 @@
     // glBindTexture
     int mGLBindTextureId;
     // glTexEnvf
-    int mGLEnvMode;
+    HashMap<Integer, Float> mGLTexEnv = new HashMap<Integer, Float>();
+    // glActiveTexture
+    int mGLActiveTexture = GL11.GL_TEXTURE0;
 
     @Override
     public void glClear(int mask) {
@@ -131,12 +134,20 @@
 
     @Override
     public void glTexEnvf(int target, int pname, float param) {
-        if (target == GL11.GL_TEXTURE_ENV
-                && pname == GL11.GL_TEXTURE_ENV_MODE) {
-            mGLEnvMode = (int) param;
+        if (target == GL11.GL_TEXTURE_ENV) {
+            mGLTexEnv.put(pname, param);
         }
     }
 
+    public int getTexEnvi(int pname) {
+        return (int) mGLTexEnv.get(pname).floatValue();
+    }
+
+    @Override
+    public void glActiveTexture(int texture) {
+        mGLActiveTexture = texture;
+    }
+
     public static int makeColor4f(float red, float green, float blue,
             float alpha) {
         return (Math.round(alpha * 255) << 24) |