diff --git a/new3d/src/com/android/gallery3d/anim/AlphaAnimation.java b/new3d/src/com/android/gallery3d/anim/AlphaAnimation.java
index d806885..c55d7c2 100644
--- a/new3d/src/com/android/gallery3d/anim/AlphaAnimation.java
+++ b/new3d/src/com/android/gallery3d/anim/AlphaAnimation.java
@@ -23,7 +23,7 @@
 
     @Override
     public int getCanvasSaveFlags() {
-        return GLCanvas.ALPHA_SAVE_FLAG;
+        return GLCanvas.SAVE_FLAG_ALPHA;
     }
 
     @Override
diff --git a/new3d/src/com/android/gallery3d/anim/ScaleAnimation.java b/new3d/src/com/android/gallery3d/anim/ScaleAnimation.java
index f5dca50..f065cf7 100644
--- a/new3d/src/com/android/gallery3d/anim/ScaleAnimation.java
+++ b/new3d/src/com/android/gallery3d/anim/ScaleAnimation.java
@@ -51,7 +51,7 @@
 
     @Override
     public int getCanvasSaveFlags() {
-        return GLCanvas.MATRIX_SAVE_FLAG;
+        return GLCanvas.SAVE_FLAG_MATRIX;
     }
 
     @Override
diff --git a/new3d/src/com/android/gallery3d/ui/DisplayItemPanel.java b/new3d/src/com/android/gallery3d/ui/DisplayItemPanel.java
index ba6ec37..8b9a4bd 100644
--- a/new3d/src/com/android/gallery3d/ui/DisplayItemPanel.java
+++ b/new3d/src/com/android/gallery3d/ui/DisplayItemPanel.java
@@ -19,8 +19,8 @@
     // The state of the items that changed position
     private static final int STATE_MOVED = 3;
 
-    private static final long NO_ANIMATION = -1;
-    private static final long START_ANIMATION = 0;
+    private static final long START_ANIMATION = -1;
+    private static final long NO_ANIMATION = -2;
 
     private ArrayList<DisplayItem> mItems = new ArrayList<DisplayItem>();
 
