/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.gallery3d.glrenderer;

import android.graphics.Bitmap;
import android.graphics.Rect;
import android.graphics.RectF;
import android.opengl.GLU;
import android.opengl.GLUtils;
import android.opengl.Matrix;
import android.util.Log;

import com.android.gallery3d.common.Utils;
import com.android.gallery3d.util.IntArray;

import junit.framework.Assert;

import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;

import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;
import javax.microedition.khronos.opengles.GL11Ext;
import javax.microedition.khronos.opengles.GL11ExtensionPack;

public class GLES11Canvas implements GLCanvas {
    @SuppressWarnings("unused")
    private static final String TAG = "GLCanvasImp";

    private static final float OPAQUE_ALPHA = 0.95f;

    private static final int OFFSET_FILL_RECT = 0;
    private static final int OFFSET_DRAW_LINE = 4;
    private static final int OFFSET_DRAW_RECT = 6;
    private static final float[] BOX_COORDINATES = {
            0, 0, 1, 0, 0, 1, 1, 1,  // used for filling a rectangle
            0, 0, 1, 1,              // used for drawing a line
            0, 0, 0, 1, 1, 1, 1, 0}; // used for drawing the outline of a rectangle

    private GL11 mGL;

    private final float mMatrixValues[] = new float[16];
    private final float mTextureMatrixValues[] = new float[16];

    // The results of mapPoints are stored in this buffer, and the order is
    // x1, y1, x2, y2.
    private final float mMapPointsBuffer[] = new float[4];

    private final float mTextureColor[] = new float[4];

    private int mBoxCoords;

    private GLState mGLState;
    private final ArrayList<RawTexture> mTargetStack = new ArrayList<RawTexture>();

    private float mAlpha;
    private final ArrayList<ConfigState> mRestoreStack = new ArrayList<ConfigState>();
    private ConfigState mRecycledRestoreAction;

    private final RectF mDrawTextureSourceRect = new RectF();
    private final RectF mDrawTextureTargetRect = new RectF();
    private final float[] mTempMatrix = new float[32];
    private final IntArray mUnboundTextures = new IntArray();
    private final IntArray mDeleteBuffers = new IntArray();
    private int mScreenWidth;
    private int mScreenHeight;
    private boolean mBlendEnabled = true;
    private int mFrameBuffer[] = new int[1];
    private static float[] sCropRect = new float[4];

    private RawTexture mTargetTexture;

    // Drawing statistics
    int mCountDrawLine;
    int mCountFillRect;
    int mCountDrawMesh;
    int mCountTextureRect;
    int mCountTextureOES;

    private static GLId mGLId = new GLES11IdImpl();

    public GLES11Canvas(GL11 gl) {
        mGL = gl;
        mGLState = new GLState(gl);
        // First create an nio buffer, then create a VBO from it.
        int size = BOX_COORDINATES.length * Float.SIZE / Byte.SIZE;
        FloatBuffer xyBuffer = allocateDirectNativeOrderBuffer(size).asFloatBuffer();
        xyBuffer.put(BOX_COORDINATES, 0, BOX_COORDINATES.length).position(0);

        int[] name = new int[1];
        mGLId.glGenBuffers(1, name, 0);
        mBoxCoords = name[0];

        gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, mBoxCoords);
        gl.glBufferData(GL11.GL_ARRAY_BUFFER, xyBuffer.capacity() * (Float.SIZE / Byte.SIZE),
                xyBuffer, GL11.GL_STATIC_DRAW);