@@ -114,7 +114,7 @@
     }
 
     private void renderItem(GLCanvas canvas, DisplayItem item) {
-        canvas.save(GLCanvas.ALPHA_SAVE_FLAG | GLCanvas.MATRIX_SAVE_FLAG);
+        canvas.save(GLCanvas.SAVE_FLAG_ALPHA | GLCanvas.SAVE_FLAG_MATRIX);
         item.mCurrent.apply(canvas);
         item.render(canvas);
         canvas.restore();
@@ -122,7 +122,7 @@
 
     private void renderItem(
             GLCanvas canvas, DisplayItem item, float interpolate) {
-        canvas.save(GLCanvas.ALPHA_SAVE_FLAG | GLCanvas.MATRIX_SAVE_FLAG);
+        canvas.save(GLCanvas.SAVE_FLAG_ALPHA | GLCanvas.SAVE_FLAG_MATRIX);
         switch (item.mState) {
             case STATE_MOVED:
                 item.updateCurrentPosition(interpolate);
diff --git a/new3d/src/com/android/gallery3d/ui/GLCanvas.java b/new3d/src/com/android/gallery3d/ui/GLCanvas.java
index 770cac4..5560098 100644
--- a/new3d/src/com/android/gallery3d/ui/GLCanvas.java
+++ b/new3d/src/com/android/gallery3d/ui/GLCanvas.java
@@ -2,773 +2,109 @@
 
 import android.graphics.Rect;
 import android.graphics.RectF;
-import android.opengl.GLU;
-import android.opengl.Matrix;
+import android.view.animation.Transformation;
 
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
 import java.util.Collection;
-import java.util.Stack;
 
-import javax.microedition.khronos.opengles.GL10;
 import javax.microedition.khronos.opengles.GL11;
-import javax.microedition.khronos.opengles.GL11Ext;
 
-public class GLCanvas {
+//
+// GLCanvas gives a convenient interface to draw using OpenGL.
+//
+// When a rectangle is specified in this interface, it means the region
+// [x, x+width) * [y, y+height)
+//
+public interface GLCanvas {
+    // Tells GLCanvas the size of the underlying GL surface. This should be
+    // called before first drawing and when the size of GL surface is changed.
+    // This is called by GLRootView and should not be called by the clients
+    // who only want to draw on the GLCanvas.
+    public void setSize(int width, int height);
 
-    public static final int ALL_SAVE_FLAG = 0xFFFFFFFF;
-    public static final int CLIP_SAVE_FLAG = 0x01;
-    public static final int ALPHA_SAVE_FLAG = 0x02;
-    public static final int MATRIX_SAVE_FLAG = 0x04;
+    // Clear the drawing buffers. This should only be used by GLRootView.
+    public void clearBuffer();
 
-    // We need 16 vertices for a normal nine-patch image (the 4x4 vertices)
-    private static final int VERTEX_BUFFER_SIZE = 16 * 2;
+    // This is the time value used to calculate the animation in the current
+    // frame. The "set" function should only called by GLRootView, and the
+    // "time" parameter must be nonnegative.
+    public void setCurrentAnimationTimeMillis(long time);
+    public long currentAnimationTimeMillis();
 
-    // We need 22 indices for a normal nine-patch image
-    private static final int INDEX_BUFFER_SIZE = 22;
+    // Sets the current drawing color used for drawLine and fillRect.
+    public void setColor(int color);
 
-    private static final float OPAQUE_ALPHA = 0.95f;
+    // Sets and gets the current alpha
+    public void setAlpha(float alpha);
+    public float getAlpha();
 
-    private final GL11 mGL;
+    // (current alpha) = (current alpha) * alpha
+    public void multiplyAlpha(float alpha);
 
-    private final float mMatrixValues[] = new float[16];
+    public void translate(float x, float y, float z);
+    public void scale(float sx, float sy, float sz);
+    public void rotate(float angle, float x, float y, float z);
 
-    private final float mUvBuffer[] = new float[VERTEX_BUFFER_SIZE];
-    private final float mXyBuffer[] = new float[VERTEX_BUFFER_SIZE];
-    private final byte mIndexBuffer[] = new byte[INDEX_BUFFER_SIZE];
+    // Modifies the current clip with the specified rectangle.
+    // (current clip) = (current clip) intersect (specified rectangle).
+    // Returns true if the result clip is non-empty.
+    public boolean clipRect(int x, int y, int width, int height);
 
-    private final int mNinePatchX[] = new int[4];
-    private final int mNinePatchY[] = new int[4];
-    private final float mNinePatchU[] = new float[4];
-    private final float mNinePatchV[] = new float[4];
-    private final float mTextureColor[] = new float[4];
+    // Pushes the configuration state (matrix, alpha, and clip) onto
+    // a private stack.
+    public int save();
 
-    private FloatBuffer mXyPointer;
-    private FloatBuffer mUvPointer;
-    private ByteBuffer mIndexPointer;
+    // Same as save(), but only save those specified in saveFlags.
+    public int save(int saveFlags);
 
-    private final GLState mGLState;
+    public static final int SAVE_FLAG_ALL = 0xFFFFFFFF;
+    public static final int SAVE_FLAG_CLIP = 0x01;
+    public static final int SAVE_FLAG_ALPHA = 0x02;
+    public static final int SAVE_FLAG_MATRIX = 0x04;
 
-    private long mAnimationTime;
+    // Pops from the top of the stack as current configuration state (matrix,
+    // alpha, and clip). This call balances a previous call to save(), and is
+    // used to remove all modifications to the configuration state since the
+    // last save call.
+    public void restore();
 
-    private float mAlpha;
-    private final Rect mClipRect = new Rect();
-    private final Stack<ConfigState> mRestoreStack =
-            new Stack<ConfigState>();
-    private ConfigState mRecycledRestoreAction;
+    // Draws a line using current drawing color from (x1, y1) to (x2, y2).
+    // (Both end points are included).
+    public void drawLine(int x1, int y1, int x2, int y2);
 
-    GLCanvas(GL11 gl) {
-        mGL = gl;
-        mGLState = new GLState(gl);
-        initialize();
-    }
+    // Fills the specified rectange with the current drawing color or
+    // the color of texture.
+    public void fillRect(int x, int y, int width, int height);
+    public void fillRect(Rect r);
 
-    public void setSize(int width, int height) {
-        GL11 gl = mGL;
-        gl.glViewport(0, 0, width, height);
-        gl.glMatrixMode(GL11.GL_PROJECTION);
-        gl.glLoadIdentity();
-        GLU.gluOrtho2D(gl, 0, width, 0, height);
+    // Sets the texture coordinates for fillRect calls.
+    public void setTextureCoords(RectF source);
 
-        gl.glMatrixMode(GL11.GL_MODELVIEW);
-        gl.glLoadIdentity();
-
-        // The positive direction in Y coordinate in OpenGL is from bottom to
-        // top, which is different from the coordinate system in Java. So, we
-        // flip it here.
-        float matrix[] = mMatrixValues;
-        Matrix.setIdentityM(matrix, 0);
-        Matrix.translateM(matrix, 0, 0, height, 0);
-        Matrix.scaleM(matrix, 0, 1, -1, 1);
-
-        mClipRect.set(0, 0, width, height);
-        gl.glScissor(0, 0, width, height);
-    }
-
-    public long currentAnimationTimeMillis() {
-        return mAnimationTime;
-    }
-
-    public void setAlpha(float alpha) {
-        mAlpha = alpha;
-    }
-
-    public void multiplyAlpha(float alpha) {
-        mAlpha *= alpha;
-    }
-
-    public float getAlpha() {
-        return mAlpha;
-    }
-
-    private static ByteBuffer allocateDirectNativeOrderBuffer(int size) {
-        return ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder());
-    }
-
-    private void initialize() {
-        int size = VERTEX_BUFFER_SIZE * Float.SIZE / Byte.SIZE;
-        mXyPointer = allocateDirectNativeOrderBuffer(size).asFloatBuffer();
-        mUvPointer = allocateDirectNativeOrderBuffer(size).asFloatBuffer();
-        mIndexPointer = allocateDirectNativeOrderBuffer(INDEX_BUFFER_SIZE);
-
-        GL11 gl = mGL;
-
-        gl.glVertexPointer(2, GL11.GL_FLOAT, 0, mXyPointer);
-        gl.glTexCoordPointer(2, GL11.GL_FLOAT, 0, mUvPointer);
-
-        // Enable the texture coordinate array for Texture 1
-        gl.glClientActiveTexture(GL11.GL_TEXTURE1);
-        gl.glTexCoordPointer(2, GL11.GL_FLOAT, 0, mUvPointer);
-        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
-
-        // mMatrixValues will be initialized in setSize()
-        mAlpha = 1.0f;
-    }
-
-    private static void putRectangle(float x, float y,
-            float width, float height, float[] buffer, FloatBuffer pointer) {
-        buffer[0] = x;
-        buffer[1] = y;
-        buffer[2] = x + width;
-        buffer[3] = y;
-        buffer[4] = x;
-        buffer[5] = y + height;
-        buffer[6] = x + width;
-        buffer[7] = y + height;
-        pointer.put(buffer, 0, 8).position(0);
-    }
-
-    public void setColor(int color) {
-        float alpha = mAlpha;
-        mGLState.setBlendEnabled(!Util.isOpaque(color) || alpha < OPAQUE_ALPHA);
-        mGLState.setFragmentColor(color, alpha);
-    }
-
-    public void drawLine(int x1, int y1, int x2, int y2) {
-        GL11 gl = mGL;
-        gl.glLoadMatrixf(mMatrixValues, 0);
-        float buffer[] = mXyBuffer;
-        buffer[0] = x1;
-        buffer[1] = y1;
-        buffer[2] = x2;
-        buffer[3] = y2;
-        mXyPointer.put(buffer, 0, 4).position(0);
-        gl.glDrawArrays(GL11.GL_LINE_STRIP, 0, 2);
-    }
-
-    public void fillRect(Rect r) {
-        fillRect(r.left, r.top, r.right - r.left, r.bottom - r.top);
-    }
-
-    public void translate(float x, float y, float z) {
-        Matrix.translateM(mMatrixValues, 0, x, y, z);
-    }
-
-    public void scale(float sx, float sy, float sz) {
-        Matrix.scaleM(mMatrixValues, 0, sx, sy, sz);
-    }
-
-    public void rotate(float angle, float x, float y, float z) {
-        Matrix.rotateM(mMatrixValues, 0, angle, x, y, z);
-    }
-
-    public void fillRect(int x, int y, int width, int height) {
-        GL11 gl = mGL;
-        gl.glLoadMatrixf(mMatrixValues, 0);
-        putRectangle(x, y, width, height, mXyBuffer, mXyPointer);
-        gl.glDrawArrays(GL11.GL_TRIANGLE_STRIP, 0, 4);
-    }
-
-    public void drawNinePatch(
-            NinePatchTexture tex, int x, int y, int width, int height) {
-        float alpha = mAlpha;
-        NinePatchChunk chunk = tex.getNinePatchChunk();
-
-        mGLState.setTexture2DEnabled(true);
-
-        // The code should be easily extended to handle the general cases by
-        // allocating more space for buffers. But let's just handle the only
-        // use case.
-        if (chunk.mDivX.length != 2 || chunk.mDivY.length != 2) {
-            throw new RuntimeException("unsupported nine patch");
-        }
-        tex.bind(this);
-        if (width <= 0 || height <= 0) return ;
-
-        int divX[] = mNinePatchX;
-        int divY[] = mNinePatchY;
-        float divU[] = mNinePatchU;
-        float divV[] = mNinePatchV;
-
-        int nx = stretch(divX, divU, chunk.mDivX, tex.getWidth(), width);
-        int ny = stretch(divY, divV, chunk.mDivY, tex.getHeight(), height);
-        mGLState.setBlendEnabled(!tex.isOpaque() || alpha < OPAQUE_ALPHA);
-
-        mGLState.setTextureAlpha(alpha);
-
-        GL11 gl = mGL;
-        gl.glLoadMatrixf(mMatrixValues, 0);
-        gl.glTranslatef(x, y, 0);
-        drawMesh(divX, divY, divU, divV, nx, ny);
-    }
-
-    /**
-     * Stretches the texture according to the nine-patch rules. It will
-     * linearly distribute the strechy parts defined in the nine-patch chunk to
-     * the target area.
-     *
-     * <pre>
-     *                      source
-     *          /--------------^---------------\
-     *         u0    u1       u2  u3     u4   u5
-     * div ---> |fffff|ssssssss|fff|ssssss|ffff| ---> u
-     *          |    div0    div1 div2   div3  |
-     *          |     |       /   /      /    /
-     *          |     |      /   /     /    /
-     *          |     |     /   /    /    /
-     *          |fffff|ssss|fff|sss|ffff| ---> x
-     *         x0    x1   x2  x3  x4   x5
-     *          \----------v------------/
-     *                  target
-     *
-     * f: fixed segment
-     * s: stretchy segment
-     * </pre>
-     *
-     * @param div the stretch parts defined in nine-patch chunk
-     * @param source the length of the texture
-     * @param target the length on the drawing plan
-     * @param u output, the positions of these dividers in the texture
-     *        coordinate
-     * @param x output, the corresponding position of these dividers on the
-     *        drawing plan
-     * @return the number of these dividers.
-     */
-    private int stretch(
-            int x[], float u[], int div[], int source, int target) {
-        int textureSize = Util.nextPowerOf2(source);
-        float textureBound = (source - 0.5f) / textureSize;
-
-        int stretch = 0;
-        for (int i = 0, n = div.length; i < n; i += 2) {
-            stretch += div[i + 1] - div[i];
-        }
-
-        float remaining = target - source + stretch;
-
-        int lastX = 0;
-        int lastU = 0;
-
-        x[0] = 0;
-        u[0] = 0;
-        for (int i = 0, n = div.length; i < n; i += 2) {
-            // fixed segment
-            x[i + 1] = lastX + (div[i] - lastU);
-            u[i + 1] = Math.min((float) div[i] / textureSize, textureBound);
-
-            // stretchy segment
-            float partU = div[i + 1] - div[i];
-            int partX = (int)(remaining * partU / stretch + 0.5f);
-            remaining -= partX;
-            stretch -= partU;
-
-            lastX = x[i + 1] + partX;
-            lastU = div[i + 1];
-            x[i + 2] = lastX;
-            u[i + 2] = Math.min((float) lastU / textureSize, textureBound);
-        }
-        // the last fixed segment
-        x[div.length + 1] = target;
-        u[div.length + 1] = textureBound;
-
-        // remove segments with length 0.
-        int last = 0;
-        for (int i = 1, n = div.length + 2; i < n; ++i) {
-            if (x[last] == x[i]) continue;
-            x[++last] = x[i];
-            u[last] = u[i];
-        }
-        return last + 1;
-    }
-
-    private void drawMesh(
-            int x[], int y[], float u[], float v[], int nx, int ny) {
-        /*
-         * Given a 3x3 nine-patch image, the vertex order is defined as the
-         * following graph:
-         *
-         * (0) (1) (2) (3)
-         *  |  /|  /|  /|
-         *  | / | / | / |
-         * (4) (5) (6) (7)
-         *  | \ | \ | \ |
-         *  |  \|  \|  \|
-         * (8) (9) (A) (B)
-         *  |  /|  /|  /|
-         *  | / | / | / |
-         * (C) (D) (E) (F)
-         *
-         * And we draw the triangle strip in the following index order:
-         *
-         * index: 04152637B6A5948C9DAEBF
-         */
-        int pntCount = 0;
-        float xy[] = mXyBuffer;
-        float uv[] = mUvBuffer;
-        for (int j = 0; j < ny; ++j) {
-            for (int i = 0; i < nx; ++i) {
-                int xIndex = (pntCount++) << 1;
-                int yIndex = xIndex + 1;
-                xy[xIndex] = x[i];
-                xy[yIndex] = y[j];
-                uv[xIndex] = u[i];
-                uv[yIndex] = v[j];
-            }
-        }
-        mUvPointer.put(uv, 0, pntCount << 1).position(0);
-        mXyPointer.put(xy, 0, pntCount << 1).position(0);
-
-        int idxCount = 1;
-        byte index[] = mIndexBuffer;
-        for (int i = 0, bound = nx * (ny - 1); true;) {
-            // normal direction
-            --idxCount;
-            for (int j = 0; j < nx; ++j, ++i) {
-                index[idxCount++] = (byte) i;
-                index[idxCount++] = (byte) (i + nx);
-            }
-            if (i >= bound) break;
-
-            // reverse direction
-            int sum = i + i + nx - 1;
-            --idxCount;
-            for (int j = 0; j < nx; ++j, ++i) {
-                index[idxCount++] = (byte) (sum - i);
-                index[idxCount++] = (byte) (sum - i + nx);
-            }
-            if (i >= bound) break;
-        }
-        mIndexPointer.put(index, 0, idxCount).position(0);
-
-        mGL.glDrawElements(GL11.GL_TRIANGLE_STRIP,
-                idxCount, GL11.GL_UNSIGNED_BYTE, mIndexPointer);
-    }
-
-    private float[] mapPoints(float matrix[], int x1, int y1, int x2, int y2) {
-        float[] point = mXyBuffer;
-        int srcOffset = 6;
-        point[srcOffset] = x1;
-        point[srcOffset + 1] = y1;
-        point[srcOffset + 2] = 0;
-        point[srcOffset + 3] = 1;
-
-        int resultOffset = 0;
-        Matrix.multiplyMV(point, resultOffset, matrix, 0, point, srcOffset);
-        point[resultOffset] /= point[resultOffset + 3];
-        point[resultOffset + 1] /= point[resultOffset + 3];
-
-        // map the second point
-        point[srcOffset] = x2;
-        point[srcOffset + 1] = y2;
-        resultOffset = 2;
-        Matrix.multiplyMV(point, resultOffset, matrix, 0, point, srcOffset);
-        point[resultOffset] /= point[resultOffset + 3];
-        point[resultOffset + 1] /= point[resultOffset + 3];
-
-        return point;
-    }
-
-
-    public boolean clipRect(int left, int top, int right, int bottom) {
-        float point[] = mapPoints(mMatrixValues, left, top, right, bottom);
-
-        // mMatrix could be a rotation matrix. In this case, we need to find
-        // the boundaries after rotation. (only handle 90 * n degrees)
-        if (point[0] > point[2]) {
-            left = (int) point[2];
-            right = (int) point[0];
-        } else {
-            left = (int) point[0];
-            right = (int) point[2];
-        }
-        if (point[1] > point[3]) {
-            top = (int) point[3];
-            bottom = (int) point[1];
-        } else {
-            top = (int) point[1];
-            bottom = (int) point[3];
-        }
-        Rect clip = mClipRect;
-
-        boolean intersect = clip.intersect(left, top, right, bottom);
-        if (!intersect) clip.set(0, 0, 0, 0);
-        mGL.glScissor(clip.left, clip.top, clip.width(), clip.height());
-        return intersect;
-    }
-
-    public void drawColor(int x, int y, int width, int height, int color) {
-        float alpha = mAlpha;
-        mGLState.setBlendEnabled(!Util.isOpaque(color) || alpha < OPAQUE_ALPHA);
-        mGLState.setFragmentColor(color, alpha);
-        fillRect(x, y, width, height);
-    }
-
-    private void drawBoundTexture(
-            BasicTexture texture, int x, int y, int width, int height) {
-        // Test whether it has been rotated or flipped, if so, glDrawTexiOES
-        // won't work
-        if (isMatrixRotatedOrFlipped(mMatrixValues)) {
-            putRectangle(0, 0,
-                    (texture.mWidth - 0.5f) / texture.mTextureWidth,
-                    (texture.mHeight - 0.5f) / texture.mTextureHeight,
-                    mUvBuffer, mUvPointer);
-            fillRect(x, y, width, height);
-        } else {
-            // draw the rect from bottom-left to top-right
-            float points[] = mapPoints(
-                    mMatrixValues, x, y + height, x + width, y);
-            x = (int) points[0];
-            y = (int) points[1];
-            width = (int) points[2] - x;
-            height = (int) points[3] - y;
-            if (width > 0 && height > 0) {
-                ((GL11Ext) mGL).glDrawTexiOES(x, y, 0, width, height);
-            }
-        }
-
-    }
-
+    // Draws a texture to the specified rectangle.
     public void drawTexture(
-            BasicTexture texture, int x, int y, int width, int height) {
-        drawTexture(texture, x, y, width, height, mAlpha);
-    }
+            BasicTexture texture, int x, int y, int width, int height);
+    public void drawNinePatch(
+            NinePatchTexture tex, int x, int y, int width, int height);
 
+    // Draws a texture to the specified rectangle. The "alpha" parameter
+    // overrides the current drawing alpha value.
     public void drawTexture(BasicTexture texture,
-            int x, int y, int width, int height, float alpha) {
-        if (width <= 0 || height <= 0) return ;
+            int x, int y, int width, int height, float alpha);
 
-        mGLState.setBlendEnabled(!texture.isOpaque() || alpha < OPAQUE_ALPHA);
-        mGLState.setTexture2DEnabled(true);
-        texture.bind(this);
-        mGLState.setTextureAlpha(alpha);
-        drawBoundTexture(texture, x, y, width, height);
-    }
+    // Draw two textures to the specified rectange. The actual texture used is
+    // from * (1 - ratio) + to * ratio
+    public void drawMixed(BasicTexture from, BasicTexture to,
+            float ratio, int x, int y, int w, int h);
 
     public void drawMixed(BasicTexture from, BasicTexture to,
-            float ratio, int x, int y, int w, int h) {
-        drawMixed(from, to, ratio, x, y, w, h, mAlpha);
-    }
+            float ratio, int x, int y, int width, int height, float alpha);
 
-    private void setTextureColor(float r, float g, float b, float alpha) {
-        float[] color = mTextureColor;
-        color[0] = r;
-        color[1] = g;
-        color[2] = b;
-        color[3] = alpha;
-    }
-
-    public void handleLowMemory() {
-    }
-
-    public void drawMixed(BasicTexture from, BasicTexture to,
-            float ratio, int x, int y, int width, int height, float alpha) {
-        if (alpha < OPAQUE_ALPHA) {
-            throw new RuntimeException("Cannot support alpha value");
-        }
-        mGLState.setBlendEnabled(!from.isOpaque() || !to.isOpaque());
-        mGLState.setTextureAlpha(1);
-        mGLState.setTexture2DEnabled(true);
-
-        final GL11 gl = mGL;
-        from.bind(this);
-
-        gl.glActiveTexture(GL11.GL_TEXTURE1);
-        to.bind(this);
-        gl.glEnable(GL11.GL_TEXTURE_2D);
-
-        // Interpolate the RGB and alpha values between both textures.
-        mGLState.setTexEnvMode(GL11.GL_COMBINE);
-        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_COMBINE_RGB, GL11.GL_INTERPOLATE);
-        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.
-        setTextureColor(ratio, ratio, ratio, ratio);
-        gl.glTexEnvfv(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_COLOR, mTextureColor, 0);
-
-        // Wire up the interpolation factor for RGB.
-        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC2_RGB, GL11.GL_CONSTANT);
-        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND2_RGB, GL11.GL_SRC_ALPHA);
-
-        // Wire up the interpolation factor for alpha.
-        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC2_ALPHA, GL11.GL_CONSTANT);
-        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND2_ALPHA, GL11.GL_SRC_ALPHA);
-
-        // Draw the combined texture.
-        drawBoundTexture(to, x, y, width, height);
-
-        // Disable TEXTURE1.
-        gl.glDisable(GL11.GL_TEXTURE_2D);
-        // Switch back to the default texture unit.
-        gl.glActiveTexture(GL11.GL_TEXTURE0);
-    }
-
-    // TODO: the code only work for 2D should get fixed for 3D or removed
-    private static final int MSKEW_X = 4;
-    private static final int MSKEW_Y = 1;
-    private static final int MSCALE_X = 0;
-    private static final int MSCALE_Y = 5;
-
-    private static boolean isMatrixRotatedOrFlipped(float matrix[]) {
-        return matrix[MSKEW_X] != 0 || matrix[MSKEW_Y] != 0
-                || matrix[MSCALE_X] < 0 || matrix[MSCALE_Y] > 0;
-    }
-
+    // Copies the specified rectangle to the RawTexture.
     public void copyTexture2D(
-            RawTexture texture, int x, int y, int width, int height) {
+            RawTexture texture, int x, int y, int width, int height);
 
-        if (isMatrixRotatedOrFlipped(mMatrixValues)) {
-            throw new IllegalArgumentException("cannot support rotated matrix");
-        }
-        float points[] = mapPoints(mMatrixValues, x, y + height, x + width, y);
-        x = (int) points[0];
-        y = (int) points[1];
-        width = (int) points[2] - x;
-        height = (int) points[3] - y;
+    // TODO: Remove this or document it.
+    public void releaseTextures(Collection<? extends BasicTexture> c);
 
-        GL11 gl = mGL;
-        int newWidth = Util.nextPowerOf2(width);
-        int newHeight = Util.nextPowerOf2(height);
-        int glError = GL11.GL_NO_ERROR;
-
-        gl.glBindTexture(GL11.GL_TEXTURE_2D, texture.getId());
-
-        int[] cropRect = {0,  0, width, height};
-        gl.glTexParameteriv(GL11.GL_TEXTURE_2D,
-                GL11Ext.GL_TEXTURE_CROP_RECT_OES, cropRect, 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.glCopyTexImage2D(GL11.GL_TEXTURE_2D, 0,
-                GL11.GL_RGBA, x, y, newWidth, newHeight, 0);
-        glError = gl.glGetError();
-
-        if (glError == GL11.GL_OUT_OF_MEMORY) {
-            throw new GLOutOfMemoryException();
-        }
-
-        if (glError != GL11.GL_NO_ERROR) {
-            throw new RuntimeException(
-                    "Texture copy fail, glError " + glError);
-        }
-
-        texture.setSize(width, height);
-        texture.setTextureSize(newWidth, newHeight);
-    }
-
-    private static class GLState {
-
-        private final GL11 mGL;
-
-        private int mTexEnvMode = GL11.GL_REPLACE;
-        private float mTextureAlpha = 1.0f;
-        private boolean mTexture2DEnabled = true;
-        private boolean mBlendEnabled = true;
-
-        public GLState(GL11 gl) {
-            mGL = gl;
-
-            // Disable unused state
-            gl.glDisable(GL11.GL_LIGHTING);
-
-            // Enable used features
-            gl.glEnable(GL11.GL_DITHER);
-
-            gl.glEnable(GL11.GL_SCISSOR_TEST);
-            gl.glEnable(GL11.GL_STENCIL_TEST);
-
-            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
-            gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
-            gl.glEnable(GL11.GL_TEXTURE_2D);
-
-            gl.glTexEnvf(GL11.GL_TEXTURE_ENV,
-                    GL11.GL_TEXTURE_ENV_MODE, GL11.GL_REPLACE);
-
-            // Set the background color
-            gl.glClearColor(0f, 0f, 0f, 0f);
-            gl.glClearStencil(0);
-
-            gl.glEnable(GL11.GL_BLEND);
-            gl.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
-        }
-
-        public void setTexEnvMode(int mode) {
-            if (mTexEnvMode == mode) return;
-            mTexEnvMode = mode;
-            mGL.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, mode);
-        }
-
-        public void setTextureAlpha(float alpha) {
-            if (mTextureAlpha == alpha) return;
-            mTextureAlpha = alpha;
-            if (alpha >= OPAQUE_ALPHA) {
-                // The alpha is need for those texture without alpha channel
-                mGL.glColor4f(1, 1, 1, 1);
-                setTexEnvMode(GL11.GL_REPLACE);
-            } else {
-                mGL.glColor4f(alpha, alpha, alpha, alpha);
-                setTexEnvMode(GL11.GL_MODULATE);
-            }
-        }
-
-        public void setFragmentColor(int color, float alpha) {
-            // Set mTextureAlpha to an invalid value, so that it will reset
-            // again in setTextureAlpha(float) later.
-            mTextureAlpha = -1.0f;
-
-            setTexture2DEnabled(false);
-            int prealpha = (int) ((color >>> 24) * alpha + 0.5);
-            mGL.glColor4x(
-                    ((color >> 16) & 0xFF) * prealpha,
-                    ((color >> 8) & 0xFF) * prealpha,
-                    (color & 0xFF) * prealpha, prealpha << 8);
-        }
-
-        public void setTexture2DEnabled(boolean enabled) {
-            if (mTexture2DEnabled == enabled) return;
-            mTexture2DEnabled = enabled;
-            if (enabled) {
-                mGL.glEnable(GL11.GL_TEXTURE_2D);
-            } else {
-                mGL.glDisable(GL11.GL_TEXTURE_2D);
-            }
-        }
-
-        public void setBlendEnabled(boolean enabled) {
-            if (mBlendEnabled == enabled) return;
-            mBlendEnabled = enabled;
-            if (enabled) {
-                mGL.glEnable(GL11.GL_BLEND);
-            } else {
-                mGL.glDisable(GL11.GL_BLEND);
-            }
-        }
-    }
-
-    public GL11 getGLInstance() {
-        return mGL;
-    }
-
-    protected void setCurrentTimeMillis(long time) {
-        mAnimationTime = time;
-    }
-
-    public void clearBuffer() {
-        mGL.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_STENCIL_BUFFER_BIT);
-    }
-
-    public void setTextureCoords(RectF source) {
-        float buffer[] = mUvBuffer;
-        buffer[0] = source.left;
-        buffer[1] = source.top;
-        buffer[2] = source.right;
-        buffer[3] = source.top;
-        buffer[4] = source.left;
-        buffer[5] = source.bottom;
-        buffer[6] = source.right;
-        buffer[7] = source.bottom;
-        mUvPointer.put(buffer, 0, 8).position(0);
-    }
-
-    public void releaseTextures(Collection<? extends BasicTexture> c) {
-        IntArray array = new IntArray();
-        for (BasicTexture t : c) {
-            if (t.isLoaded(this)) array.add(t.mId);
-        }
-        if (array.size() > 0) {
-            mGL.glDeleteTextures(array.size(), array.toArray(null), 0);
-        }
-    }
-
-    public int save() {
-        return save(ALL_SAVE_FLAG);
-    }
-
-    public int save(int saveFlags) {
-        ConfigState config = obtainRestoreConfig();
-
-        if ((saveFlags & ALPHA_SAVE_FLAG) != 0) {
-            config.mAlpha = mAlpha;
-        } else {
-            config.mAlpha = -1;
-        }
-
-        if ((saveFlags & CLIP_SAVE_FLAG) != 0) {
-            config.mRect.set(mClipRect);
-        } else {
-            config.mRect.left = Integer.MAX_VALUE;
-        }
-
-        if ((saveFlags & MATRIX_SAVE_FLAG) != 0) {
-            System.arraycopy(mMatrixValues, 0, config.mMatrix, 0, 16);
-        } else {
-            config.mMatrix[0] = Float.NEGATIVE_INFINITY;
-        }
-
-        mRestoreStack.push(config);
-        return mRestoreStack.size() - 1;
-    }
-
-    public void restore() {
-        if (mRestoreStack.isEmpty()) throw new IllegalStateException();
-        ConfigState config = mRestoreStack.pop();
-        config.restore(this);
-        freeRestoreConfig(config);
-    }
-
-    public void restoreToCount(int saveCount) {
-        while (mRestoreStack.size() > saveCount) {
-            restore();
-        }
-    }
-
-    private void freeRestoreConfig(ConfigState action) {
-        action.mNextFree = mRecycledRestoreAction;
-        mRecycledRestoreAction = action;
-    }
-
-    private ConfigState obtainRestoreConfig() {
-        if (mRecycledRestoreAction != null) {
-            ConfigState result = mRecycledRestoreAction;
-            mRecycledRestoreAction = result.mNextFree;
-            return result;
-        }
-        return new ConfigState();
-    }
-
-    private static class ConfigState {
-        float mAlpha;
-        Rect mRect = new Rect();
-        float mMatrix[] = new float[16];
-        ConfigState mNextFree;
-
-        public void restore(GLCanvas canvas) {
-            if (mAlpha >= 0) canvas.setAlpha(mAlpha);
-            if (mRect.left != Integer.MAX_VALUE) {
-                Rect rect = mRect;
-                canvas.mClipRect.set(rect);
-                canvas.mGL.glScissor(
-                        rect.left, rect.top, rect.width(), rect.height());
-            }
-            if (mMatrix[0] != Float.NEGATIVE_INFINITY) {
-                System.arraycopy(mMatrix, 0, canvas.mMatrixValues, 0, 16);
-            }
-        }
-    }
+    // Gets the underlying GL instance. This is used when
+    public GL11 getGLInstance();
 }