        gl.glVertexPointer(2, GL11.GL_FLOAT, 0, 0);
        gl.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0);

        // Enable the texture coordinate array for Texture 1
        gl.glClientActiveTexture(GL11.GL_TEXTURE1);
        gl.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0);
        gl.glClientActiveTexture(GL11.GL_TEXTURE0);
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        // mMatrixValues and mAlpha will be initialized in setSize()
    }

    @Override
    public void setSize(int width, int height) {
        Assert.assertTrue(width >= 0 && height >= 0);

        if (mTargetTexture == null) {
            mScreenWidth = width;
            mScreenHeight = height;
        }
        mAlpha = 1.0f;

        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();

        float matrix[] = mMatrixValues;
        Matrix.setIdentityM(matrix, 0);
        // to match the graphic coordinate system in android, we flip it vertically.
        if (mTargetTexture == null) {
            Matrix.translateM(matrix, 0, 0, height, 0);
            Matrix.scaleM(matrix, 0, 1, -1, 1);
        }
    }

    @Override
    public void setAlpha(float alpha) {
        Assert.assertTrue(alpha >= 0 && alpha <= 1);
        mAlpha = alpha;
    }

    @Override
    public float getAlpha() {
        return mAlpha;
    }

    @Override
    public void multiplyAlpha(float alpha) {
        Assert.assertTrue(alpha >= 0 && alpha <= 1);
        mAlpha *= alpha;
    }

    private static ByteBuffer allocateDirectNativeOrderBuffer(int size) {
        return ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder());
    }

    @Override
    public void drawRect(float x, float y, float width, float height, GLPaint paint) {
        GL11 gl = mGL;

        mGLState.setColorMode(paint.getColor(), mAlpha);
        mGLState.setLineWidth(paint.getLineWidth());

        saveTransform();
        translate(x, y);
        scale(width, height, 1);

        gl.glLoadMatrixf(mMatrixValues, 0);
        gl.glDrawArrays(GL11.GL_LINE_LOOP, OFFSET_DRAW_RECT, 4);

        restoreTransform();
        mCountDrawLine++;
    }

    @Override
    public void drawLine(float x1, float y1, float x2, float y2, GLPaint paint) {
        GL11 gl = mGL;

        mGLState.setColorMode(paint.getColor(), mAlpha);
        mGLState.setLineWidth(paint.getLineWidth());

        saveTransform();
        translate(x1, y1);
        scale(x2 - x1, y2 - y1, 1);

        gl.glLoadMatrixf(mMatrixValues, 0);
        gl.glDrawArrays(GL11.GL_LINE_STRIP, OFFSET_DRAW_LINE, 2);

        restoreTransform();
        mCountDrawLine++;
    }

    @Override
    public void fillRect(float x, float y, float width, float height, int color) {
        mGLState.setColorMode(color, mAlpha);
        GL11 gl = mGL;

        saveTransform();
        translate(x, y);
        scale(width, height, 1);

        gl.glLoadMatrixf(mMatrixValues, 0);
        gl.glDrawArrays(GL11.GL_TRIANGLE_STRIP, OFFSET_FILL_RECT, 4);

        restoreTransform();
        mCountFillRect++;
    }

    @Override
    public void translate(float x, float y, float z) {
        Matrix.translateM(mMatrixValues, 0, x, y, z);
    }

    // This is a faster version of translate(x, y, z) because
    // (1) we knows z = 0, (2) we inline the Matrix.translateM call,
    // (3) we unroll the loop
    @Override
    public void translate(float x, float y) {
        float[] m = mMatrixValues;
        m[12] += m[0] * x + m[4] * y;
        m[13] += m[1] * x + m[5] * y;
        m[14] += m[2] * x + m[6] * y;
        m[15] += m[3] * x + m[7] * y;
    }

    @Override
    public void scale(float sx, float sy, float sz) {
        Matrix.scaleM(mMatrixValues, 0, sx, sy, sz);
    }

    @Override
    public void rotate(float angle, float x, float y, float z) {
        if (angle == 0) return;
        float[] temp = mTempMatrix;
        Matrix.setRotateM(temp, 0, angle, x, y, z);
        Matrix.multiplyMM(temp, 16, mMatrixValues, 0, temp, 0);
        System.arraycopy(temp, 16, mMatrixValues, 0, 16);
    }

    @Override
    public void multiplyMatrix(float matrix[], int offset) {
        float[] temp = mTempMatrix;
        Matrix.multiplyMM(temp, 0, mMatrixValues, 0, matrix, offset);
        System.arraycopy(temp, 0, mMatrixValues, 0, 16);
    }

    private void textureRect(float x, float y, float width, float height) {
        GL11 gl = mGL;

        saveTransform();
        translate(x, y);
        scale(width, height, 1);

        gl.glLoadMatrixf(mMatrixValues, 0);
        gl.glDrawArrays(GL11.GL_TRIANGLE_STRIP, OFFSET_FILL_RECT, 4);

        restoreTransform();
        mCountTextureRect++;
    }

    @Override
    public void drawMesh(BasicTexture tex, int x, int y, int xyBuffer,
            int uvBuffer, int indexBuffer, int indexCount) {
        float alpha = mAlpha;
        if (!bindTexture(tex)) return;

        mGLState.setBlendEnabled(mBlendEnabled
                && (!tex.isOpaque() || alpha < OPAQUE_ALPHA));
        mGLState.setTextureAlpha(alpha);

        // Reset the texture matrix. We will set our own texture coordinates
        // below.
        setTextureCoords(0, 0, 1, 1);

        saveTransform();
        translate(x, y);

        mGL.glLoadMatrixf(mMatrixValues, 0);

        mGL.glBindBuffer(GL11.GL_ARRAY_BUFFER, xyBuffer);
        mGL.glVertexPointer(2, GL11.GL_FLOAT, 0, 0);

        mGL.glBindBuffer(GL11.GL_ARRAY_BUFFER, uvBuffer);
        mGL.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0);

        mGL.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
        mGL.glDrawElements(GL11.GL_TRIANGLE_STRIP,
                indexCount, GL11.GL_UNSIGNED_BYTE, 0);

        mGL.glBindBuffer(GL11.GL_ARRAY_BUFFER, mBoxCoords);
        mGL.glVertexPointer(2, GL11.GL_FLOAT, 0, 0);
        mGL.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0);

        restoreTransform();
        mCountDrawMesh++;
    }

    // Transforms two points by the given matrix m. The result
    // {x1', y1', x2', y2'} are stored in mMapPointsBuffer and also returned.
    private float[] mapPoints(float m[], int x1, int y1, int x2, int y2) {
        float[] r = mMapPointsBuffer;

        // Multiply m and (x1 y1 0 1) to produce (x3 y3 z3 w3). z3 is unused.
        float x3 = m[0] * x1 + m[4] * y1 + m[12];
        float y3 = m[1] * x1 + m[5] * y1 + m[13];
        float w3 = m[3] * x1 + m[7] * y1 + m[15];
        r[0] = x3 / w3;
        r[1] = y3 / w3;

        // Same for x2 y2.
        float x4 = m[0] * x2 + m[4] * y2 + m[12];
        float y4 = m[1] * x2 + m[5] * y2 + m[13];
        float w4 = m[3] * x2 + m[7] * y2 + m[15];
        r[2] = x4 / w4;
        r[3] = y4 / w4;

        return r;
    }

    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)) {
            if (texture.hasBorder()) {
                setTextureCoords(
                        1.0f / texture.getTextureWidth(),
                        1.0f / texture.getTextureHeight(),
                        (texture.getWidth() - 1.0f) / texture.getTextureWidth(),
                        (texture.getHeight() - 1.0f) / texture.getTextureHeight());
            } else {
                setTextureCoords(0, 0,
                        (float) texture.getWidth() / texture.getTextureWidth(),
                        (float) texture.getHeight() / texture.getTextureHeight());
            }
            textureRect(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] + 0.5f);
            y = (int) (points[1] + 0.5f);
            width = (int) (points[2] + 0.5f) - x;
            height = (int) (points[3] + 0.5f) - y;
            if (width > 0 && height > 0) {
                ((GL11Ext) mGL).glDrawTexiOES(x, y, 0, width, height);
                mCountTextureOES++;
            }
        }
    }

    @Override
    public void drawTexture(
            BasicTexture texture, int x, int y, int width, int height) {
        drawTexture(texture, x, y, width, height, mAlpha);
    }

    private void drawTexture(BasicTexture texture,
            int x, int y, int width, int height, float alpha) {
        if (width <= 0 || height <= 0) return;

        mGLState.setBlendEnabled(mBlendEnabled
                && (!texture.isOpaque() || alpha < OPAQUE_ALPHA));
        if (!bindTexture(texture)) return;
        mGLState.setTextureAlpha(alpha);
        drawBoundTexture(texture, x, y, width, height);
    }

    @Override
    public void drawTexture(BasicTexture texture, RectF source, RectF target) {
        if (target.width() <= 0 || target.height() <= 0) return;

        // Copy the input to avoid changing it.
        mDrawTextureSourceRect.set(source);
        mDrawTextureTargetRect.set(target);
        source = mDrawTextureSourceRect;
        target = mDrawTextureTargetRect;

        mGLState.setBlendEnabled(mBlendEnabled
                && (!texture.isOpaque() || mAlpha < OPAQUE_ALPHA));
        if (!bindTexture(texture)) return;
        convertCoordinate(source, target, texture);
        setTextureCoords(source);
        mGLState.setTextureAlpha(mAlpha);
        textureRect(target.left, target.top, target.width(), target.height());
    }

    @Override
    public void drawTexture(BasicTexture texture, float[] mTextureTransform,
            int x, int y, int w, int h) {
        mGLState.setBlendEnabled(mBlendEnabled
                && (!texture.isOpaque() || mAlpha < OPAQUE_ALPHA));
        if (!bindTexture(texture)) return;
        setTextureCoords(mTextureTransform);
        mGLState.setTextureAlpha(mAlpha);
        textureRect(x, y, w, h);
    }

    // This function changes the source coordinate to the texture coordinates.
    // It also clips the source and target coordinates if it is beyond the
    // bound of the texture.
    private static void convertCoordinate(RectF source, RectF target,
            BasicTexture texture) {

        int width = texture.getWidth();
        int height = texture.getHeight();
        int texWidth = texture.getTextureWidth();
        int texHeight = texture.getTextureHeight();
        // Convert to texture coordinates
        source.left /= texWidth;
        source.right /= texWidth;
        source.top /= texHeight;
        source.bottom /= texHeight;

        // Clip if the rendering range is beyond the bound of the texture.
        float xBound = (float) width / texWidth;
        if (source.right > xBound) {
            target.right = target.left + target.width() *
                    (xBound - source.left) / source.width();
            source.right = xBound;
        }
        float yBound = (float) height / texHeight;
        if (source.bottom > yBound) {
            target.bottom = target.top + target.height() *
                    (yBound - source.top) / source.height();
            source.bottom = yBound;
        }
    }

    @Override
    public void drawMixed(BasicTexture from,
            int toColor, float ratio, int x, int y, int w, int h) {
        drawMixed(from, toColor, ratio, x, y, w, h, mAlpha);
    }

    private boolean bindTexture(BasicTexture texture) {
        if (!texture.onBind(this)) return false;
        int target = texture.getTarget();
        mGLState.setTextureTarget(target);
        mGL.glBindTexture(target, texture.getId());
        return true;
    }

    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;
    }

    private void setMixedColor(int toColor, float ratio, float alpha) {
        //
        // The formula we want:
        //     alpha * ((1 - ratio) * from + ratio * to)
        //
        // The formula that GL supports is in the form of:
        //     combo * from + (1 - combo) * to * scale
        //
        // So, we have combo = alpha * (1 - ratio)
        //     and     scale = alpha * ratio / (1 - combo)
        //
        float combo = alpha * (1 - ratio);
        float scale = alpha * ratio / (1 - combo);

        // Specify the interpolation factor via the alpha component of
        // GL_TEXTURE_ENV_COLORs.
        // RGB component are get from toColor and will used as SRC1
        float colorScale = scale * (toColor >>> 24) / (0xff * 0xff);
        setTextureColor(((toColor >>> 16) & 0xff) * colorScale,
                ((toColor >>> 8) & 0xff) * colorScale,
                (toColor & 0xff) * colorScale, combo);
        GL11 gl = mGL;
        gl.glTexEnvfv(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_COLOR, mTextureColor, 0);

        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);
        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC1_RGB, GL11.GL_CONSTANT);
        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND1_RGB, GL11.GL_SRC_COLOR);
        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC1_ALPHA, GL11.GL_CONSTANT);
        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND1_ALPHA, GL11.GL_SRC_ALPHA);

        // 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);

    }

    @Override
    public void drawMixed(BasicTexture from, int toColor, float ratio,
            RectF source, RectF target) {
        if (target.width() <= 0 || target.height() <= 0) return;

        if (ratio <= 0.01f) {
            drawTexture(from, source, target);
            return;
        } else if (ratio >= 1) {
            fillRect(target.left, target.top, target.width(), target.height(), toColor);
            return;
        }

        float alpha = mAlpha;

        // Copy the input to avoid changing it.
        mDrawTextureSourceRect.set(source);
        mDrawTextureTargetRect.set(target);
        source = mDrawTextureSourceRect;
        target = mDrawTextureTargetRect;

        mGLState.setBlendEnabled(mBlendEnabled && (!from.isOpaque()
                || !Utils.isOpaque(toColor) || alpha < OPAQUE_ALPHA));

        if (!bindTexture(from)) return;

        // Interpolate the RGB and alpha values between both textures.
        mGLState.setTexEnvMode(GL11.GL_COMBINE);
        setMixedColor(toColor, ratio, alpha);
        convertCoordinate(source, target, from);
        setTextureCoords(source);
        textureRect(target.left, target.top, target.width(), target.height());
        mGLState.setTexEnvMode(GL11.GL_REPLACE);
    }

    private void drawMixed(BasicTexture from, int toColor,
            float ratio, int x, int y, int width, int height, float alpha) {
        // change from 0 to 0.01f to prevent getting divided by zero below
        if (ratio <= 0.01f) {
            drawTexture(from, x, y, width, height, alpha);
            return;
        } else if (ratio >= 1) {
            fillRect(x, y, width, height, toColor);
            return;
        }

        mGLState.setBlendEnabled(mBlendEnabled && (!from.isOpaque()
                || !Utils.isOpaque(toColor) || alpha < OPAQUE_ALPHA));

        final GL11 gl = mGL;
        if (!bindTexture(from)) return;

        // Interpolate the RGB and alpha values between both textures.
        mGLState.setTexEnvMode(GL11.GL_COMBINE);
        setMixedColor(toColor, ratio, alpha);

        drawBoundTexture(from, x, y, width, height);
        mGLState.setTexEnvMode(GL11.GL_REPLACE);
    }

    // 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[]) {
        final float eps = 1e-5f;
        return Math.abs(matrix[MSKEW_X]) > eps
                || Math.abs(matrix[MSKEW_Y]) > eps
                || matrix[MSCALE_X] < -eps
                || matrix[MSCALE_Y] > eps;
    }

    private static class GLState {

        private final GL11 mGL;

        private int mTexEnvMode = GL11.GL_REPLACE;
        private float mTextureAlpha = 1.0f;
        private int mTextureTarget = GL11.GL_TEXTURE_2D;
        private boolean mBlendEnabled = true;
        private float mLineWidth = 1.0f;
        private boolean mLineSmooth = false;

        public GLState(GL11 gl) {
            mGL = gl;

            // Disable unused state
            gl.glDisable(GL11.GL_LIGHTING);

            // Enable used features
            gl.glEnable(GL11.GL_DITHER);

            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.glEnable(GL11.GL_BLEND);
            gl.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);

            // We use 565 or 8888 format, so set the alignment to 2 bytes/pixel.
            gl.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 2);
        }

        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 setLineWidth(float width) {
            if (mLineWidth == width) return;
            mLineWidth = width;
            mGL.glLineWidth(width);
        }

        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 setColorMode(int color, float alpha) {
            setBlendEnabled(!Utils.isOpaque(color) || alpha < OPAQUE_ALPHA);

            // Set mTextureAlpha to an invalid value, so that it will reset
            // again in setTextureAlpha(float) later.
            mTextureAlpha = -1.0f;

            setTextureTarget(0);

            float prealpha = (color >>> 24) * alpha * 65535f / 255f / 255f;
            mGL.glColor4x(
                    Math.round(((color >> 16) & 0xFF) * prealpha),
                    Math.round(((color >> 8) & 0xFF) * prealpha),
                    Math.round((color & 0xFF) * prealpha),
                    Math.round(255 * prealpha));
        }

        // target is a value like GL_TEXTURE_2D. If target = 0, texturing is disabled.
        public void setTextureTarget(int target) {
            if (mTextureTarget == target) return;
            if (mTextureTarget != 0) {
                mGL.glDisable(mTextureTarget);
            }
            mTextureTarget = target;
            if (mTextureTarget != 0) {
                mGL.glEnable(mTextureTarget);
            }
        }

        public void setBlendEnabled(boolean enabled) {
            if (mBlendEnabled == enabled) return;
            mBlendEnabled = enabled;
            if (enabled) {
                mGL.glEnable(GL11.GL_BLEND);
            } else {
                mGL.glDisable(GL11.GL_BLEND);
            }
        }
    }

    @Override
    public void clearBuffer(float[] argb) {
        if(argb != null && argb.length == 4) {
            mGL.glClearColor(argb[1], argb[2], argb[3], argb[0]);
        } else {
            mGL.glClearColor(0, 0, 0, 1);
        }
        mGL.glClear(GL10.GL_COLOR_BUFFER_BIT);
    }

    @Override
    public void clearBuffer() {
        clearBuffer(null);
    }

    private void setTextureCoords(RectF source) {
        setTextureCoords(source.left, source.top, source.right, source.bottom);
    }

    private void setTextureCoords(float left, float top,
            float right, float bottom) {
        mGL.glMatrixMode(GL11.GL_TEXTURE);
        mTextureMatrixValues[0] = right - left;
        mTextureMatrixValues[5] = bottom - top;
        mTextureMatrixValues[10] = 1;
        mTextureMatrixValues[12] = left;
        mTextureMatrixValues[13] = top;
        mTextureMatrixValues[15] = 1;
        mGL.glLoadMatrixf(mTextureMatrixValues, 0);
        mGL.glMatrixMode(GL11.GL_MODELVIEW);
    }

    private void setTextureCoords(float[] mTextureTransform) {
        mGL.glMatrixMode(GL11.GL_TEXTURE);
        mGL.glLoadMatrixf(mTextureTransform, 0);
        mGL.glMatrixMode(GL11.GL_MODELVIEW);
    }

    // unloadTexture and deleteBuffer can be called from the finalizer thread,
    // so we synchronized on the mUnboundTextures object.
    @Override
    public boolean unloadTexture(BasicTexture t) {
        synchronized (mUnboundTextures) {
            if (!t.isLoaded()) return false;
            mUnboundTextures.add(t.mId);
            return true;
        }
    }

    @Override
    public void deleteBuffer(int bufferId) {
        synchronized (mUnboundTextures) {
            mDeleteBuffers.add(bufferId);
        }
    }

    @Override
    public void deleteRecycledResources() {
        synchronized (mUnboundTextures) {
            IntArray ids = mUnboundTextures;
            if (ids.size() > 0) {
                mGLId.glDeleteTextures(mGL, ids.size(), ids.getInternalArray(), 0);
                ids.clear();
            }

            ids = mDeleteBuffers;
            if (ids.size() > 0) {
                mGLId.glDeleteBuffers(mGL, ids.size(), ids.getInternalArray(), 0);
                ids.clear();
            }
        }
    }

    @Override
    public void save() {
        save(SAVE_FLAG_ALL);
    }

    @Override
    public void save(int saveFlags) {
        ConfigState config = obtainRestoreConfig();

        if ((saveFlags & SAVE_FLAG_ALPHA) != 0) {
            config.mAlpha = mAlpha;
        } else {
            config.mAlpha = -1;
        }

        if ((saveFlags & SAVE_FLAG_MATRIX) != 0) {
            System.arraycopy(mMatrixValues, 0, config.mMatrix, 0, 16);
        } else {
            config.mMatrix[0] = Float.NEGATIVE_INFINITY;
        }

        mRestoreStack.add(config);
    }

    @Override
    public void restore() {
        if (mRestoreStack.isEmpty()) throw new IllegalStateException();
        ConfigState config = mRestoreStack.remove(mRestoreStack.size() - 1);
        config.restore(this);
        freeRestoreConfig(config);
    }

    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;
        float mMatrix[] = new float[16];
        ConfigState mNextFree;

        public void restore(GLES11Canvas canvas) {
            if (mAlpha >= 0) canvas.setAlpha(mAlpha);
            if (mMatrix[0] != Float.NEGATIVE_INFINITY) {
                System.arraycopy(mMatrix, 0, canvas.mMatrixValues, 0, 16);
            }
        }
    }

    @Override
    public void dumpStatisticsAndClear() {
        String line = String.format(
                "MESH:%d, TEX_OES:%d, TEX_RECT:%d, FILL_RECT:%d, LINE:%d",
                mCountDrawMesh, mCountTextureRect, mCountTextureOES,
                mCountFillRect, mCountDrawLine);
        mCountDrawMesh = 0;
        mCountTextureRect = 0;
        mCountTextureOES = 0;
        mCountFillRect = 0;
        mCountDrawLine = 0;
        Log.d(TAG, line);
    }

    private void saveTransform() {
        System.arraycopy(mMatrixValues, 0, mTempMatrix, 0, 16);
    }

    private void restoreTransform() {
        System.arraycopy(mTempMatrix, 0, mMatrixValues, 0, 16);
    }

    private void setRenderTarget(RawTexture texture) {
        GL11ExtensionPack gl11ep = (GL11ExtensionPack) mGL;

        if (mTargetTexture == null && texture != null) {
            mGLId.glGenBuffers(1, mFrameBuffer, 0);
            gl11ep.glBindFramebufferOES(
                    GL11ExtensionPack.GL_FRAMEBUFFER_OES, mFrameBuffer[0]);
        }
        if (mTargetTexture != null && texture  == null) {
            gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, 0);
            gl11ep.glDeleteFramebuffersOES(1, mFrameBuffer, 0);
        }

        mTargetTexture = texture;
        if (texture == null) {
            setSize(mScreenWidth, mScreenHeight);
        } else {
            setSize(texture.getWidth(), texture.getHeight());

            if (!texture.isLoaded()) texture.prepare(this);

            gl11ep.glFramebufferTexture2DOES(
                    GL11ExtensionPack.GL_FRAMEBUFFER_OES,
                    GL11ExtensionPack.GL_COLOR_ATTACHMENT0_OES,
                    GL11.GL_TEXTURE_2D, texture.getId(), 0);

            checkFramebufferStatus(gl11ep);
        }
    }

    @Override
    public void endRenderTarget() {
        RawTexture texture = mTargetStack.remove(mTargetStack.size() - 1);
        setRenderTarget(texture);
        restore(); // restore matrix and alpha
    }

    @Override
    public void beginRenderTarget(RawTexture texture) {
        save(); // save matrix and alpha
        mTargetStack.add(mTargetTexture);
        setRenderTarget(texture);
    }

    private static void checkFramebufferStatus(GL11ExtensionPack gl11ep) {
        int status = gl11ep.glCheckFramebufferStatusOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES);
        if (status != GL11ExtensionPack.GL_FRAMEBUFFER_COMPLETE_OES) {
            String msg = "";
            switch (status) {
                case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES:
                    msg = "FRAMEBUFFER_FORMATS";
                    break;
                case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES:
                    msg = "FRAMEBUFFER_ATTACHMENT";
                    break;
                case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES:
                    msg = "FRAMEBUFFER_MISSING_ATTACHMENT";
                    break;
                case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES:
                    msg = "FRAMEBUFFER_DRAW_BUFFER";
                    break;
                case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES:
                    msg = "FRAMEBUFFER_READ_BUFFER";
                    break;
                case GL11ExtensionPack.GL_FRAMEBUFFER_UNSUPPORTED_OES:
                    msg = "FRAMEBUFFER_UNSUPPORTED";
                    break;
                case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES:
                    msg = "FRAMEBUFFER_INCOMPLETE_DIMENSIONS";
                    break;
            }
            throw new RuntimeException(msg + ":" + Integer.toHexString(status));
        }
    }

    @Override
    public void setTextureParameters(BasicTexture texture) {
        int width = texture.getWidth();
        int height = texture.getHeight();
        // Define a vertically flipped crop rectangle for OES_draw_texture.
        // The four values in sCropRect are: left, bottom, width, and
        // height. Negative value of width or height means flip.
        sCropRect[0] = 0;
        sCropRect[1] = height;
        sCropRect[2] = width;
        sCropRect[3] = -height;

        // Set texture parameters.
        int target = texture.getTarget();
        mGL.glBindTexture(target, texture.getId());
        mGL.glTexParameterfv(target, GL11Ext.GL_TEXTURE_CROP_RECT_OES, sCropRect, 0);
        mGL.glTexParameteri(target, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP_TO_EDGE);
        mGL.glTexParameteri(target, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP_TO_EDGE);
        mGL.glTexParameterf(target, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
        mGL.glTexParameterf(target, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
    }

    @Override
    public void initializeTextureSize(BasicTexture texture, int format, int type) {
        int target = texture.getTarget();
        mGL.glBindTexture(target, texture.getId());
        int width = texture.getTextureWidth();
        int height = texture.getTextureHeight();
        mGL.glTexImage2D(target, 0, format, width, height, 0, format, type, null);
    }

    @Override
    public void initializeTexture(BasicTexture texture, Bitmap bitmap) {
        int target = texture.getTarget();
        mGL.glBindTexture(target, texture.getId());
        GLUtils.texImage2D(target, 0, bitmap, 0);
    }

    @Override
    public void texSubImage2D(BasicTexture texture, int xOffset, int yOffset, Bitmap bitmap,
            int format, int type) {
        int target = texture.getTarget();
        mGL.glBindTexture(target, texture.getId());
        GLUtils.texSubImage2D(target, 0, xOffset, yOffset, bitmap, format, type);
    }

    @Override
    public int uploadBuffer(FloatBuffer buf) {
        return uploadBuffer(buf, Float.SIZE / Byte.SIZE);
    }

    @Override
    public int uploadBuffer(ByteBuffer buf) {
        return uploadBuffer(buf, 1);
    }

    private int uploadBuffer(Buffer buf, int elementSize) {
        int[] bufferIds = new int[1];
        mGLId.glGenBuffers(bufferIds.length, bufferIds, 0);
        int bufferId = bufferIds[0];
        mGL.glBindBuffer(GL11.GL_ARRAY_BUFFER, bufferId);
        mGL.glBufferData(GL11.GL_ARRAY_BUFFER, buf.capacity() * elementSize, buf,
                GL11.GL_STATIC_DRAW);
        return bufferId;
    }

    @Override
    public void recoverFromLightCycle() {
        // This is only required for GLES20
    }

    @Override
    public void getBounds(Rect bounds, int x, int y, int width, int height) {
        // This is only required for GLES20
    }

    @Override
    public GLId getGLId() {
        return mGLId;
    }
}