diff --git a/new3d/src/com/android/gallery3d/ui/GLCanvasImp.java b/new3d/src/com/android/gallery3d/ui/GLCanvasImp.java
new file mode 100644
index 0000000..33796f1
--- /dev/null
+++ b/new3d/src/com/android/gallery3d/ui/GLCanvasImp.java
@@ -0,0 +1,770 @@
+package com.android.gallery3d.ui;
+
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.opengl.GLU;
+import android.opengl.Matrix;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.util.Collection;
+import java.util.Stack;
+
+import javax.microedition.khronos.opengles.GL10;
+import javax.microedition.khronos.opengles.GL11;
+import javax.microedition.khronos.opengles.GL11Ext;
+
+public class GLCanvasImp implements GLCanvas {
+
+    // We need 16 vertices for a normal nine-patch image (the 4x4 vertices)
+    private static final int VERTEX_BUFFER_SIZE = 16 * 2;
+
+    // We need 22 indices for a normal nine-patch image
+    private static final int INDEX_BUFFER_SIZE = 22;
+
+    private static final float OPAQUE_ALPHA = 0.95f;
+
+    private final GL11 mGL;
+
+    private final float mMatrixValues[] = new float[16];
+
+    private final float mUvBuffer[] = new float[VERTEX_BUFFER_SIZE];
+    private final float mXyBuffer[] = new float[VERTEX_BUFFER_SIZE];
+    private final byte mIndexBuffer[] = new byte[INDEX_BUFFER_SIZE];
+
+    private final int mNinePatchX[] = new int[4];
+    private final int mNinePatchY[] = new int[4];
+    private final float mNinePatchU[] = new float[4];
+    private final float mNinePatchV[] = new float[4];
+    private final float mTextureColor[] = new float[4];
+
+    private FloatBuffer mXyPointer;
+    private FloatBuffer mUvPointer;
+    private ByteBuffer mIndexPointer;
+
+    private final GLState mGLState;
+
+    private long mAnimationTime;
+
+    private float mAlpha;
+    private final Rect mClipRect = new Rect();
+    private final Stack<ConfigState> mRestoreStack =
+            new Stack<ConfigState>();
+    private ConfigState mRecycledRestoreAction;
+
+    GLCanvasImp(GL11 gl) {
+        mGL = gl;
+        mGLState = new GLState(gl);
+        initialize();
+    }
+
+    public void setSize(int width, int height) {
+        GL11 gl = mGL;
+        gl.glViewport(0, 0, width, height);
+        gl.glMatrixMode(GL11.GL_PROJECTION);
+        gl.glLoadIdentity();
+        GLU.gluOrtho2D(gl, 0, width, 0, height);
+
+        gl.glMatrixMode(GL11.GL_MODELVIEW);
+        gl.glLoadIdentity();
+
+        // The positive direction in Y coordinate in OpenGL is from bottom to
+        // top, which is different from the coordinate system in Java. So, we
+        // flip it here.
+        float matrix[] = mMatrixValues;
+        Matrix.setIdentityM(matrix, 0);
+        Matrix.translateM(matrix, 0, 0, height, 0);
+        Matrix.scaleM(matrix, 0, 1, -1, 1);
+
+        mClipRect.set(0, 0, width, height);
+        gl.glScissor(0, 0, width, height);
+    }
+
+    public long currentAnimationTimeMillis() {
+        return mAnimationTime;
+    }
+
+    public void setAlpha(float alpha) {
+        mAlpha = alpha;
+    }
+
+    public void multiplyAlpha(float alpha) {
+        mAlpha *= alpha;
+    }
+
+    public float getAlpha() {
+        return mAlpha;
+    }
+
+    private static ByteBuffer allocateDirectNativeOrderBuffer(int size) {
+        return ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder());
+    }
+
+    private void initialize() {
+        int size = VERTEX_BUFFER_SIZE * Float.SIZE / Byte.SIZE;
+        mXyPointer = allocateDirectNativeOrderBuffer(size).asFloatBuffer();
+        mUvPointer = allocateDirectNativeOrderBuffer(size).asFloatBuffer();
+        mIndexPointer = allocateDirectNativeOrderBuffer(INDEX_BUFFER_SIZE);
+
+        GL11 gl = mGL;
+
+        gl.glVertexPointer(2, GL11.GL_FLOAT, 0, mXyPointer);
+        gl.glTexCoordPointer(2, GL11.GL_FLOAT, 0, mUvPointer);
+
+        // Enable the texture coordinate array for Texture 1
+        gl.glClientActiveTexture(GL11.GL_TEXTURE1);
+        gl.glTexCoordPointer(2, GL11.GL_FLOAT, 0, mUvPointer);
+        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
+
+        // mMatrixValues will be initialized in setSize()
+        mAlpha = 1.0f;
+    }
+
+    private static void putRectangle(float x, float y,
+            float width, float height, float[] buffer, FloatBuffer pointer) {
+        buffer[0] = x;
+        buffer[1] = y;
+        buffer[2] = x + width;
+        buffer[3] = y;
+        buffer[4] = x;
+        buffer[5] = y + height;
+        buffer[6] = x + width;
+        buffer[7] = y + height;
+        pointer.put(buffer, 0, 8).position(0);
+    }
+
+    public void setColor(int color) {
+        float alpha = mAlpha;
+        mGLState.setBlendEnabled(!Util.isOpaque(color) || alpha < OPAQUE_ALPHA);
+        mGLState.setFragmentColor(color, alpha);
+    }
+
+    public void drawLine(int x1, int y1, int x2, int y2) {
+        GL11 gl = mGL;
+        gl.glLoadMatrixf(mMatrixValues, 0);
+        float buffer[] = mXyBuffer;
+        buffer[0] = x1;
+        buffer[1] = y1;
+        buffer[2] = x2;
+        buffer[3] = y2;
+        mXyPointer.put(buffer, 0, 4).position(0);
+        gl.glDrawArrays(GL11.GL_LINE_STRIP, 0, 2);
+    }
+
+    public void fillRect(Rect r) {
+        fillRect(r.left, r.top, r.right - r.left, r.bottom - r.top);
+    }
+
+    public void translate(float x, float y, float z) {
+        Matrix.translateM(mMatrixValues, 0, x, y, z);
+    }
+
+    public void scale(float sx, float sy, float sz) {
+        Matrix.scaleM(mMatrixValues, 0, sx, sy, sz);
+    }
+
+    public void rotate(float angle, float x, float y, float z) {
+        Matrix.rotateM(mMatrixValues, 0, angle, x, y, z);
+    }
+
+    public void fillRect(int x, int y, int width, int height) {
+        GL11 gl = mGL;
+        gl.glLoadMatrixf(mMatrixValues, 0);
+        putRectangle(x, y, width, height, mXyBuffer, mXyPointer);
+        gl.glDrawArrays(GL11.GL_TRIANGLE_STRIP, 0, 4);
+    }
+
+    public void drawNinePatch(
+            NinePatchTexture tex, int x, int y, int width, int height) {
+        float alpha = mAlpha;
+        NinePatchChunk chunk = tex.getNinePatchChunk();
+
+        mGLState.setTexture2DEnabled(true);
+
+        // The code should be easily extended to handle the general cases by
+        // allocating more space for buffers. But let's just handle the only
+        // use case.
+        if (chunk.mDivX.length != 2 || chunk.mDivY.length != 2) {
+            throw new RuntimeException("unsupported nine patch");
+        }
+        tex.bind(this);
+        if (width <= 0 || height <= 0) return ;
+
+        int divX[] = mNinePatchX;
+        int divY[] = mNinePatchY;
+        float divU[] = mNinePatchU;
+        float divV[] = mNinePatchV;
+
+        int nx = stretch(divX, divU, chunk.mDivX, tex.getWidth(), width);
+        int ny = stretch(divY, divV, chunk.mDivY, tex.getHeight(), height);
+        mGLState.setBlendEnabled(!tex.isOpaque() || alpha < OPAQUE_ALPHA);
+
+        mGLState.setTextureAlpha(alpha);
+
+        GL11 gl = mGL;
+        gl.glLoadMatrixf(mMatrixValues, 0);
+        gl.glTranslatef(x, y, 0);
+        drawMesh(divX, divY, divU, divV, nx, ny);
+    }
+
+    /**
+     * Stretches the texture according to the nine-patch rules. It will
+     * linearly distribute the strechy parts defined in the nine-patch chunk to
+     * the target area.
+     *
+     * <pre>
+     *                      source
+     *          /--------------^---------------\
+     *         u0    u1       u2  u3     u4   u5
+     * div ---> |fffff|ssssssss|fff|ssssss|ffff| ---> u
+     *          |    div0    div1 div2   div3  |
+     *          |     |       /   /      /    /
+     *          |     |      /   /     /    /
+     *          |     |     /   /    /    /
+     *          |fffff|ssss|fff|sss|ffff| ---> x
+     *         x0    x1   x2  x3  x4   x5
+     *          \----------v------------/
+     *                  target
+     *
+     * f: fixed segment
+     * s: stretchy segment
+     * </pre>
+     *
+     * @param div the stretch parts defined in nine-patch chunk
+     * @param source the length of the texture
+     * @param target the length on the drawing plan
+     * @param u output, the positions of these dividers in the texture
+     *        coordinate
+     * @param x output, the corresponding position of these dividers on the
+     *        drawing plan
+     * @return the number of these dividers.
+     */
+    private int stretch(
+            int x[], float u[], int div[], int source, int target) {
+        int textureSize = Util.nextPowerOf2(source);
+        float textureBound = (source - 0.5f) / textureSize;
+
+        int stretch = 0;
+        for (int i = 0, n = div.length; i < n; i += 2) {
+            stretch += div[i + 1] - div[i];
+        }
+
+        float remaining = target - source + stretch;
+
+        int lastX = 0;
+        int lastU = 0;
+
+        x[0] = 0;
+        u[0] = 0;
+        for (int i = 0, n = div.length; i < n; i += 2) {
+            // fixed segment
+            x[i + 1] = lastX + (div[i] - lastU);
+            u[i + 1] = Math.min((float) div[i] / textureSize, textureBound);
+
+            // stretchy segment
+            float partU = div[i + 1] - div[i];
+            int partX = (int)(remaining * partU / stretch + 0.5f);
+            remaining -= partX;
+            stretch -= partU;
+
+            lastX = x[i + 1] + partX;
+            lastU = div[i + 1];
+            x[i + 2] = lastX;
+            u[i + 2] = Math.min((float) lastU / textureSize, textureBound);
+        }
+        // the last fixed segment
+        x[div.length + 1] = target;
+        u[div.length + 1] = textureBound;
+
+        // remove segments with length 0.
+        int last = 0;
+        for (int i = 1, n = div.length + 2; i < n; ++i) {
+            if (x[last] == x[i]) continue;
+            x[++last] = x[i];
+            u[last] = u[i];
+        }
+        return last + 1;
+    }
+
+    private void drawMesh(
+            int x[], int y[], float u[], float v[], int nx, int ny) {
+        /*
+         * Given a 3x3 nine-patch image, the vertex order is defined as the
+         * following graph:
+         *
+         * (0) (1) (2) (3)
+         *  |  /|  /|  /|
+         *  | / | / | / |
+         * (4) (5) (6) (7)
+         *  | \ | \ | \ |
+         *  |  \|  \|  \|
+         * (8) (9) (A) (B)
+         *  |  /|  /|  /|
+         *  | / | / | / |
+         * (C) (D) (E) (F)
+         *
+         * And we draw the triangle strip in the following index order:
+         *
+         * index: 04152637B6A5948C9DAEBF
+         */
+        int pntCount = 0;
+        float xy[] = mXyBuffer;
+        float uv[] = mUvBuffer;
+        for (int j = 0; j < ny; ++j) {
+            for (int i = 0; i < nx; ++i) {
+                int xIndex = (pntCount++) << 1;
+                int yIndex = xIndex + 1;
+                xy[xIndex] = x[i];
+                xy[yIndex] = y[j];
+                uv[xIndex] = u[i];
+                uv[yIndex] = v[j];
+            }
+        }
+        mUvPointer.put(uv, 0, pntCount << 1).position(0);
+        mXyPointer.put(xy, 0, pntCount << 1).position(0);
+
+        int idxCount = 1;
+        byte index[] = mIndexBuffer;
+        for (int i = 0, bound = nx * (ny - 1); true;) {
+            // normal direction
+            --idxCount;
+            for (int j = 0; j < nx; ++j, ++i) {
+                index[idxCount++] = (byte) i;
+                index[idxCount++] = (byte) (i + nx);
+            }
+            if (i >= bound) break;
+
+            // reverse direction
+            int sum = i + i + nx - 1;
+            --idxCount;
+            for (int j = 0; j < nx; ++j, ++i) {
+                index[idxCount++] = (byte) (sum - i);
+                index[idxCount++] = (byte) (sum - i + nx);
+            }
+            if (i >= bound) break;
+        }
+        mIndexPointer.put(index, 0, idxCount).position(0);
+
+        mGL.glDrawElements(GL11.GL_TRIANGLE_STRIP,
+                idxCount, GL11.GL_UNSIGNED_BYTE, mIndexPointer);
+    }
+
+    private float[] mapPoints(float matrix[], int x1, int y1, int x2, int y2) {
+        float[] point = mXyBuffer;
+        int srcOffset = 6;
+        point[srcOffset] = x1;
+        point[srcOffset + 1] = y1;
+        point[srcOffset + 2] = 0;
+        point[srcOffset + 3] = 1;
+
+        int resultOffset = 0;
+        Matrix.multiplyMV(point, resultOffset, matrix, 0, point, srcOffset);
+        point[resultOffset] /= point[resultOffset + 3];
+        point[resultOffset + 1] /= point[resultOffset + 3];
+
+        // map the second point
+        point[srcOffset] = x2;
+        point[srcOffset + 1] = y2;
+        resultOffset = 2;
+        Matrix.multiplyMV(point, resultOffset, matrix, 0, point, srcOffset);
+        point[resultOffset] /= point[resultOffset + 3];
+        point[resultOffset + 1] /= point[resultOffset + 3];
+
+        return point;
+    }
+
+
+    public boolean clipRect(int left, int top, int right, int bottom) {
+        float point[] = mapPoints(mMatrixValues, left, top, right, bottom);
+
+        // mMatrix could be a rotation matrix. In this case, we need to find
+        // the boundaries after rotation. (only handle 90 * n degrees)
+        if (point[0] > point[2]) {
+            left = (int) point[2];
+            right = (int) point[0];
+        } else {
+            left = (int) point[0];
+            right = (int) point[2];
+        }
+        if (point[1] > point[3]) {
+            top = (int) point[3];
+            bottom = (int) point[1];
+        } else {
+            top = (int) point[1];
+            bottom = (int) point[3];
+        }
+        Rect clip = mClipRect;
+
+        boolean intersect = clip.intersect(left, top, right, bottom);
+        if (!intersect) clip.set(0, 0, 0, 0);
+        mGL.glScissor(clip.left, clip.top, clip.width(), clip.height());
+        return intersect;
+    }
+
+    public void drawColor(int x, int y, int width, int height, int color) {
+        float alpha = mAlpha;
+        mGLState.setBlendEnabled(!Util.isOpaque(color) || alpha < OPAQUE_ALPHA);
+        mGLState.setFragmentColor(color, alpha);
+        fillRect(x, y, width, height);
+    }
+
+    private void drawBoundTexture(
+            BasicTexture texture, int x, int y, int width, int height) {
+        // Test whether it has been rotated or flipped, if so, glDrawTexiOES
+        // won't work
+        if (isMatrixRotatedOrFlipped(mMatrixValues)) {
+            putRectangle(0, 0,
+                    (texture.mWidth - 0.5f) / texture.mTextureWidth,
+                    (texture.mHeight - 0.5f) / texture.mTextureHeight,
+                    mUvBuffer, mUvPointer);
+            fillRect(x, y, width, height);
+        } else {
+            // draw the rect from bottom-left to top-right
+            float points[] = mapPoints(
+                    mMatrixValues, x, y + height, x + width, y);
+            x = (int) points[0];
+            y = (int) points[1];
+            width = (int) points[2] - x;
+            height = (int) points[3] - y;
+            if (width > 0 && height > 0) {
+                ((GL11Ext) mGL).glDrawTexiOES(x, y, 0, width, height);
+            }
+        }
+
+    }
+
+    public void drawTexture(
+            BasicTexture texture, int x, int y, int width, int height) {
+        drawTexture(texture, x, y, width, height, mAlpha);
+    }
+
+    public void drawTexture(BasicTexture texture,
+            int x, int y, int width, int height, float alpha) {
+        if (width <= 0 || height <= 0) return ;
+
+        mGLState.setBlendEnabled(!texture.isOpaque() || alpha < OPAQUE_ALPHA);
+        mGLState.setTexture2DEnabled(true);
+        texture.bind(this);
+        mGLState.setTextureAlpha(alpha);
+        drawBoundTexture(texture, x, y, width, height);
+    }
+
+    public void drawMixed(BasicTexture from, BasicTexture to,
+            float ratio, int x, int y, int w, int h) {
+        drawMixed(from, to, ratio, x, y, w, h, mAlpha);
+    }
+
+    private void setTextureColor(float r, float g, float b, float alpha) {
+        float[] color = mTextureColor;
+        color[0] = r;
+        color[1] = g;
+        color[2] = b;
+        color[3] = alpha;
+    }
+
+    public void handleLowMemory() {
+    }
+
+    public void drawMixed(BasicTexture from, BasicTexture to,
+            float ratio, int x, int y, int width, int height, float alpha) {
+        if (alpha < OPAQUE_ALPHA) {
+            throw new RuntimeException("Cannot support alpha value");
+        }
+        mGLState.setBlendEnabled(!from.isOpaque() || !to.isOpaque());
+        mGLState.setTextureAlpha(1);
+        mGLState.setTexture2DEnabled(true);
+
+        final GL11 gl = mGL;
+        from.bind(this);
+
+        gl.glActiveTexture(GL11.GL_TEXTURE1);
+        to.bind(this);
+        gl.glEnable(GL11.GL_TEXTURE_2D);
+
+        // Interpolate the RGB and alpha values between both textures.
+        mGLState.setTexEnvMode(GL11.GL_COMBINE);
+        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_COMBINE_RGB, GL11.GL_INTERPOLATE);
+        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.
+        setTextureColor(ratio, ratio, ratio, ratio);
+        gl.glTexEnvfv(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_COLOR, mTextureColor, 0);
+
+        // Wire up the interpolation factor for RGB.
+        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC2_RGB, GL11.GL_CONSTANT);
+        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND2_RGB, GL11.GL_SRC_ALPHA);
+
+        // Wire up the interpolation factor for alpha.
+        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC2_ALPHA, GL11.GL_CONSTANT);
+        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND2_ALPHA, GL11.GL_SRC_ALPHA);
+
+        // Draw the combined texture.
+        drawBoundTexture(to, x, y, width, height);
+
+        // Disable TEXTURE1.
+        gl.glDisable(GL11.GL_TEXTURE_2D);
+        // Switch back to the default texture unit.
+        gl.glActiveTexture(GL11.GL_TEXTURE0);
+    }
+
+    // TODO: the code only work for 2D should get fixed for 3D or removed
+    private static final int MSKEW_X = 4;
+    private static final int MSKEW_Y = 1;
+    private static final int MSCALE_X = 0;
+    private static final int MSCALE_Y = 5;
+
+    private static boolean isMatrixRotatedOrFlipped(float matrix[]) {
+        return matrix[MSKEW_X] != 0 || matrix[MSKEW_Y] != 0
+                || matrix[MSCALE_X] < 0 || matrix[MSCALE_Y] > 0;
+    }
+
+    public void copyTexture2D(
+            RawTexture texture, int x, int y, int width, int height) {
+
+        if (isMatrixRotatedOrFlipped(mMatrixValues)) {
+            throw new IllegalArgumentException("cannot support rotated matrix");
+        }
+        float points[] = mapPoints(mMatrixValues, x, y + height, x + width, y);
+        x = (int) points[0];
+        y = (int) points[1];
+        width = (int) points[2] - x;
+        height = (int) points[3] - y;
+
+        GL11 gl = mGL;
+        int newWidth = Util.nextPowerOf2(width);
+        int newHeight = Util.nextPowerOf2(height);
+        int glError = GL11.GL_NO_ERROR;
+
+        gl.glBindTexture(GL11.GL_TEXTURE_2D, texture.getId());
+
+        int[] cropRect = {0,  0, width, height};
+        gl.glTexParameteriv(GL11.GL_TEXTURE_2D,
+                GL11Ext.GL_TEXTURE_CROP_RECT_OES, cropRect, 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.glCopyTexImage2D(GL11.GL_TEXTURE_2D, 0,
+                GL11.GL_RGBA, x, y, newWidth, newHeight, 0);
+        glError = gl.glGetError();
+
+        if (glError == GL11.GL_OUT_OF_MEMORY) {
+            throw new GLOutOfMemoryException();
+        }
+
+        if (glError != GL11.GL_NO_ERROR) {
+            throw new RuntimeException(
+                    "Texture copy fail, glError " + glError);
+        }
+
+        texture.setSize(width, height);
+        texture.setTextureSize(newWidth, newHeight);
+    }
+
+    private static class GLState {
+
+        private final GL11 mGL;
+
+        private int mTexEnvMode = GL11.GL_REPLACE;
+        private float mTextureAlpha = 1.0f;
+        private boolean mTexture2DEnabled = true;
+        private boolean mBlendEnabled = true;
+
+        public GLState(GL11 gl) {
+            mGL = gl;
+
+            // Disable unused state
+            gl.glDisable(GL11.GL_LIGHTING);
+
+            // Enable used features
+            gl.glEnable(GL11.GL_DITHER);
+
+            gl.glEnable(GL11.GL_SCISSOR_TEST);
+            gl.glEnable(GL11.GL_STENCIL_TEST);
+
+            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+            gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
+            gl.glEnable(GL11.GL_TEXTURE_2D);
+
+            gl.glTexEnvf(GL11.GL_TEXTURE_ENV,
+                    GL11.GL_TEXTURE_ENV_MODE, GL11.GL_REPLACE);
+
+            // Set the background color
+            gl.glClearColor(0f, 0f, 0f, 0f);
+            gl.glClearStencil(0);
+
+            gl.glEnable(GL11.GL_BLEND);
+            gl.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+        }
+
+        public void setTexEnvMode(int mode) {
+            if (mTexEnvMode == mode) return;
+            mTexEnvMode = mode;
+            mGL.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, mode);
+        }
+
+        public void setTextureAlpha(float alpha) {
+            if (mTextureAlpha == alpha) return;
+            mTextureAlpha = alpha;
+            if (alpha >= OPAQUE_ALPHA) {
+                // The alpha is need for those texture without alpha channel
+                mGL.glColor4f(1, 1, 1, 1);
+                setTexEnvMode(GL11.GL_REPLACE);
+            } else {
+                mGL.glColor4f(alpha, alpha, alpha, alpha);
+                setTexEnvMode(GL11.GL_MODULATE);
+            }
+        }
+
+        public void setFragmentColor(int color, float alpha) {
+            // Set mTextureAlpha to an invalid value, so that it will reset
+            // again in setTextureAlpha(float) later.
+            mTextureAlpha = -1.0f;
+
+            setTexture2DEnabled(false);
+            int prealpha = (int) ((color >>> 24) * alpha + 0.5);
+            mGL.glColor4x(
+                    ((color >> 16) & 0xFF) * prealpha,
+                    ((color >> 8) & 0xFF) * prealpha,
+                    (color & 0xFF) * prealpha, prealpha << 8);
+        }
+
+        public void setTexture2DEnabled(boolean enabled) {
+            if (mTexture2DEnabled == enabled) return;
+            mTexture2DEnabled = enabled;
+            if (enabled) {
+                mGL.glEnable(GL11.GL_TEXTURE_2D);
+            } else {
+                mGL.glDisable(GL11.GL_TEXTURE_2D);
+            }
+        }
+
+        public void setBlendEnabled(boolean enabled) {
+            if (mBlendEnabled == enabled) return;
+            mBlendEnabled = enabled;
+            if (enabled) {
+                mGL.glEnable(GL11.GL_BLEND);
+            } else {
+                mGL.glDisable(GL11.GL_BLEND);
+            }
+        }
+    }
+
+    public GL11 getGLInstance() {
+        return mGL;
+    }
+
+    public void setCurrentAnimationTimeMillis(long time) {
+        if (time < 0) throw new IllegalArgumentException("time must be nonnegative");
+        mAnimationTime = time;
+    }
+
+    public void clearBuffer() {
+        mGL.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_STENCIL_BUFFER_BIT);
+    }
+
+    public void setTextureCoords(RectF source) {
+        float buffer[] = mUvBuffer;
+        buffer[0] = source.left;
+        buffer[1] = source.top;
+        buffer[2] = source.right;
+        buffer[3] = source.top;
+        buffer[4] = source.left;
+        buffer[5] = source.bottom;
+        buffer[6] = source.right;
+        buffer[7] = source.bottom;
+        mUvPointer.put(buffer, 0, 8).position(0);
+    }
+
+    public void releaseTextures(Collection<? extends BasicTexture> c) {
+        IntArray array = new IntArray();
+        for (BasicTexture t : c) {
+            if (t.isLoaded(this)) array.add(t.mId);
+        }
+        if (array.size() > 0) {
+            mGL.glDeleteTextures(array.size(), array.toArray(null), 0);
+        }
+    }
+
+    public int save() {
+        return save(SAVE_FLAG_ALL);
+    }
+
+    public int save(int saveFlags) {
+        ConfigState config = obtainRestoreConfig();
+
+        if ((saveFlags & SAVE_FLAG_ALPHA) != 0) {
+            config.mAlpha = mAlpha;
+        } else {
+            config.mAlpha = -1;
+        }
+
+        if ((saveFlags & SAVE_FLAG_CLIP) != 0) {
+            config.mRect.set(mClipRect);
+        } else {
+            config.mRect.left = Integer.MAX_VALUE;
+        }
+
+        if ((saveFlags & SAVE_FLAG_MATRIX) != 0) {
+            System.arraycopy(mMatrixValues, 0, config.mMatrix, 0, 16);
+        } else {
+            config.mMatrix[0] = Float.NEGATIVE_INFINITY;
+        }
+
+        mRestoreStack.push(config);
+        return mRestoreStack.size() - 1;
+    }
+
+    public void restore() {
+        if (mRestoreStack.isEmpty()) throw new IllegalStateException();
+        ConfigState config = mRestoreStack.pop();
+        config.restore(this);
+        freeRestoreConfig(config);
+    }
+
+    public void restoreToCount(int saveCount) {
+        while (mRestoreStack.size() > saveCount) {
+            restore();
+        }
+    }
+
+    private void freeRestoreConfig(ConfigState action) {
+        action.mNextFree = mRecycledRestoreAction;
+        mRecycledRestoreAction = action;
+    }
+
+    private ConfigState obtainRestoreConfig() {
+        if (mRecycledRestoreAction != null) {
+            ConfigState result = mRecycledRestoreAction;
+            mRecycledRestoreAction = result.mNextFree;
+            return result;
+        }
+        return new ConfigState();
+    }
+
+    private static class ConfigState {
+        float mAlpha;
+        Rect mRect = new Rect();
+        float mMatrix[] = new float[16];
+        ConfigState mNextFree;
+
+        public void restore(GLCanvasImp canvas) {
+            if (mAlpha >= 0) canvas.setAlpha(mAlpha);
+            if (mRect.left != Integer.MAX_VALUE) {
+                Rect rect = mRect;
+                canvas.mClipRect.set(rect);
+                canvas.mGL.glScissor(
+                        rect.left, rect.top, rect.width(), rect.height());
+            }
+            if (mMatrix[0] != Float.NEGATIVE_INFINITY) {
+                System.arraycopy(mMatrix, 0, canvas.mMatrixValues, 0, 16);
+            }
+        }
+    }
+}
diff --git a/new3d/src/com/android/gallery3d/ui/GLListView.java b/new3d/src/com/android/gallery3d/ui/GLListView.java
index b2042c5..edc1627 100644
--- a/new3d/src/com/android/gallery3d/ui/GLListView.java
+++ b/new3d/src/com/android/gallery3d/ui/GLListView.java
@@ -132,7 +132,7 @@
 
     @Override
     protected void render(GLCanvas canvas) {
-        canvas.save(GLCanvas.CLIP_SAVE_FLAG);
+        canvas.save(GLCanvas.SAVE_FLAG_CLIP);
         canvas.clipRect(0, 0, getWidth(), getHeight());
         if (mHighlightIndex != INDEX_NONE) {
             GLView view = mModel.getView(mHighlightIndex);
diff --git a/new3d/src/com/android/gallery3d/ui/GLRootView.java b/new3d/src/com/android/gallery3d/ui/GLRootView.java
index 659a4be..81cc256 100644
--- a/new3d/src/com/android/gallery3d/ui/GLRootView.java
+++ b/new3d/src/com/android/gallery3d/ui/GLRootView.java
@@ -167,7 +167,7 @@
             Log.i(TAG, "GLObject has changed from " + mGL + " to " + gl);
         }
         mGL = gl;
-        mCanvas = new GLCanvas(gl);
+        mCanvas = new GLCanvasImp(gl);
         if (!ENABLE_FPS_TEST) {
             setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
         } else {
@@ -207,7 +207,7 @@
 
         if ((mFlags & FLAG_NEED_LAYOUT) != 0) layoutContentPane();
         mCanvas.clearBuffer();
-        mCanvas.setCurrentTimeMillis(SystemClock.uptimeMillis());
+        mCanvas.setCurrentAnimationTimeMillis(SystemClock.uptimeMillis());
         if (mContentView != null) {
            mContentView.render(mCanvas);
         }
diff --git a/new3d/src/com/android/gallery3d/ui/Pathbar.java b/new3d/src/com/android/gallery3d/ui/Pathbar.java
index 06cf4e0..b92f1da 100644
--- a/new3d/src/com/android/gallery3d/ui/Pathbar.java
+++ b/new3d/src/com/android/gallery3d/ui/Pathbar.java
@@ -251,7 +251,7 @@
             int degrees = mProgressStep * 360 / PROGRESS_STEP_COUNT;
             int pivotX = offsetX + icon.getWidth() / 2;
             int pivotY = offsetY + icon.getHeight() / 2;
-            canvas.save(GLCanvas.MATRIX_SAVE_FLAG);
+            canvas.save(GLCanvas.SAVE_FLAG_MATRIX);
             canvas.translate(pivotX, pivotY, 0);
             canvas.rotate(degrees, 0, 0, 1);
             canvas.translate(-pivotX, -pivotY, 0);
diff --git a/new3d/src/com/android/gallery3d/ui/ScrollerHelper.java b/new3d/src/com/android/gallery3d/ui/ScrollerHelper.java
index 916a637..a14de7d 100644
--- a/new3d/src/com/android/gallery3d/ui/ScrollerHelper.java
+++ b/new3d/src/com/android/gallery3d/ui/ScrollerHelper.java
@@ -6,7 +6,7 @@
 import android.view.animation.Interpolator;
 
 public class ScrollerHelper {
-    private static final long ANIMATION_START = 0;
+    private static final long START_ANIMATION = -1;
 
     private final float mDeceleration;
 
@@ -38,7 +38,7 @@
      */
     public boolean computeScrollOffset(long currentTimeMillis) {
         if (mFinished) return false;
-        if (mStartTime == ANIMATION_START) mStartTime = currentTimeMillis;
+        if (mStartTime == START_ANIMATION) mStartTime = currentTimeMillis;
 
         int timePassed = (int)(currentTimeMillis - mStartTime);
         if (timePassed < mDuration) {
@@ -70,7 +70,7 @@
         mVelocity = Math.abs(velocity);
         mDirection = velocity >= 0 ? 1 : -1;
         mDuration = (int) (1000 * mVelocity / mDeceleration);
-        mStartTime = ANIMATION_START;
+        mStartTime = START_ANIMATION;
         mStart = start;
         mMin = min;
         mMax = max;
diff --git a/new3d/tests/src/com/android/gallery3d/ui/GLCanvasTest.java b/new3d/tests/src/com/android/gallery3d/ui/GLCanvasTest.java
new file mode 100644
index 0000000..597ca7b
--- /dev/null
+++ b/new3d/tests/src/com/android/gallery3d/ui/GLCanvasTest.java
@@ -0,0 +1,41 @@
+package com.android.gallery3d.ui;
+
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Log;
+
+import java.util.Arrays;
+import javax.microedition.khronos.opengles.GL11;
+import junit.framework.TestCase;
+
+@SmallTest
+public class GLCanvasTest extends TestCase {
+    private static final String TAG = "GLCanvasTest";
+
+    GL11 mGlStub;
+    GLCanvas mCanvas;
+
+    public void setUp() {
+        mGlStub = new GLStub();
+        mCanvas = new GLCanvasImp(mGlStub);
+    }
+
+    public void testGetGLInstance() {
+        assertSame(mGlStub, mCanvas.getGLInstance());
+    }
+
+    public void testAnimationTime() {
+        long[] testData = {0, 1, 2, 1000, 10000, Long.MAX_VALUE};
+
+        for (long v : testData) {
+            mCanvas.setCurrentAnimationTimeMillis(v);
+            assertEquals(v, mCanvas.currentAnimationTimeMillis());
+        }
+
+        try {
+            mCanvas.setCurrentAnimationTimeMillis(-1);
+            fail();
+        } catch (IllegalArgumentException ex) {
+            // expected.
+        }
+    }
+}
diff --git a/new3d/tests/src/com/android/gallery3d/ui/GLStub.java b/new3d/tests/src/com/android/gallery3d/ui/GLStub.java
new file mode 100644
index 0000000..3b4d7d6
--- /dev/null
+++ b/new3d/tests/src/com/android/gallery3d/ui/GLStub.java
@@ -0,0 +1,1476 @@
+package com.android.gallery3d.ui;
+
+import android.util.Log;
+
+import javax.microedition.khronos.opengles.GL;
+import javax.microedition.khronos.opengles.GL10;
+import javax.microedition.khronos.opengles.GL10Ext;
+import javax.microedition.khronos.opengles.GL11;
+import javax.microedition.khronos.opengles.GL11Ext;
+import javax.microedition.khronos.opengles.GL11ExtensionPack;
+
+public class GLStub implements GL, GL10, GL10Ext, GL11, GL11Ext {
+    private static final String TAG = "GLStub";
+
+    public void glActiveTexture(
+        int texture
+    ){}
+
+    public void glAlphaFunc(
+        int func,
+        float ref
+    ){}
+
+    public void glAlphaFuncx(
+        int func,
+        int ref
+    ){}
+
+    public void glBindTexture(
+        int target,
+        int texture
+    ){}
+
+    public void glBlendFunc(
+        int sfactor,
+        int dfactor
+    ){}
+
+    public void glClear(
+        int mask
+    ){}
+
+    public void glClearColor(
+        float red,
+        float green,
+        float blue,
+        float alpha
+    ){}
+
+    public void glClearColorx(
+        int red,
+        int green,
+        int blue,
+        int alpha
+    ){}
+
+    public void glClearDepthf(
+        float depth
+    ){}
+
+    public void glClearDepthx(
+        int depth
+    ){}
+
+    public void glClearStencil(
+        int s
+    ){}
+
+    public void glClientActiveTexture(
+        int texture
+    ){}
+
+    public void glColor4f(
+        float red,
+        float green,
+        float blue,
+        float alpha
+    ){}
+
+    public void glColor4x(
+        int red,
+        int green,
+        int blue,
+        int alpha
+    ){}
+
+    public void glColorMask(
+        boolean red,
+        boolean green,
+        boolean blue,
+        boolean alpha
+    ){}
+
+    public void glColorPointer(
+        int size,
+        int type,
+        int stride,
+        java.nio.Buffer pointer
+    ){}
+
+    public void glCompressedTexImage2D(
+        int target,
+        int level,
+        int internalformat,
+        int width,
+        int height,
+        int border,
+        int imageSize,
+        java.nio.Buffer data
+    ){}
+
+    public void glCompressedTexSubImage2D(
+        int target,
+        int level,
+        int xoffset,
+        int yoffset,
+        int width,
+        int height,
+        int format,
+        int imageSize,
+        java.nio.Buffer data
+    ){}
+
+    public void glCopyTexImage2D(
+        int target,
+        int level,
+        int internalformat,
+        int x,
+        int y,
+        int width,
+        int height,
+        int border
+    ){}
+
+    public void glCopyTexSubImage2D(
+        int target,
+        int level,
+        int xoffset,
+        int yoffset,
+        int x,
+        int y,
+        int width,
+        int height
+    ){}
+
+    public void glCullFace(
+        int mode
+    ){}
+
+    public void glDeleteTextures(
+        int n,
+        int[] textures,
+        int offset
+    ){}
+
+    public void glDeleteTextures(
+        int n,
+        java.nio.IntBuffer textures
+    ){}
+
+    public void glDepthFunc(
+        int func
+    ){}
+
+    public void glDepthMask(
+        boolean flag
+    ){}
+
+    public void glDepthRangef(
+        float zNear,
+        float zFar
+    ){}
+
+    public void glDepthRangex(
+        int zNear,
+        int zFar
+    ){}
+
+    public void glDisable(
+        int cap
+    ){}
+
+    public void glDisableClientState(
+        int array
+    ){}
+
+    public void glDrawArrays(
+        int mode,
+        int first,
+        int count
+    ){}
+
+    public void glDrawElements(
+        int mode,
+        int count,
+        int type,
+        java.nio.Buffer indices
+    ){}
+
+    public void glEnable(
+        int cap
+    ){}
+
+    public void glEnableClientState(
+        int array
+    ){}
+
+    public void glFinish(
+    ){}
+
+    public void glFlush(
+    ){}
+
+    public void glFogf(
+        int pname,
+        float param
+    ){}
+
+    public void glFogfv(
+        int pname,
+        float[] params,
+        int offset
+    ){}
+
+    public void glFogfv(
+        int pname,
+        java.nio.FloatBuffer params
+    ){}
+
+    public void glFogx(
+        int pname,
+        int param
+    ){}
+
+    public void glFogxv(
+        int pname,
+        int[] params,
+        int offset
+    ){}
+
+    public void glFogxv(
+        int pname,
+        java.nio.IntBuffer params
+    ){}
+
+    public void glFrontFace(
+        int mode
+    ){}
+
+    public void glFrustumf(
+        float left,
+        float right,
+        float bottom,
+        float top,
+        float zNear,
+        float zFar
+    ){}
+
+    public void glFrustumx(
+        int left,
+        int right,
+        int bottom,
+        int top,
+        int zNear,
+        int zFar
+    ){}
+
+    public void glGenTextures(
+        int n,
+        int[] textures,
+        int offset
+    ){}
+
+    public void glGenTextures(
+        int n,
+        java.nio.IntBuffer textures
+    ){}
+
+    public int glGetError(
+    ){ throw new UnsupportedOperationException(); }
+
+    public void glGetIntegerv(
+        int pname,
+        int[] params,
+        int offset
+    ){}
+
+    public void glGetIntegerv(
+        int pname,
+        java.nio.IntBuffer params
+    ){}
+
+    public String glGetString(
+        int name
+    ){ throw new UnsupportedOperationException(); }
+
+    public void glHint(
+        int target,
+        int mode
+    ){}
+
+    public void glLightModelf(
+        int pname,
+        float param
+    ){}
+
+    public void glLightModelfv(
+        int pname,
+        float[] params,
+        int offset
+    ){}
+
+    public void glLightModelfv(
+        int pname,
+        java.nio.FloatBuffer params
+    ){}
+
+    public void glLightModelx(
+        int pname,
+        int param
+    ){}
+
+    public void glLightModelxv(
+        int pname,
+        int[] params,
+        int offset
+    ){}
+
+    public void glLightModelxv(
+        int pname,
+        java.nio.IntBuffer params
+    ){}
+
+    public void glLightf(
+        int light,
+        int pname,
+        float param
+    ){}
+
+    public void glLightfv(
+        int light,
+        int pname,
+        float[] params,
+        int offset
+    ){}
+
+    public void glLightfv(
+        int light,
+        int pname,
+        java.nio.FloatBuffer params
+    ){}
+
+    public void glLightx(
+        int light,
+        int pname,
+        int param
+    ){}
+
+    public void glLightxv(
+        int light,
+        int pname,
+        int[] params,
+        int offset
+    ){}
+
+    public void glLightxv(
+        int light,
+        int pname,
+        java.nio.IntBuffer params
+    ){}
+
+    public void glLineWidth(
+        float width
+    ){}
+
+    public void glLineWidthx(
+        int width
+    ){}
+
+    public void glLoadIdentity(
+    ){}
+
+    public void glLoadMatrixf(
+        float[] m,
+        int offset
+    ){}
+
+    public void glLoadMatrixf(
+        java.nio.FloatBuffer m
+    ){}
+
+    public void glLoadMatrixx(
+        int[] m,
+        int offset
+    ){}
+
+    public void glLoadMatrixx(
+        java.nio.IntBuffer m
+    ){}
+
+    public void glLogicOp(
+        int opcode
+    ){}
+
+    public void glMaterialf(
+        int face,
+        int pname,
+        float param
+    ){}
+
+    public void glMaterialfv(
+        int face,
+        int pname,
+        float[] params,
+        int offset
+    ){}
+
+    public void glMaterialfv(
+        int face,
+        int pname,
+        java.nio.FloatBuffer params
+    ){}
+
+    public void glMaterialx(
+        int face,
+        int pname,
+        int param
+    ){}
+
+    public void glMaterialxv(
+        int face,
+        int pname,
+        int[] params,
+        int offset
+    ){}
+
+    public void glMaterialxv(
+        int face,
+        int pname,
+        java.nio.IntBuffer params
+    ){}
+
+    public void glMatrixMode(
+        int mode
+    ){}
+
+    public void glMultMatrixf(
+        float[] m,
+        int offset
+    ){}
+
+    public void glMultMatrixf(
+        java.nio.FloatBuffer m
+    ){}
+
+    public void glMultMatrixx(
+        int[] m,
+        int offset
+    ){}
+
+    public void glMultMatrixx(
+        java.nio.IntBuffer m
+    ){}
+
+    public void glMultiTexCoord4f(
+        int target,
+        float s,
+        float t,
+        float r,
+        float q
+    ){}
+
+    public void glMultiTexCoord4x(
+        int target,
+        int s,
+        int t,
+        int r,
+        int q
+    ){}
+
+    public void glNormal3f(
+        float nx,
+        float ny,
+        float nz
+    ){}
+
+    public void glNormal3x(
+        int nx,
+        int ny,
+        int nz
+    ){}
+
+    public void glNormalPointer(
+        int type,
+        int stride,
+        java.nio.Buffer pointer
+    ){}
+
+    public void glOrthof(
+        float left,
+        float right,
+        float bottom,
+        float top,
+        float zNear,
+        float zFar
+    ){}
+
+    public void glOrthox(
+        int left,
+        int right,
+        int bottom,
+        int top,
+        int zNear,
+        int zFar
+    ){}
+
+    public void glPixelStorei(
+        int pname,
+        int param
+    ){}
+
+    public void glPointSize(
+        float size
+    ){}
+
+    public void glPointSizex(
+        int size
+    ){}
+
+    public void glPolygonOffset(
+        float factor,
+        float units
+    ){}
+
+    public void glPolygonOffsetx(
+        int factor,
+        int units
+    ){}
+
+    public void glPopMatrix(
+    ){}
+
+    public void glPushMatrix(
+    ){}
+
+    public void glReadPixels(
+        int x,
+        int y,
+        int width,
+        int height,
+        int format,
+        int type,
+        java.nio.Buffer pixels
+    ){}
+
+    public void glRotatef(
+        float angle,
+        float x,
+        float y,
+        float z
+    ){}
+
+    public void glRotatex(
+        int angle,
+        int x,
+        int y,
+        int z
+    ){}
+
+    public void glSampleCoverage(
+        float value,
+        boolean invert
+    ){}
+
+    public void glSampleCoveragex(
+        int value,
+        boolean invert
+    ){}
+
+    public void glScalef(
+        float x,
+        float y,
+        float z
+    ){}
+
+    public void glScalex(
+        int x,
+        int y,
+        int z
+    ){}
+
+    public void glScissor(
+        int x,
+        int y,
+        int width,
+        int height
+    ){}
+
+    public void glShadeModel(
+        int mode
+    ){}
+
+    public void glStencilFunc(
+        int func,
+        int ref,
+        int mask
+    ){}
+
+    public void glStencilMask(
+        int mask
+    ){}
+
+    public void glStencilOp(
+        int fail,
+        int zfail,
+        int zpass
+    ){}
+
+    public void glTexCoordPointer(
+        int size,
+        int type,
+        int stride,
+        java.nio.Buffer pointer
+    ){}
+
+    public void glTexEnvf(
+        int target,
+        int pname,
+        float param
+    ){}
+
+    public void glTexEnvfv(
+        int target,
+        int pname,
+        float[] params,
+        int offset
+    ){}
+
+    public void glTexEnvfv(
+        int target,
+        int pname,
+        java.nio.FloatBuffer params
+    ){}
+
+    public void glTexEnvx(
+        int target,
+        int pname,
+        int param
+    ){}
+
+    public void glTexEnvxv(
+        int target,
+        int pname,
+        int[] params,
+        int offset
+    ){}
+
+    public void glTexEnvxv(
+        int target,
+        int pname,
+        java.nio.IntBuffer params
+    ){}
+
+    public void glTexImage2D(
+        int target,
+        int level,
+        int internalformat,
+        int width,
+        int height,
+        int border,
+        int format,
+        int type,
+        java.nio.Buffer pixels
+    ){}
+
+    public void glTexParameterf(
+        int target,
+        int pname,
+        float param
+    ){}
+
+    public void glTexParameterx(
+        int target,
+        int pname,
+        int param
+    ){}
+
+    public void glTexSubImage2D(
+        int target,
+        int level,
+        int xoffset,
+        int yoffset,
+        int width,
+        int height,
+        int format,
+        int type,
+        java.nio.Buffer pixels
+    ){}
+
+    public void glTranslatef(
+        float x,
+        float y,
+        float z
+    ){}
+
+    public void glTranslatex(
+        int x,
+        int y,
+        int z
+    ){}
+
+    public void glVertexPointer(
+        int size,
+        int type,
+        int stride,
+        java.nio.Buffer pointer
+    ){}
+
+    public void glViewport(
+        int x,
+        int y,
+        int width,
+        int height
+    ){}
+
+    public int glQueryMatrixxOES(
+        int[] mantissa,
+        int mantissaOffset,
+        int[] exponent,
+        int exponentOffset
+    ){ throw new UnsupportedOperationException(); }
+
+    public int glQueryMatrixxOES(
+        java.nio.IntBuffer mantissa,
+        java.nio.IntBuffer exponent
+    ){ throw new UnsupportedOperationException(); }
+
+    public void glGetPointerv(int pname, java.nio.Buffer[] params){}
+    public void glBindBuffer(
+        int target,
+        int buffer
+    ){}
+
+    public void glBufferData(
+        int target,
+        int size,
+        java.nio.Buffer data,
+        int usage
+    ){}
+
+    public void glBufferSubData(
+        int target,
+        int offset,
+        int size,
+        java.nio.Buffer data
+    ){}
+
+    public void glClipPlanef(
+        int plane,
+        float[] equation,
+        int offset
+    ){}
+
+    public void glClipPlanef(
+        int plane,
+        java.nio.FloatBuffer equation
+    ){}
+
+    public void glClipPlanex(
+        int plane,
+        int[] equation,
+        int offset
+    ){}
+
+    public void glClipPlanex(
+        int plane,
+        java.nio.IntBuffer equation
+    ){}
+
+    public void glColor4ub(
+        byte red,
+        byte green,
+        byte blue,
+        byte alpha
+    ){}
+
+    public void glColorPointer(
+        int size,
+        int type,
+        int stride,
+        int offset
+    ){}
+
+    public void glDeleteBuffers(
+        int n,
+        int[] buffers,
+        int offset
+    ){}
+
+    public void glDeleteBuffers(
+        int n,
+        java.nio.IntBuffer buffers
+    ){}
+
+    public void glDrawElements(
+        int mode,
+        int count,
+        int type,
+        int offset
+    ){}
+
+    public void glGenBuffers(
+        int n,
+        int[] buffers,
+        int offset
+    ){}
+
+    public void glGenBuffers(
+        int n,
+        java.nio.IntBuffer buffers
+    ){}
+
+    public void glGetBooleanv(
+        int pname,
+        boolean[] params,
+        int offset
+    ){}
+
+    public void glGetBooleanv(
+        int pname,
+        java.nio.IntBuffer params
+    ){}
+
+    public void glGetBufferParameteriv(
+        int target,
+        int pname,
+        int[] params,
+        int offset
+    ){}
+
+    public void glGetBufferParameteriv(
+        int target,
+        int pname,
+        java.nio.IntBuffer params
+    ){}
+
+    public void glGetClipPlanef(
+        int pname,
+        float[] eqn,
+        int offset
+    ){}
+
+    public void glGetClipPlanef(
+        int pname,
+        java.nio.FloatBuffer eqn
+    ){}
+
+    public void glGetClipPlanex(
+        int pname,
+        int[] eqn,
+        int offset
+    ){}
+
+    public void glGetClipPlanex(
+        int pname,
+        java.nio.IntBuffer eqn
+    ){}
+
+    public void glGetFixedv(
+        int pname,
+        int[] params,
+        int offset
+    ){}
+
+    public void glGetFixedv(
+        int pname,
+        java.nio.IntBuffer params
+    ){}
+
+    public void glGetFloatv(
+        int pname,
+        float[] params,
+        int offset
+    ){}
+
+    public void glGetFloatv(
+        int pname,
+        java.nio.FloatBuffer params
+    ){}
+
+    public void glGetLightfv(
+        int light,
+        int pname,
+        float[] params,
+        int offset
+    ){}
+
+    public void glGetLightfv(
+        int light,
+        int pname,
+        java.nio.FloatBuffer params
+    ){}
+
+    public void glGetLightxv(
+        int light,
+        int pname,
+        int[] params,
+        int offset
+    ){}
+
+    public void glGetLightxv(
+        int light,
+        int pname,
+        java.nio.IntBuffer params
+    ){}
+
+    public void glGetMaterialfv(
+        int face,
+        int pname,
+        float[] params,
+        int offset
+    ){}
+
+    public void glGetMaterialfv(
+        int face,
+        int pname,
+        java.nio.FloatBuffer params
+    ){}
+
+    public void glGetMaterialxv(
+        int face,
+        int pname,
+        int[] params,
+        int offset
+    ){}
+
+    public void glGetMaterialxv(
+        int face,
+        int pname,
+        java.nio.IntBuffer params
+    ){}
+
+    public void glGetTexEnviv(
+        int env,
+        int pname,
+        int[] params,
+        int offset
+    ){}
+
+    public void glGetTexEnviv(
+        int env,
+        int pname,
+        java.nio.IntBuffer params
+    ){}
+
+    public void glGetTexEnvxv(
+        int env,
+        int pname,
+        int[] params,
+        int offset
+    ){}
+
+    public void glGetTexEnvxv(
+        int env,
+        int pname,
+        java.nio.IntBuffer params
+    ){}
+
+    public void glGetTexParameterfv(
+        int target,
+        int pname,
+        float[] params,
+        int offset
+    ){}
+
+    public void glGetTexParameterfv(
+        int target,
+        int pname,
+        java.nio.FloatBuffer params
+    ){}
+
+    public void glGetTexParameteriv(
+        int target,
+        int pname,
+        int[] params,
+        int offset
+    ){}
+
+    public void glGetTexParameteriv(
+        int target,
+        int pname,
+        java.nio.IntBuffer params
+    ){}
+
+    public void glGetTexParameterxv(
+        int target,
+        int pname,
+        int[] params,
+        int offset
+    ){}
+
+    public void glGetTexParameterxv(
+        int target,
+        int pname,
+        java.nio.IntBuffer params
+    ){}
+
+    public boolean glIsBuffer(
+        int buffer
+    ){ throw new UnsupportedOperationException(); }
+
+    public boolean glIsEnabled(
+        int cap
+    ){ throw new UnsupportedOperationException(); }
+
+    public boolean glIsTexture(
+        int texture
+    ){ throw new UnsupportedOperationException(); }
+
+    public void glNormalPointer(
+        int type,
+        int stride,
+        int offset
+    ){}
+
+    public void glPointParameterf(
+        int pname,
+        float param
+    ){}
+
+    public void glPointParameterfv(
+        int pname,
+        float[] params,
+        int offset
+    ){}
+
+    public void glPointParameterfv(
+        int pname,
+        java.nio.FloatBuffer params
+    ){}
+
+    public void glPointParameterx(
+        int pname,
+        int param
+    ){}
+
+    public void glPointParameterxv(
+        int pname,
+        int[] params,
+        int offset
+    ){}
+
+    public void glPointParameterxv(
+        int pname,
+        java.nio.IntBuffer params
+    ){}
+
+    public void glPointSizePointerOES(
+        int type,
+        int stride,
+        java.nio.Buffer pointer
+    ){}
+
+    public void glTexCoordPointer(
+        int size,
+        int type,
+        int stride,
+        int offset
+    ){}
+
+    public void glTexEnvi(
+        int target,
+        int pname,
+        int param
+    ){}
+
+    public void glTexEnviv(
+        int target,
+        int pname,
+        int[] params,
+        int offset
+    ){}
+
+    public void glTexEnviv(
+        int target,
+        int pname,
+        java.nio.IntBuffer params
+    ){}
+
+    public void glTexParameterfv(
+        int target,
+        int pname,
+        float[] params,
+        int offset
+    ){}
+
+    public void glTexParameterfv(
+        int target,
+        int pname,
+        java.nio.FloatBuffer params
+    ){}
+
+    public void glTexParameteri(
+        int target,
+        int pname,
+        int param
+    ){}
+
+    public void glTexParameteriv(
+        int target,
+        int pname,
+        int[] params,
+        int offset
+    ){}
+
+    public void glTexParameteriv(
+        int target,
+        int pname,
+        java.nio.IntBuffer params
+    ){}
+
+    public void glTexParameterxv(
+        int target,
+        int pname,
+        int[] params,
+        int offset
+    ){}
+
+    public void glTexParameterxv(
+        int target,
+        int pname,
+        java.nio.IntBuffer params
+    ){}
+
+    public void glVertexPointer(
+        int size,
+        int type,
+        int stride,
+        int offset
+    ){}
+
+    public void glCurrentPaletteMatrixOES(
+        int matrixpaletteindex
+    ){}
+
+    public void glDrawTexfOES(
+        float x,
+        float y,
+        float z,
+        float width,
+        float height
+    ){}
+
+    public void glDrawTexfvOES(
+        float[] coords,
+        int offset
+    ){}
+
+    public void glDrawTexfvOES(
+        java.nio.FloatBuffer coords
+    ){}
+
+    public void glDrawTexiOES(
+        int x,
+        int y,
+        int z,
+        int width,
+        int height
+    ){}
+
+    public void glDrawTexivOES(
+        int[] coords,
+        int offset
+    ){}
+
+    public void glDrawTexivOES(
+        java.nio.IntBuffer coords
+    ){}
+
+    public void glDrawTexsOES(
+        short x,
+        short y,
+        short z,
+        short width,
+        short height
+    ){}
+
+    public void glDrawTexsvOES(
+        short[] coords,
+        int offset
+    ){}
+
+    public void glDrawTexsvOES(
+        java.nio.ShortBuffer coords
+    ){}
+
+    public void glDrawTexxOES(
+        int x,
+        int y,
+        int z,
+        int width,
+        int height
+    ){}
+
+    public void glDrawTexxvOES(
+        int[] coords,
+        int offset
+    ){}
+
+    public void glDrawTexxvOES(
+        java.nio.IntBuffer coords
+    ){}
+
+    public void glLoadPaletteFromModelViewMatrixOES(
+    ){}
+
+    public void glMatrixIndexPointerOES(
+        int size,
+        int type,
+        int stride,
+        java.nio.Buffer pointer
+    ){}
+
+    public void glMatrixIndexPointerOES(
+        int size,
+        int type,
+        int stride,
+        int offset
+    ){}
+
+    public void glWeightPointerOES(
+        int size,
+        int type,
+        int stride,
+        java.nio.Buffer pointer
+    ){}
+
+    public void glWeightPointerOES(
+        int size,
+        int type,
+        int stride,
+        int offset
+    ){}
+
+    public void glBindFramebufferOES(
+        int target,
+        int framebuffer
+    ){}
+
+    public void glBindRenderbufferOES(
+        int target,
+        int renderbuffer
+    ){}
+
+    public void glBlendEquation(
+        int mode
+    ){}
+
+    public void glBlendEquationSeparate(
+        int modeRGB,
+        int modeAlpha
+    ){}
+
+    public void glBlendFuncSeparate(
+        int srcRGB,
+        int dstRGB,
+        int srcAlpha,
+        int dstAlpha
+    ){}
+
+    public int glCheckFramebufferStatusOES(
+        int target
+    ){ throw new UnsupportedOperationException(); }
+
+    public void glDeleteFramebuffersOES(
+        int n,
+        int[] framebuffers,
+        int offset
+    ){}
+
+    public void glDeleteFramebuffersOES(
+        int n,
+        java.nio.IntBuffer framebuffers
+    ){}
+
+    public void glDeleteRenderbuffersOES(
+        int n,
+        int[] renderbuffers,
+        int offset
+    ){}
+
+    public void glDeleteRenderbuffersOES(
+        int n,
+        java.nio.IntBuffer renderbuffers
+    ){}
+
+    public void glFramebufferRenderbufferOES(
+        int target,
+        int attachment,
+        int renderbuffertarget,
+        int renderbuffer
+    ){}
+
+    public void glFramebufferTexture2DOES(
+        int target,
+        int attachment,
+        int textarget,
+        int texture,
+        int level
+    ){}
+
+    public void glGenerateMipmapOES(
+        int target
+    ){}
+
+    public void glGenFramebuffersOES(
+        int n,
+        int[] framebuffers,
+        int offset
+    ){}
+
+    public void glGenFramebuffersOES(
+        int n,
+        java.nio.IntBuffer framebuffers
+    ){}
+
+    public void glGenRenderbuffersOES(
+        int n,
+        int[] renderbuffers,
+        int offset
+    ){}
+
+    public void glGenRenderbuffersOES(
+        int n,
+        java.nio.IntBuffer renderbuffers
+    ){}
+
+    public void glGetFramebufferAttachmentParameterivOES(
+        int target,
+        int attachment,
+        int pname,
+        int[] params,
+        int offset
+    ){}
+
+    public void glGetFramebufferAttachmentParameterivOES(
+        int target,
+        int attachment,
+        int pname,
+        java.nio.IntBuffer params
+    ){}
+
+    public void glGetRenderbufferParameterivOES(
+        int target,
+        int pname,
+        int[] params,
+        int offset
+    ){}
+
+    public void glGetRenderbufferParameterivOES(
+        int target,
+        int pname,
+        java.nio.IntBuffer params
+    ){}
+
+    public void glGetTexGenfv(
+        int coord,
+        int pname,
+        float[] params,
+        int offset
+    ){}
+
+    public void glGetTexGenfv(
+        int coord,
+        int pname,
+        java.nio.FloatBuffer params
+    ){}
+
+    public void glGetTexGeniv(
+        int coord,
+        int pname,
+        int[] params,
+        int offset
+    ){}
+
+    public void glGetTexGeniv(
+        int coord,
+        int pname,
+        java.nio.IntBuffer params
+    ){}
+
+    public void glGetTexGenxv(
+        int coord,
+        int pname,
+        int[] params,
+        int offset
+    ){}
+
+    public void glGetTexGenxv(
+        int coord,
+        int pname,
+        java.nio.IntBuffer params
+    ){}
+
+    public boolean glIsFramebufferOES(
+        int framebuffer
+    ){ throw new UnsupportedOperationException(); }
+
+    public boolean glIsRenderbufferOES(
+        int renderbuffer
+    ){ throw new UnsupportedOperationException(); }
+
+    public void glRenderbufferStorageOES(
+        int target,
+        int internalformat,
+        int width,
+        int height
+    ){}
+
+    public void glTexGenf(
+        int coord,
+        int pname,
+        float param
+    ){}
+
+    public void glTexGenfv(
+        int coord,
+        int pname,
+        float[] params,
+        int offset
+    ){}
+
+    public void glTexGenfv(
+        int coord,
+        int pname,
+        java.nio.FloatBuffer params
+    ){}
+
+    public void glTexGeni(
+        int coord,
+        int pname,
+        int param
+    ){}
+
+    public void glTexGeniv(
+        int coord,
+        int pname,
+        int[] params,
+        int offset
+    ){}
+
+    public void glTexGeniv(
+        int coord,
+        int pname,
+        java.nio.IntBuffer params
+    ){}
+
+    public void glTexGenx(
+        int coord,
+        int pname,
+        int param
+    ){}
+
+    public void glTexGenxv(
+        int coord,
+        int pname,
+        int[] params,
+        int offset
+    ){}
+
+    public void glTexGenxv(
+        int coord,
+        int pname,
+        java.nio.IntBuffer params
+    ){}
+}
