Removing some unused code in GLCanvas
Change-Id: Icd421dd16c82275f0ac1a6881d1d86b9c1eaf1e8
This commit is contained in:
@@ -46,8 +46,6 @@ public abstract class BasicTexture implements Texture {
|
||||
protected int mTextureWidth;
|
||||
protected int mTextureHeight;
|
||||
|
||||
private boolean mHasBorder;
|
||||
|
||||
protected GLCanvas mCanvasRef = null;
|
||||
private static WeakHashMap<BasicTexture, Object> sAllTextures
|
||||
= new WeakHashMap<BasicTexture, Object>();
|
||||
@@ -85,10 +83,6 @@ public abstract class BasicTexture implements Texture {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFlippedVertically() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return mId;
|
||||
}
|
||||
@@ -113,25 +107,6 @@ public abstract class BasicTexture implements Texture {
|
||||
return mTextureHeight;
|
||||
}
|
||||
|
||||
// Returns true if the texture has one pixel transparent border around the
|
||||
// actual content. This is used to avoid jigged edges.
|
||||
//
|
||||
// The jigged edges appear because we use GL_CLAMP_TO_EDGE for texture wrap
|
||||
// mode (GL_CLAMP is not available in OpenGL ES), so a pixel partially
|
||||
// covered by the texture will use the color of the edge texel. If we add
|
||||
// the transparent border, the color of the edge texel will be mixed with
|
||||
// appropriate amount of transparent.
|
||||
//
|
||||
// Currently our background is black, so we can draw the thumbnails without
|
||||
// enabling blending.
|
||||
public boolean hasBorder() {
|
||||
return mHasBorder;
|
||||
}
|
||||
|
||||
protected void setBorder(boolean hasBorder) {
|
||||
mHasBorder = hasBorder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(GLCanvas canvas, int x, int y) {
|
||||
canvas.drawTexture(this, x, y, getWidth(), getHeight());
|
||||
@@ -146,9 +121,6 @@ public abstract class BasicTexture implements Texture {
|
||||
// It should make sure the data is uploaded to GL memory.
|
||||
abstract protected boolean onBind(GLCanvas canvas);
|
||||
|
||||
// Returns the GL texture target for this texture (e.g. GL_TEXTURE_2D).
|
||||
abstract protected int getTarget();
|
||||
|
||||
public boolean isLoaded() {
|
||||
return mState == STATE_LOADED;
|
||||
}
|
||||
@@ -185,13 +157,6 @@ public abstract class BasicTexture implements Texture {
|
||||
sInFinalizer.set(null);
|
||||
}
|
||||
|
||||
// This is for deciding if we can call Bitmap's recycle().
|
||||
// We cannot call Bitmap's recycle() in finalizer because at that point
|
||||
// the finalizer of Bitmap may already be called so recycle() will crash.
|
||||
public static boolean inFinalizer() {
|
||||
return sInFinalizer.get() != null;
|
||||
}
|
||||
|
||||
public static void yieldAllTextures() {
|
||||
synchronized (sAllTextures) {
|
||||
for (BasicTexture t : sAllTextures.keySet()) {
|
||||
|
||||
@@ -29,11 +29,7 @@ public class BitmapTexture extends UploadedTexture {
|
||||
protected Bitmap mContentBitmap;
|
||||
|
||||
public BitmapTexture(Bitmap bitmap) {
|
||||
this(bitmap, false);
|
||||
}
|
||||
|
||||
public BitmapTexture(Bitmap bitmap, boolean hasBorder) {
|
||||
super(hasBorder);
|
||||
super();
|
||||
Utils.assertTrue(bitmap != null && !bitmap.isRecycled());
|
||||
mContentBitmap = bitmap;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.android.gallery3d.glrenderer;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
|
||||
//
|
||||
@@ -40,36 +39,14 @@ public interface GLCanvas {
|
||||
// Clear the drawing buffers. This should only be used by GLRoot.
|
||||
public abstract void clearBuffer();
|
||||
|
||||
public abstract void clearBuffer(float[] argb);
|
||||
|
||||
// Sets and gets the current alpha, alpha must be in [0, 1].
|
||||
public abstract void setAlpha(float alpha);
|
||||
|
||||
public abstract float getAlpha();
|
||||
|
||||
// (current alpha) = (current alpha) * alpha
|
||||
public abstract void multiplyAlpha(float alpha);
|
||||
|
||||
// Change the current transform matrix.
|
||||
public abstract void translate(float x, float y, float z);
|
||||
|
||||
public abstract void translate(float x, float y);
|
||||
|
||||
public abstract void scale(float sx, float sy, float sz);
|
||||
|
||||
public abstract void rotate(float angle, float x, float y, float z);
|
||||
|
||||
public abstract void multiplyMatrix(float[] mMatrix, int offset);
|
||||
|
||||
// Pushes the configuration state (matrix, and alpha) onto
|
||||
// a private stack.
|
||||
public abstract void save();
|
||||
|
||||
// Same as save(), but only save those specified in saveFlags.
|
||||
public abstract void save(int saveFlags);
|
||||
|
||||
public static final int SAVE_FLAG_ALL = 0xFFFFFFFF;
|
||||
public static final int SAVE_FLAG_ALPHA = 0x01;
|
||||
public static final int SAVE_FLAG_MATRIX = 0x02;
|
||||
|
||||
// Pops from the top of the stack as current configuration state (matrix,
|
||||
@@ -78,64 +55,22 @@ public interface GLCanvas {
|
||||
// last save call.
|
||||
public abstract void restore();
|
||||
|
||||
// Draws a line using the specified paint from (x1, y1) to (x2, y2).
|
||||
// (Both end points are included).
|
||||
public abstract void drawLine(float x1, float y1, float x2, float y2, GLPaint paint);
|
||||
|
||||
// Draws a rectangle using the specified paint from (x1, y1) to (x2, y2).
|
||||
// (Both end points are included).
|
||||
public abstract void drawRect(float x1, float y1, float x2, float y2, GLPaint paint);
|
||||
|
||||
// Fills the specified rectangle with the specified color.
|
||||
public abstract void fillRect(float x, float y, float width, float height, int color);
|
||||
|
||||
// Draws a texture to the specified rectangle.
|
||||
public abstract void drawTexture(
|
||||
BasicTexture texture, int x, int y, int width, int height);
|
||||
|
||||
public abstract void drawMesh(BasicTexture tex, int x, int y, int xyBuffer,
|
||||
int uvBuffer, int indexBuffer, int indexCount);
|
||||
public abstract void drawTexture(BasicTexture texture, int x, int y, int width, int height);
|
||||
|
||||
// Draws the source rectangle part of the texture to the target rectangle.
|
||||
public abstract void drawTexture(BasicTexture texture, RectF source, RectF target);
|
||||
|
||||
// Draw a texture with a specified texture transform.
|
||||
public abstract void drawTexture(BasicTexture texture, float[] mTextureTransform,
|
||||
int x, int y, int w, int h);
|
||||
|
||||
// Draw two textures to the specified rectangle. The actual texture used is
|
||||
// from * (1 - ratio) + to * ratio
|
||||
// The two textures must have the same size.
|
||||
public abstract void drawMixed(BasicTexture from, int toColor,
|
||||
float ratio, int x, int y, int w, int h);
|
||||
|
||||
// Draw a region of a texture and a specified color to the specified
|
||||
// rectangle. The actual color used is from * (1 - ratio) + to * ratio.
|
||||
// The region of the texture is defined by parameter "src". The target
|
||||
// rectangle is specified by parameter "target".
|
||||
public abstract void drawMixed(BasicTexture from, int toColor,
|
||||
float ratio, RectF src, RectF target);
|
||||
|
||||
// Unloads the specified texture from the canvas. The resource allocated
|
||||
// to draw the texture will be released. The specified texture will return
|
||||
// to the unloaded state. This function should be called only from
|
||||
// BasicTexture or its descendant
|
||||
public abstract boolean unloadTexture(BasicTexture texture);
|
||||
|
||||
// Delete the specified buffer object, similar to unloadTexture.
|
||||
public abstract void deleteBuffer(int bufferId);
|
||||
|
||||
// Delete the textures and buffers in GL side. This function should only be
|
||||
// called in the GL thread.
|
||||
public abstract void deleteRecycledResources();
|
||||
|
||||
// Dump statistics information and clear the counters. For debug only.
|
||||
public abstract void dumpStatisticsAndClear();
|
||||
|
||||
public abstract void beginRenderTarget(RawTexture texture);
|
||||
|
||||
public abstract void endRenderTarget();
|
||||
|
||||
/**
|
||||
* Sets texture parameters to use GL_CLAMP_TO_EDGE for both
|
||||
* GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T. Sets texture parameters to be
|
||||
@@ -185,31 +120,4 @@ public interface GLCanvas {
|
||||
* @return The buffer ID that was generated.
|
||||
*/
|
||||
public abstract int uploadBuffer(java.nio.FloatBuffer buffer);
|
||||
|
||||
/**
|
||||
* Generates buffers and uploads the element array buffer data.
|
||||
*
|
||||
* @param buffer The buffer to upload
|
||||
* @return The buffer ID that was generated.
|
||||
*/
|
||||
public abstract int uploadBuffer(java.nio.ByteBuffer buffer);
|
||||
|
||||
/**
|
||||
* After LightCycle makes GL calls, this method is called to restore the GL
|
||||
* configuration to the one expected by GLCanvas.
|
||||
*/
|
||||
public abstract void recoverFromLightCycle();
|
||||
|
||||
/**
|
||||
* Gets the bounds given by x, y, width, and height as well as the internal
|
||||
* matrix state. There is no special handling for non-90-degree rotations.
|
||||
* It only considers the lower-left and upper-right corners as the bounds.
|
||||
*
|
||||
* @param bounds The output bounds to write to.
|
||||
* @param x The left side of the input rectangle.
|
||||
* @param y The bottom of the input rectangle.
|
||||
* @param width The width of the input rectangle.
|
||||
* @param height The height of the input rectangle.
|
||||
*/
|
||||
public abstract void getBounds(Rect bounds, int x, int y, int width, int height);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package com.android.gallery3d.glrenderer;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.opengl.GLES20;
|
||||
import android.opengl.GLUtils;
|
||||
@@ -27,24 +26,22 @@ import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.microedition.khronos.opengles.GL11;
|
||||
|
||||
public class GLES20Canvas implements GLCanvas {
|
||||
// ************** Constants **********************
|
||||
private static final String TAG = GLES20Canvas.class.getSimpleName();
|
||||
private static final int FLOAT_SIZE = Float.SIZE / Byte.SIZE;
|
||||
private static final float OPAQUE_ALPHA = 0.95f;
|
||||
|
||||
private static final int COORDS_PER_VERTEX = 2;
|
||||
private static final int VERTEX_STRIDE = COORDS_PER_VERTEX * FLOAT_SIZE;
|
||||
|
||||
private static final int COUNT_FILL_VERTEX = 4;
|
||||
private static final int COUNT_LINE_VERTEX = 2;
|
||||
private static final int COUNT_RECT_VERTEX = 4;
|
||||
private static final int OFFSET_FILL_RECT = 0;
|
||||
private static final int OFFSET_DRAW_LINE = OFFSET_FILL_RECT + COUNT_FILL_VERTEX;
|
||||
private static final int OFFSET_DRAW_RECT = OFFSET_DRAW_LINE + COUNT_LINE_VERTEX;
|
||||
|
||||
private static final int GL_TARGET = GL11.GL_TEXTURE_2D;
|
||||
|
||||
private static final float[] BOX_COORDINATES = {
|
||||
0, 0, // Fill rectangle
|
||||
@@ -59,33 +56,11 @@ public class GLES20Canvas implements GLCanvas {
|
||||
1, 0,
|
||||
};
|
||||
|
||||
private static final float[] BOUNDS_COORDINATES = {
|
||||
0, 0, 0, 1,
|
||||
1, 1, 0, 1,
|
||||
};
|
||||
|
||||
private static final String POSITION_ATTRIBUTE = "aPosition";
|
||||
private static final String COLOR_UNIFORM = "uColor";
|
||||
private static final String MATRIX_UNIFORM = "uMatrix";
|
||||
private static final String TEXTURE_MATRIX_UNIFORM = "uTextureMatrix";
|
||||
private static final String TEXTURE_SAMPLER_UNIFORM = "uTextureSampler";
|
||||
private static final String ALPHA_UNIFORM = "uAlpha";
|
||||
private static final String TEXTURE_COORD_ATTRIBUTE = "aTextureCoordinate";
|
||||
|
||||
private static final String DRAW_VERTEX_SHADER = ""
|
||||
+ "uniform mat4 " + MATRIX_UNIFORM + ";\n"
|
||||
+ "attribute vec2 " + POSITION_ATTRIBUTE + ";\n"
|
||||
+ "void main() {\n"
|
||||
+ " vec4 pos = vec4(" + POSITION_ATTRIBUTE + ", 0.0, 1.0);\n"
|
||||
+ " gl_Position = " + MATRIX_UNIFORM + " * pos;\n"
|
||||
+ "}\n";
|
||||
|
||||
private static final String DRAW_FRAGMENT_SHADER = ""
|
||||
+ "precision mediump float;\n"
|
||||
+ "uniform vec4 " + COLOR_UNIFORM + ";\n"
|
||||
+ "void main() {\n"
|
||||
+ " gl_FragColor = " + COLOR_UNIFORM + ";\n"
|
||||
+ "}\n";
|
||||
|
||||
private static final String TEXTURE_VERTEX_SHADER = ""
|
||||
+ "uniform mat4 " + MATRIX_UNIFORM + ";\n"
|
||||
@@ -98,17 +73,6 @@ public class GLES20Canvas implements GLCanvas {
|
||||
+ " vTextureCoord = (" + TEXTURE_MATRIX_UNIFORM + " * pos).xy;\n"
|
||||
+ "}\n";
|
||||
|
||||
private static final String MESH_VERTEX_SHADER = ""
|
||||
+ "uniform mat4 " + MATRIX_UNIFORM + ";\n"
|
||||
+ "attribute vec2 " + POSITION_ATTRIBUTE + ";\n"
|
||||
+ "attribute vec2 " + TEXTURE_COORD_ATTRIBUTE + ";\n"
|
||||
+ "varying vec2 vTextureCoord;\n"
|
||||
+ "void main() {\n"
|
||||
+ " vec4 pos = vec4(" + POSITION_ATTRIBUTE + ", 0.0, 1.0);\n"
|
||||
+ " gl_Position = " + MATRIX_UNIFORM + " * pos;\n"
|
||||
+ " vTextureCoord = " + TEXTURE_COORD_ATTRIBUTE + ";\n"
|
||||
+ "}\n";
|
||||
|
||||
private static final String TEXTURE_FRAGMENT_SHADER = ""
|
||||
+ "precision mediump float;\n"
|
||||
+ "varying vec2 vTextureCoord;\n"
|
||||
@@ -119,26 +83,13 @@ public class GLES20Canvas implements GLCanvas {
|
||||
+ " gl_FragColor *= " + ALPHA_UNIFORM + ";\n"
|
||||
+ "}\n";
|
||||
|
||||
private static final String OES_TEXTURE_FRAGMENT_SHADER = ""
|
||||
+ "#extension GL_OES_EGL_image_external : require\n"
|
||||
+ "precision mediump float;\n"
|
||||
+ "varying vec2 vTextureCoord;\n"
|
||||
+ "uniform float " + ALPHA_UNIFORM + ";\n"
|
||||
+ "uniform samplerExternalOES " + TEXTURE_SAMPLER_UNIFORM + ";\n"
|
||||
+ "void main() {\n"
|
||||
+ " gl_FragColor = texture2D(" + TEXTURE_SAMPLER_UNIFORM + ", vTextureCoord);\n"
|
||||
+ " gl_FragColor *= " + ALPHA_UNIFORM + ";\n"
|
||||
+ "}\n";
|
||||
|
||||
private static final int INITIAL_RESTORE_STATE_SIZE = 8;
|
||||
private static final int MATRIX_SIZE = 16;
|
||||
|
||||
// Keep track of restore state
|
||||
private float[] mMatrices = new float[INITIAL_RESTORE_STATE_SIZE * MATRIX_SIZE];
|
||||
private float[] mAlphas = new float[INITIAL_RESTORE_STATE_SIZE];
|
||||
private IntArray mSaveFlags = new IntArray();
|
||||
|
||||
private int mCurrentAlphaIndex = 0;
|
||||
private int mCurrentMatrixIndex = 0;
|
||||
|
||||
// Viewport size
|
||||
@@ -148,15 +99,8 @@ public class GLES20Canvas implements GLCanvas {
|
||||
// Projection matrix
|
||||
private float[] mProjectionMatrix = new float[MATRIX_SIZE];
|
||||
|
||||
// Screen size for when we aren't bound to a texture
|
||||
private int mScreenWidth;
|
||||
private int mScreenHeight;
|
||||
|
||||
// GL programs
|
||||
private int mDrawProgram;
|
||||
private int mTextureProgram;
|
||||
private int mOesTextureProgram;
|
||||
private int mMeshProgram;
|
||||
|
||||
// GL buffer containing BOX_COORDINATES
|
||||
private int mBoxCoordinates;
|
||||
@@ -165,17 +109,11 @@ public class GLES20Canvas implements GLCanvas {
|
||||
private static final int INDEX_POSITION = 0;
|
||||
private static final int INDEX_MATRIX = 1;
|
||||
|
||||
// Handle indices -- draw
|
||||
private static final int INDEX_COLOR = 2;
|
||||
|
||||
// Handle indices -- texture
|
||||
private static final int INDEX_TEXTURE_MATRIX = 2;
|
||||
private static final int INDEX_TEXTURE_SAMPLER = 3;
|
||||
private static final int INDEX_ALPHA = 4;
|
||||
|
||||
// Handle indices -- mesh
|
||||
private static final int INDEX_TEXTURE_COORD = 2;
|
||||
|
||||
private abstract static class ShaderParameter {
|
||||
public int handle;
|
||||
protected final String mName;
|
||||
@@ -211,52 +149,18 @@ public class GLES20Canvas implements GLCanvas {
|
||||
}
|
||||
}
|
||||
|
||||
ShaderParameter[] mDrawParameters = {
|
||||
new AttributeShaderParameter(POSITION_ATTRIBUTE), // INDEX_POSITION
|
||||
new UniformShaderParameter(MATRIX_UNIFORM), // INDEX_MATRIX
|
||||
new UniformShaderParameter(COLOR_UNIFORM), // INDEX_COLOR
|
||||
};
|
||||
ShaderParameter[] mTextureParameters = {
|
||||
private ShaderParameter[] mTextureParameters = {
|
||||
new AttributeShaderParameter(POSITION_ATTRIBUTE), // INDEX_POSITION
|
||||
new UniformShaderParameter(MATRIX_UNIFORM), // INDEX_MATRIX
|
||||
new UniformShaderParameter(TEXTURE_MATRIX_UNIFORM), // INDEX_TEXTURE_MATRIX
|
||||
new UniformShaderParameter(TEXTURE_SAMPLER_UNIFORM), // INDEX_TEXTURE_SAMPLER
|
||||
new UniformShaderParameter(ALPHA_UNIFORM), // INDEX_ALPHA
|
||||
};
|
||||
ShaderParameter[] mOesTextureParameters = {
|
||||
new AttributeShaderParameter(POSITION_ATTRIBUTE), // INDEX_POSITION
|
||||
new UniformShaderParameter(MATRIX_UNIFORM), // INDEX_MATRIX
|
||||
new UniformShaderParameter(TEXTURE_MATRIX_UNIFORM), // INDEX_TEXTURE_MATRIX
|
||||
new UniformShaderParameter(TEXTURE_SAMPLER_UNIFORM), // INDEX_TEXTURE_SAMPLER
|
||||
new UniformShaderParameter(ALPHA_UNIFORM), // INDEX_ALPHA
|
||||
};
|
||||
ShaderParameter[] mMeshParameters = {
|
||||
new AttributeShaderParameter(POSITION_ATTRIBUTE), // INDEX_POSITION
|
||||
new UniformShaderParameter(MATRIX_UNIFORM), // INDEX_MATRIX
|
||||
new AttributeShaderParameter(TEXTURE_COORD_ATTRIBUTE), // INDEX_TEXTURE_COORD
|
||||
new UniformShaderParameter(TEXTURE_SAMPLER_UNIFORM), // INDEX_TEXTURE_SAMPLER
|
||||
new UniformShaderParameter(ALPHA_UNIFORM), // INDEX_ALPHA
|
||||
};
|
||||
|
||||
private final IntArray mUnboundTextures = new IntArray();
|
||||
private final IntArray mDeleteBuffers = new IntArray();
|
||||
|
||||
// Keep track of statistics for debugging
|
||||
private int mCountDrawMesh = 0;
|
||||
private int mCountTextureRect = 0;
|
||||
private int mCountFillRect = 0;
|
||||
private int mCountDrawLine = 0;
|
||||
|
||||
// Buffer for framebuffer IDs -- we keep track so we can switch the attached
|
||||
// texture.
|
||||
private int[] mFrameBuffer = new int[1];
|
||||
|
||||
// Bound textures.
|
||||
private ArrayList<RawTexture> mTargetTextures = new ArrayList<RawTexture>();
|
||||
|
||||
// Temporary variables used within calculations
|
||||
private final float[] mTempMatrix = new float[32];
|
||||
private final float[] mTempColor = new float[4];
|
||||
private final RectF mTempSourceRect = new RectF();
|
||||
private final RectF mTempTargetRect = new RectF();
|
||||
private final float[] mTempTextureMatrix = new float[MATRIX_SIZE];
|
||||
@@ -267,26 +171,15 @@ public class GLES20Canvas implements GLCanvas {
|
||||
public GLES20Canvas() {
|
||||
Matrix.setIdentityM(mTempTextureMatrix, 0);
|
||||
Matrix.setIdentityM(mMatrices, mCurrentMatrixIndex);
|
||||
mAlphas[mCurrentAlphaIndex] = 1f;
|
||||
mTargetTextures.add(null);
|
||||
|
||||
FloatBuffer boxBuffer = createBuffer(BOX_COORDINATES);
|
||||
mBoxCoordinates = uploadBuffer(boxBuffer);
|
||||
|
||||
int drawVertexShader = loadShader(GLES20.GL_VERTEX_SHADER, DRAW_VERTEX_SHADER);
|
||||
int textureVertexShader = loadShader(GLES20.GL_VERTEX_SHADER, TEXTURE_VERTEX_SHADER);
|
||||
int meshVertexShader = loadShader(GLES20.GL_VERTEX_SHADER, MESH_VERTEX_SHADER);
|
||||
int drawFragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, DRAW_FRAGMENT_SHADER);
|
||||
int textureFragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, TEXTURE_FRAGMENT_SHADER);
|
||||
int oesTextureFragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER,
|
||||
OES_TEXTURE_FRAGMENT_SHADER);
|
||||
|
||||
mDrawProgram = assembleProgram(drawVertexShader, drawFragmentShader, mDrawParameters);
|
||||
mTextureProgram = assembleProgram(textureVertexShader, textureFragmentShader,
|
||||
mTextureParameters);
|
||||
mOesTextureProgram = assembleProgram(textureVertexShader, oesTextureFragmentShader,
|
||||
mOesTextureParameters);
|
||||
mMeshProgram = assembleProgram(meshVertexShader, textureFragmentShader, mMeshParameters);
|
||||
GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);
|
||||
checkError();
|
||||
}
|
||||
@@ -348,12 +241,8 @@ public class GLES20Canvas implements GLCanvas {
|
||||
checkError();
|
||||
Matrix.setIdentityM(mMatrices, mCurrentMatrixIndex);
|
||||
Matrix.orthoM(mProjectionMatrix, 0, 0, width, 0, height, -1, 1);
|
||||
if (getTargetTexture() == null) {
|
||||
mScreenWidth = width;
|
||||
mScreenHeight = height;
|
||||
Matrix.translateM(mMatrices, mCurrentMatrixIndex, 0, height, 0);
|
||||
Matrix.scaleM(mMatrices, mCurrentMatrixIndex, 1, -1, 1);
|
||||
}
|
||||
Matrix.translateM(mMatrices, mCurrentMatrixIndex, 0, height, 0);
|
||||
Matrix.scaleM(mMatrices, mCurrentMatrixIndex, 1, -1, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -364,34 +253,6 @@ public class GLES20Canvas implements GLCanvas {
|
||||
checkError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearBuffer(float[] argb) {
|
||||
GLES20.glClearColor(argb[1], argb[2], argb[3], argb[0]);
|
||||
checkError();
|
||||
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
|
||||
checkError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAlpha() {
|
||||
return mAlphas[mCurrentAlphaIndex];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(float alpha) {
|
||||
mAlphas[mCurrentAlphaIndex] = alpha;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void multiplyAlpha(float alpha) {
|
||||
setAlpha(getAlpha() * alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(float x, float y, float z) {
|
||||
Matrix.translateM(mMatrices, mCurrentMatrixIndex, 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
|
||||
@@ -405,11 +266,6 @@ public class GLES20Canvas implements GLCanvas {
|
||||
m[index + 15] += m[index + 3] * x + m[index + 7] * y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scale(float sx, float sy, float sz) {
|
||||
Matrix.scaleM(mMatrices, mCurrentMatrixIndex, sx, sy, sz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rotate(float angle, float x, float y, float z) {
|
||||
if (angle == 0f) {
|
||||
@@ -423,31 +279,8 @@ public class GLES20Canvas implements GLCanvas {
|
||||
System.arraycopy(temp, MATRIX_SIZE, matrix, index, MATRIX_SIZE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void multiplyMatrix(float[] matrix, int offset) {
|
||||
float[] temp = mTempMatrix;
|
||||
float[] currentMatrix = mMatrices;
|
||||
int index = mCurrentMatrixIndex;
|
||||
Matrix.multiplyMM(temp, 0, currentMatrix, index, matrix, offset);
|
||||
System.arraycopy(temp, 0, currentMatrix, index, 16);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
save(SAVE_FLAG_ALL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(int saveFlags) {
|
||||
boolean saveAlpha = (saveFlags & SAVE_FLAG_ALPHA) == SAVE_FLAG_ALPHA;
|
||||
if (saveAlpha) {
|
||||
float currentAlpha = getAlpha();
|
||||
mCurrentAlphaIndex++;
|
||||
if (mAlphas.length <= mCurrentAlphaIndex) {
|
||||
mAlphas = Arrays.copyOf(mAlphas, mAlphas.length * 2);
|
||||
}
|
||||
mAlphas[mCurrentAlphaIndex] = currentAlpha;
|
||||
}
|
||||
boolean saveMatrix = (saveFlags & SAVE_FLAG_MATRIX) == SAVE_FLAG_MATRIX;
|
||||
if (saveMatrix) {
|
||||
int currentIndex = mCurrentMatrixIndex;
|
||||
@@ -463,82 +296,12 @@ public class GLES20Canvas implements GLCanvas {
|
||||
@Override
|
||||
public void restore() {
|
||||
int restoreFlags = mSaveFlags.removeLast();
|
||||
boolean restoreAlpha = (restoreFlags & SAVE_FLAG_ALPHA) == SAVE_FLAG_ALPHA;
|
||||
if (restoreAlpha) {
|
||||
mCurrentAlphaIndex--;
|
||||
}
|
||||
boolean restoreMatrix = (restoreFlags & SAVE_FLAG_MATRIX) == SAVE_FLAG_MATRIX;
|
||||
if (restoreMatrix) {
|
||||
mCurrentMatrixIndex -= MATRIX_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawLine(float x1, float y1, float x2, float y2, GLPaint paint) {
|
||||
draw(GLES20.GL_LINE_STRIP, OFFSET_DRAW_LINE, COUNT_LINE_VERTEX, x1, y1, x2 - x1, y2 - y1,
|
||||
paint);
|
||||
mCountDrawLine++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRect(float x, float y, float width, float height, GLPaint paint) {
|
||||
draw(GLES20.GL_LINE_LOOP, OFFSET_DRAW_RECT, COUNT_RECT_VERTEX, x, y, width, height, paint);
|
||||
mCountDrawLine++;
|
||||
}
|
||||
|
||||
private void draw(int type, int offset, int count, float x, float y, float width, float height,
|
||||
GLPaint paint) {
|
||||
draw(type, offset, count, x, y, width, height, paint.getColor(), paint.getLineWidth());
|
||||
}
|
||||
|
||||
private void draw(int type, int offset, int count, float x, float y, float width, float height,
|
||||
int color, float lineWidth) {
|
||||
prepareDraw(offset, color, lineWidth);
|
||||
draw(mDrawParameters, type, count, x, y, width, height);
|
||||
}
|
||||
|
||||
private void prepareDraw(int offset, int color, float lineWidth) {
|
||||
GLES20.glUseProgram(mDrawProgram);
|
||||
checkError();
|
||||
if (lineWidth > 0) {
|
||||
GLES20.glLineWidth(lineWidth);
|
||||
checkError();
|
||||
}
|
||||
float[] colorArray = getColor(color);
|
||||
boolean blendingEnabled = (colorArray[3] < 1f);
|
||||
enableBlending(blendingEnabled);
|
||||
if (blendingEnabled) {
|
||||
GLES20.glBlendColor(colorArray[0], colorArray[1], colorArray[2], colorArray[3]);
|
||||
checkError();
|
||||
}
|
||||
|
||||
GLES20.glUniform4fv(mDrawParameters[INDEX_COLOR].handle, 1, colorArray, 0);
|
||||
setPosition(mDrawParameters, offset);
|
||||
checkError();
|
||||
}
|
||||
|
||||
private float[] getColor(int color) {
|
||||
float alpha = ((color >>> 24) & 0xFF) / 255f * getAlpha();
|
||||
float red = ((color >>> 16) & 0xFF) / 255f * alpha;
|
||||
float green = ((color >>> 8) & 0xFF) / 255f * alpha;
|
||||
float blue = (color & 0xFF) / 255f * alpha;
|
||||
mTempColor[0] = red;
|
||||
mTempColor[1] = green;
|
||||
mTempColor[2] = blue;
|
||||
mTempColor[3] = alpha;
|
||||
return mTempColor;
|
||||
}
|
||||
|
||||
private void enableBlending(boolean enableBlending) {
|
||||
if (enableBlending) {
|
||||
GLES20.glEnable(GLES20.GL_BLEND);
|
||||
checkError();
|
||||
} else {
|
||||
GLES20.glDisable(GLES20.GL_BLEND);
|
||||
checkError();
|
||||
}
|
||||
}
|
||||
|
||||
private void setPosition(ShaderParameter[] params, int offset) {
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mBoxCoordinates);
|
||||
checkError();
|
||||
@@ -569,13 +332,6 @@ public class GLES20Canvas implements GLCanvas {
|
||||
checkError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillRect(float x, float y, float width, float height, int color) {
|
||||
draw(GLES20.GL_TRIANGLE_STRIP, OFFSET_FILL_RECT, COUNT_FILL_VERTEX, x, y, width, height,
|
||||
color, 0f);
|
||||
mCountFillRect++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawTexture(BasicTexture texture, int x, int y, int width, int height) {
|
||||
if (width <= 0 || height <= 0) {
|
||||
@@ -588,17 +344,7 @@ public class GLES20Canvas implements GLCanvas {
|
||||
}
|
||||
|
||||
private static void copyTextureCoordinates(BasicTexture texture, RectF outRect) {
|
||||
int left = 0;
|
||||
int top = 0;
|
||||
int right = texture.getWidth();
|
||||
int bottom = texture.getHeight();
|
||||
if (texture.hasBorder()) {
|
||||
left = 1;
|
||||
top = 1;
|
||||
right -= 1;
|
||||
bottom -= 1;
|
||||
}
|
||||
outRect.set(left, top, right, bottom);
|
||||
outRect.set(0, 0, texture.getWidth(), texture.getHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -613,16 +359,6 @@ public class GLES20Canvas implements GLCanvas {
|
||||
drawTextureRect(texture, mTempSourceRect, mTempTargetRect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawTexture(BasicTexture texture, float[] textureTransform, int x, int y, int w,
|
||||
int h) {
|
||||
if (w <= 0 || h <= 0) {
|
||||
return;
|
||||
}
|
||||
mTempTargetRect.set(x, y, x + w, y + h);
|
||||
drawTextureRect(texture, textureTransform, mTempTargetRect);
|
||||
}
|
||||
|
||||
private void drawTextureRect(BasicTexture texture, RectF source, RectF target) {
|
||||
setTextureMatrix(source);
|
||||
drawTextureRect(texture, mTempTextureMatrix, target);
|
||||
@@ -667,30 +403,15 @@ public class GLES20Canvas implements GLCanvas {
|
||||
setPosition(params, OFFSET_FILL_RECT);
|
||||
GLES20.glUniformMatrix4fv(params[INDEX_TEXTURE_MATRIX].handle, 1, false, textureMatrix, 0);
|
||||
checkError();
|
||||
if (texture.isFlippedVertically()) {
|
||||
save(SAVE_FLAG_MATRIX);
|
||||
translate(0, target.centerY());
|
||||
scale(1, -1, 1);
|
||||
translate(0, -target.centerY());
|
||||
}
|
||||
draw(params, GLES20.GL_TRIANGLE_STRIP, COUNT_FILL_VERTEX, target.left, target.top,
|
||||
target.width(), target.height());
|
||||
if (texture.isFlippedVertically()) {
|
||||
restore();
|
||||
}
|
||||
mCountTextureRect++;
|
||||
}
|
||||
|
||||
private ShaderParameter[] prepareTexture(BasicTexture texture) {
|
||||
ShaderParameter[] params;
|
||||
int program;
|
||||
if (texture.getTarget() == GLES20.GL_TEXTURE_2D) {
|
||||
params = mTextureParameters;
|
||||
program = mTextureProgram;
|
||||
} else {
|
||||
params = mOesTextureParameters;
|
||||
program = mOesTextureProgram;
|
||||
}
|
||||
params = mTextureParameters;
|
||||
program = mTextureProgram;
|
||||
prepareTexture(texture, program, params);
|
||||
return params;
|
||||
}
|
||||
@@ -699,88 +420,19 @@ public class GLES20Canvas implements GLCanvas {
|
||||
deleteRecycledResources();
|
||||
GLES20.glUseProgram(program);
|
||||
checkError();
|
||||
enableBlending(!texture.isOpaque() || getAlpha() < OPAQUE_ALPHA);
|
||||
GLES20.glDisable(GLES20.GL_BLEND);
|
||||
checkError();
|
||||
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
|
||||
checkError();
|
||||
texture.onBind(this);
|
||||
GLES20.glBindTexture(texture.getTarget(), texture.getId());
|
||||
GLES20.glBindTexture(GL_TARGET, texture.getId());
|
||||
checkError();
|
||||
GLES20.glUniform1i(params[INDEX_TEXTURE_SAMPLER].handle, 0);
|
||||
checkError();
|
||||
GLES20.glUniform1f(params[INDEX_ALPHA].handle, getAlpha());
|
||||
GLES20.glUniform1f(params[INDEX_ALPHA].handle, 1);
|
||||
checkError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawMesh(BasicTexture texture, int x, int y, int xyBuffer, int uvBuffer,
|
||||
int indexBuffer, int indexCount) {
|
||||
prepareTexture(texture, mMeshProgram, mMeshParameters);
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
|
||||
checkError();
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, xyBuffer);
|
||||
checkError();
|
||||
int positionHandle = mMeshParameters[INDEX_POSITION].handle;
|
||||
GLES20.glVertexAttribPointer(positionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false,
|
||||
VERTEX_STRIDE, 0);
|
||||
checkError();
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, uvBuffer);
|
||||
checkError();
|
||||
int texCoordHandle = mMeshParameters[INDEX_TEXTURE_COORD].handle;
|
||||
GLES20.glVertexAttribPointer(texCoordHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT,
|
||||
false, VERTEX_STRIDE, 0);
|
||||
checkError();
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
||||
checkError();
|
||||
|
||||
GLES20.glEnableVertexAttribArray(positionHandle);
|
||||
checkError();
|
||||
GLES20.glEnableVertexAttribArray(texCoordHandle);
|
||||
checkError();
|
||||
|
||||
setMatrix(mMeshParameters, x, y, 1, 1);
|
||||
GLES20.glDrawElements(GLES20.GL_TRIANGLE_STRIP, indexCount, GLES20.GL_UNSIGNED_BYTE, 0);
|
||||
checkError();
|
||||
|
||||
GLES20.glDisableVertexAttribArray(positionHandle);
|
||||
checkError();
|
||||
GLES20.glDisableVertexAttribArray(texCoordHandle);
|
||||
checkError();
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
checkError();
|
||||
mCountDrawMesh++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawMixed(BasicTexture texture, int toColor, float ratio, int x, int y, int w, int h) {
|
||||
copyTextureCoordinates(texture, mTempSourceRect);
|
||||
mTempTargetRect.set(x, y, x + w, y + h);
|
||||
drawMixed(texture, toColor, ratio, mTempSourceRect, mTempTargetRect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawMixed(BasicTexture texture, int toColor, float ratio, RectF source, RectF target) {
|
||||
if (target.width() <= 0 || target.height() <= 0) {
|
||||
return;
|
||||
}
|
||||
save(SAVE_FLAG_ALPHA);
|
||||
|
||||
float currentAlpha = getAlpha();
|
||||
float cappedRatio = Math.min(1f, Math.max(0f, ratio));
|
||||
|
||||
float textureAlpha = (1f - cappedRatio) * currentAlpha;
|
||||
setAlpha(textureAlpha);
|
||||
drawTexture(texture, source, target);
|
||||
|
||||
float colorAlpha = cappedRatio * currentAlpha;
|
||||
setAlpha(colorAlpha);
|
||||
fillRect(target.left, target.top, target.width(), target.height(), toColor);
|
||||
|
||||
restore();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unloadTexture(BasicTexture texture) {
|
||||
boolean unload = texture.isLoaded();
|
||||
@@ -792,13 +444,6 @@ public class GLES20Canvas implements GLCanvas {
|
||||
return unload;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteBuffer(int bufferId) {
|
||||
synchronized (mUnboundTextures) {
|
||||
mDeleteBuffers.add(bufferId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteRecycledResources() {
|
||||
synchronized (mUnboundTextures) {
|
||||
@@ -807,134 +452,41 @@ public class GLES20Canvas implements GLCanvas {
|
||||
mGLId.glDeleteTextures(null, ids.size(), ids.getInternalArray(), 0);
|
||||
ids.clear();
|
||||
}
|
||||
|
||||
ids = mDeleteBuffers;
|
||||
if (ids.size() > 0) {
|
||||
mGLId.glDeleteBuffers(null, ids.size(), ids.getInternalArray(), 0);
|
||||
ids.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dumpStatisticsAndClear() {
|
||||
String line = String.format("MESH:%d, TEX_RECT:%d, FILL_RECT:%d, LINE:%d", mCountDrawMesh,
|
||||
mCountTextureRect, mCountFillRect, mCountDrawLine);
|
||||
mCountDrawMesh = 0;
|
||||
mCountTextureRect = 0;
|
||||
mCountFillRect = 0;
|
||||
mCountDrawLine = 0;
|
||||
Log.d(TAG, line);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endRenderTarget() {
|
||||
RawTexture oldTexture = mTargetTextures.remove(mTargetTextures.size() - 1);
|
||||
RawTexture texture = getTargetTexture();
|
||||
setRenderTarget(oldTexture, texture);
|
||||
restore(); // restore matrix and alpha
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginRenderTarget(RawTexture texture) {
|
||||
save(); // save matrix and alpha and blending
|
||||
RawTexture oldTexture = getTargetTexture();
|
||||
mTargetTextures.add(texture);
|
||||
setRenderTarget(oldTexture, texture);
|
||||
}
|
||||
|
||||
private RawTexture getTargetTexture() {
|
||||
return mTargetTextures.get(mTargetTextures.size() - 1);
|
||||
}
|
||||
|
||||
private void setRenderTarget(BasicTexture oldTexture, RawTexture texture) {
|
||||
if (oldTexture == null && texture != null) {
|
||||
GLES20.glGenFramebuffers(1, mFrameBuffer, 0);
|
||||
checkError();
|
||||
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFrameBuffer[0]);
|
||||
checkError();
|
||||
} else if (oldTexture != null && texture == null) {
|
||||
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
|
||||
checkError();
|
||||
GLES20.glDeleteFramebuffers(1, mFrameBuffer, 0);
|
||||
checkError();
|
||||
}
|
||||
|
||||
if (texture == null) {
|
||||
setSize(mScreenWidth, mScreenHeight);
|
||||
} else {
|
||||
setSize(texture.getWidth(), texture.getHeight());
|
||||
|
||||
if (!texture.isLoaded()) {
|
||||
texture.prepare(this);
|
||||
}
|
||||
|
||||
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0,
|
||||
texture.getTarget(), texture.getId(), 0);
|
||||
checkError();
|
||||
|
||||
checkFramebufferStatus();
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkFramebufferStatus() {
|
||||
int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);
|
||||
if (status != GLES20.GL_FRAMEBUFFER_COMPLETE) {
|
||||
String msg = "";
|
||||
switch (status) {
|
||||
case GLES20.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
|
||||
msg = "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
|
||||
break;
|
||||
case GLES20.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
|
||||
msg = "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS";
|
||||
break;
|
||||
case GLES20.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
|
||||
msg = "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
|
||||
break;
|
||||
case GLES20.GL_FRAMEBUFFER_UNSUPPORTED:
|
||||
msg = "GL_FRAMEBUFFER_UNSUPPORTED";
|
||||
break;
|
||||
}
|
||||
throw new RuntimeException(msg + ":" + Integer.toHexString(status));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTextureParameters(BasicTexture texture) {
|
||||
int target = texture.getTarget();
|
||||
GLES20.glBindTexture(target, texture.getId());
|
||||
GLES20.glBindTexture(GL_TARGET, texture.getId());
|
||||
checkError();
|
||||
GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
|
||||
GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
|
||||
GLES20.glTexParameterf(target, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
|
||||
GLES20.glTexParameterf(target, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
|
||||
GLES20.glTexParameteri(GL_TARGET, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
|
||||
GLES20.glTexParameteri(GL_TARGET, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
|
||||
GLES20.glTexParameterf(GL_TARGET, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
|
||||
GLES20.glTexParameterf(GL_TARGET, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeTextureSize(BasicTexture texture, int format, int type) {
|
||||
int target = texture.getTarget();
|
||||
GLES20.glBindTexture(target, texture.getId());
|
||||
GLES20.glBindTexture(GL_TARGET, texture.getId());
|
||||
checkError();
|
||||
int width = texture.getTextureWidth();
|
||||
int height = texture.getTextureHeight();
|
||||
GLES20.glTexImage2D(target, 0, format, width, height, 0, format, type, null);
|
||||
GLES20.glTexImage2D(GL_TARGET, 0, format, width, height, 0, format, type, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeTexture(BasicTexture texture, Bitmap bitmap) {
|
||||
int target = texture.getTarget();
|
||||
GLES20.glBindTexture(target, texture.getId());
|
||||
GLES20.glBindTexture(GL_TARGET, texture.getId());
|
||||
checkError();
|
||||
GLUtils.texImage2D(target, 0, bitmap, 0);
|
||||
GLUtils.texImage2D(GL_TARGET, 0, bitmap, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void texSubImage2D(BasicTexture texture, int xOffset, int yOffset, Bitmap bitmap,
|
||||
int format, int type) {
|
||||
int target = texture.getTarget();
|
||||
GLES20.glBindTexture(target, texture.getId());
|
||||
GLES20.glBindTexture(GL_TARGET, texture.getId());
|
||||
checkError();
|
||||
GLUtils.texSubImage2D(target, 0, xOffset, yOffset, bitmap, format, type);
|
||||
GLUtils.texSubImage2D(GL_TARGET, 0, xOffset, yOffset, bitmap, format, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -942,11 +494,6 @@ public class GLES20Canvas implements GLCanvas {
|
||||
return uploadBuffer(buf, FLOAT_SIZE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int uploadBuffer(ByteBuffer buf) {
|
||||
return uploadBuffer(buf, 1);
|
||||
}
|
||||
|
||||
private int uploadBuffer(Buffer buffer, int elementSize) {
|
||||
mGLId.glGenBuffers(1, mTempIntArray, 0);
|
||||
checkError();
|
||||
@@ -967,40 +514,6 @@ public class GLES20Canvas implements GLCanvas {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static void printMatrix(String message, float[] m, int offset) {
|
||||
StringBuilder b = new StringBuilder(message);
|
||||
for (int i = 0; i < MATRIX_SIZE; i++) {
|
||||
b.append(' ');
|
||||
if (i % 4 == 0) {
|
||||
b.append('\n');
|
||||
}
|
||||
b.append(m[offset + i]);
|
||||
}
|
||||
Log.v(TAG, b.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recoverFromLightCycle() {
|
||||
GLES20.glViewport(0, 0, mWidth, mHeight);
|
||||
GLES20.glDisable(GLES20.GL_DEPTH_TEST);
|
||||
GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);
|
||||
checkError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBounds(Rect bounds, int x, int y, int width, int height) {
|
||||
Matrix.translateM(mTempMatrix, 0, mMatrices, mCurrentMatrixIndex, x, y, 0f);
|
||||
Matrix.scaleM(mTempMatrix, 0, width, height, 1f);
|
||||
Matrix.multiplyMV(mTempMatrix, MATRIX_SIZE, mTempMatrix, 0, BOUNDS_COORDINATES, 0);
|
||||
Matrix.multiplyMV(mTempMatrix, MATRIX_SIZE + 4, mTempMatrix, 0, BOUNDS_COORDINATES, 4);
|
||||
bounds.left = Math.round(mTempMatrix[MATRIX_SIZE]);
|
||||
bounds.right = Math.round(mTempMatrix[MATRIX_SIZE + 4]);
|
||||
bounds.top = Math.round(mTempMatrix[MATRIX_SIZE + 1]);
|
||||
bounds.bottom = Math.round(mTempMatrix[MATRIX_SIZE + 5]);
|
||||
bounds.sort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GLId getGLId() {
|
||||
return mGLId;
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* 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 com.android.gallery3d.common.Utils;
|
||||
|
||||
public class GLPaint {
|
||||
private float mLineWidth = 1f;
|
||||
private int mColor = 0;
|
||||
|
||||
public void setColor(int color) {
|
||||
mColor = color;
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return mColor;
|
||||
}
|
||||
|
||||
public void setLineWidth(float width) {
|
||||
Utils.assertTrue(width >= 0);
|
||||
mLineWidth = width;
|
||||
}
|
||||
|
||||
public float getLineWidth() {
|
||||
return mLineWidth;
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* 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.util.Log;
|
||||
|
||||
import javax.microedition.khronos.opengles.GL11;
|
||||
|
||||
public class RawTexture extends BasicTexture {
|
||||
private static final String TAG = "RawTexture";
|
||||
|
||||
private final boolean mOpaque;
|
||||
private boolean mIsFlipped;
|
||||
|
||||
public RawTexture(int width, int height, boolean opaque) {
|
||||
mOpaque = opaque;
|
||||
setSize(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpaque() {
|
||||
return mOpaque;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFlippedVertically() {
|
||||
return mIsFlipped;
|
||||
}
|
||||
|
||||
public void setIsFlippedVertically(boolean isFlipped) {
|
||||
mIsFlipped = isFlipped;
|
||||
}
|
||||
|
||||
protected void prepare(GLCanvas canvas) {
|
||||
GLId glId = canvas.getGLId();
|
||||
mId = glId.generateTexture();
|
||||
canvas.initializeTextureSize(this, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE);
|
||||
canvas.setTextureParameters(this);
|
||||
mState = STATE_LOADED;
|
||||
setAssociatedCanvas(canvas);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onBind(GLCanvas canvas) {
|
||||
if (isLoaded()) return true;
|
||||
Log.w(TAG, "lost the content due to context change");
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void yield() {
|
||||
// we cannot free the texture because we have no backup.
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getTarget() {
|
||||
return GL11.GL_TEXTURE_2D;
|
||||
}
|
||||
}
|
||||
@@ -24,21 +24,14 @@ package com.android.gallery3d.glrenderer;
|
||||
// This is the current texture hierarchy:
|
||||
//
|
||||
// Texture
|
||||
// -- ColorTexture
|
||||
// -- FadeInTexture
|
||||
// -- BasicTexture
|
||||
// -- UploadedTexture
|
||||
// -- BitmapTexture
|
||||
// -- Tile
|
||||
// -- ResourceTexture
|
||||
// -- NinePatchTexture
|
||||
// -- CanvasTexture
|
||||
// -- StringTexture
|
||||
//
|
||||
public interface Texture {
|
||||
public int getWidth();
|
||||
public int getHeight();
|
||||
public void draw(GLCanvas canvas, int x, int y);
|
||||
public void draw(GLCanvas canvas, int x, int y, int w, int h);
|
||||
public boolean isOpaque();
|
||||
}
|
||||
|
||||
@@ -19,14 +19,12 @@ package com.android.gallery3d.glrenderer;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Bitmap.Config;
|
||||
import android.opengl.GLUtils;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.android.gallery3d.common.Utils;
|
||||
import com.android.launcher3.util.Thunk;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import javax.microedition.khronos.opengles.GL11;
|
||||
|
||||
// UploadedTextures use a Bitmap for the content of the texture.
|
||||
//
|
||||
// Subclasses should implement onGetBitmap() to provide the Bitmap and
|
||||
@@ -45,89 +43,29 @@ public abstract class UploadedTexture extends BasicTexture {
|
||||
|
||||
// To prevent keeping allocation the borders, we store those used borders here.
|
||||
// Since the length will be power of two, it won't use too much memory.
|
||||
private static HashMap<BorderKey, Bitmap> sBorderLines =
|
||||
new HashMap<BorderKey, Bitmap>();
|
||||
private static BorderKey sBorderKey = new BorderKey();
|
||||
private static HashMap<BorderKey, Bitmap> sBorderLines = new HashMap<BorderKey, Bitmap>();
|
||||
|
||||
private static class BorderKey extends Pair<Config, Integer> {
|
||||
public BorderKey(Config config, boolean vertical, int length) {
|
||||
super(config, vertical ? length : -length);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static final String TAG = "Texture";
|
||||
private boolean mContentValid = true;
|
||||
|
||||
// indicate this textures is being uploaded in background
|
||||
private boolean mIsUploading = false;
|
||||
private boolean mOpaque = true;
|
||||
private boolean mThrottled = false;
|
||||
private static int sUploadedCount;
|
||||
private static final int UPLOAD_LIMIT = 100;
|
||||
|
||||
protected Bitmap mBitmap;
|
||||
private int mBorder;
|
||||
|
||||
protected UploadedTexture() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
protected UploadedTexture(boolean hasBorder) {
|
||||
super(null, 0, STATE_UNLOADED);
|
||||
if (hasBorder) {
|
||||
setBorder(true);
|
||||
mBorder = 1;
|
||||
}
|
||||
}
|
||||
|
||||
protected void setIsUploading(boolean uploading) {
|
||||
mIsUploading = uploading;
|
||||
}
|
||||
|
||||
public boolean isUploading() {
|
||||
return mIsUploading;
|
||||
}
|
||||
|
||||
@Thunk static class BorderKey implements Cloneable {
|
||||
public boolean vertical;
|
||||
public Config config;
|
||||
public int length;
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int x = config.hashCode() ^ length;
|
||||
return vertical ? x : -x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (!(object instanceof BorderKey)) return false;
|
||||
BorderKey o = (BorderKey) object;
|
||||
return vertical == o.vertical
|
||||
&& config == o.config && length == o.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BorderKey clone() {
|
||||
try {
|
||||
return (BorderKey) super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void setThrottled(boolean throttled) {
|
||||
mThrottled = throttled;
|
||||
}
|
||||
|
||||
private static Bitmap getBorderLine(
|
||||
boolean vertical, Config config, int length) {
|
||||
BorderKey key = sBorderKey;
|
||||
key.vertical = vertical;
|
||||
key.config = config;
|
||||
key.length = length;
|
||||
private static Bitmap getBorderLine(boolean vertical, Config config, int length) {
|
||||
BorderKey key = new BorderKey(config, vertical, length);
|
||||
Bitmap bitmap = sBorderLines.get(key);
|
||||
if (bitmap == null) {
|
||||
bitmap = vertical
|
||||
? Bitmap.createBitmap(1, length, config)
|
||||
: Bitmap.createBitmap(length, 1, config);
|
||||
sBorderLines.put(key.clone(), bitmap);
|
||||
sBorderLines.put(key, bitmap);
|
||||
}
|
||||
return bitmap;
|
||||
}
|
||||
@@ -135,8 +73,8 @@ public abstract class UploadedTexture extends BasicTexture {
|
||||
private Bitmap getBitmap() {
|
||||
if (mBitmap == null) {
|
||||
mBitmap = onGetBitmap();
|
||||
int w = mBitmap.getWidth() + mBorder * 2;
|
||||
int h = mBitmap.getHeight() + mBorder * 2;
|
||||
int w = mBitmap.getWidth();
|
||||
int h = mBitmap.getHeight();
|
||||
if (mWidth == UNSPECIFIED) {
|
||||
setSize(w, h);
|
||||
}
|
||||
@@ -186,37 +124,23 @@ public abstract class UploadedTexture extends BasicTexture {
|
||||
*/
|
||||
public void updateContent(GLCanvas canvas) {
|
||||
if (!isLoaded()) {
|
||||
if (mThrottled && ++sUploadedCount > UPLOAD_LIMIT) {
|
||||
return;
|
||||
}
|
||||
uploadToCanvas(canvas);
|
||||
} else if (!mContentValid) {
|
||||
Bitmap bitmap = getBitmap();
|
||||
int format = GLUtils.getInternalFormat(bitmap);
|
||||
int type = GLUtils.getType(bitmap);
|
||||
canvas.texSubImage2D(this, mBorder, mBorder, bitmap, format, type);
|
||||
canvas.texSubImage2D(this, 0, 0, bitmap, format, type);
|
||||
freeBitmap();
|
||||
mContentValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static void resetUploadLimit() {
|
||||
sUploadedCount = 0;
|
||||
}
|
||||
|
||||
public static boolean uploadLimitReached() {
|
||||
return sUploadedCount > UPLOAD_LIMIT;
|
||||
}
|
||||
|
||||
private void uploadToCanvas(GLCanvas canvas) {
|
||||
|
||||
Bitmap bitmap = getBitmap();
|
||||
if (bitmap != null) {
|
||||
try {
|
||||
int bWidth = bitmap.getWidth();
|
||||
int bHeight = bitmap.getHeight();
|
||||
int width = bWidth + mBorder * 2;
|
||||
int height = bHeight + mBorder * 2;
|
||||
int texWidth = getTextureWidth();
|
||||
int texHeight = getTextureHeight();
|
||||
|
||||
@@ -234,28 +158,18 @@ public abstract class UploadedTexture extends BasicTexture {
|
||||
Config config = bitmap.getConfig();
|
||||
|
||||
canvas.initializeTextureSize(this, format, type);
|
||||
canvas.texSubImage2D(this, mBorder, mBorder, bitmap, format, type);
|
||||
|
||||
if (mBorder > 0) {
|
||||
// Left border
|
||||
Bitmap line = getBorderLine(true, config, texHeight);
|
||||
canvas.texSubImage2D(this, 0, 0, line, format, type);
|
||||
|
||||
// Top border
|
||||
line = getBorderLine(false, config, texWidth);
|
||||
canvas.texSubImage2D(this, 0, 0, line, format, type);
|
||||
}
|
||||
canvas.texSubImage2D(this, 0, 0, bitmap, format, type);
|
||||
|
||||
// Right border
|
||||
if (mBorder + bWidth < texWidth) {
|
||||
if (bWidth < texWidth) {
|
||||
Bitmap line = getBorderLine(true, config, texHeight);
|
||||
canvas.texSubImage2D(this, mBorder + bWidth, 0, line, format, type);
|
||||
canvas.texSubImage2D(this, bWidth, 0, line, format, type);
|
||||
}
|
||||
|
||||
// Bottom border
|
||||
if (mBorder + bHeight < texHeight) {
|
||||
if (bHeight < texHeight) {
|
||||
Bitmap line = getBorderLine(false, config, texWidth);
|
||||
canvas.texSubImage2D(this, 0, mBorder + bHeight, line, format, type);
|
||||
canvas.texSubImage2D(this, 0, bHeight, line, format, type);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
@@ -277,20 +191,6 @@ public abstract class UploadedTexture extends BasicTexture {
|
||||
return isContentValid();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getTarget() {
|
||||
return GL11.GL_TEXTURE_2D;
|
||||
}
|
||||
|
||||
public void setOpaque(boolean isOpaque) {
|
||||
mOpaque = isOpaque;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpaque() {
|
||||
return mOpaque;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recycle() {
|
||||
super.recycle();
|
||||
|
||||
@@ -25,7 +25,6 @@ import android.graphics.BitmapRegionDecoder;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.media.ExifInterface;
|
||||
import android.net.Uri;
|
||||
import android.opengl.GLUtils;
|
||||
import android.os.Build;
|
||||
|
||||
@@ -17,12 +17,7 @@
|
||||
package com.android.photos.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Paint.Align;
|
||||
import android.graphics.RectF;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.opengl.GLSurfaceView.Renderer;
|
||||
@@ -82,7 +77,6 @@ public class TiledImageView extends FrameLayout {
|
||||
mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
|
||||
addView(mGLSurfaceView, new LayoutParams(
|
||||
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
|
||||
//setTileSource(new ColoredTiles());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -247,66 +241,4 @@ public class TiledImageView extends FrameLayout {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class ColoredTiles implements TileSource {
|
||||
private static final int[] COLORS = new int[] {
|
||||
Color.RED,
|
||||
Color.BLUE,
|
||||
Color.YELLOW,
|
||||
Color.GREEN,
|
||||
Color.CYAN,
|
||||
Color.MAGENTA,
|
||||
Color.WHITE,
|
||||
};
|
||||
|
||||
private Paint mPaint = new Paint();
|
||||
private Canvas mCanvas = new Canvas();
|
||||
|
||||
@Override
|
||||
public int getTileSize() {
|
||||
return 256;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getImageWidth() {
|
||||
return 16384;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getImageHeight() {
|
||||
return 8192;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRotation() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bitmap getTile(int level, int x, int y, Bitmap bitmap) {
|
||||
int tileSize = getTileSize();
|
||||
if (bitmap == null) {
|
||||
bitmap = Bitmap.createBitmap(tileSize, tileSize,
|
||||
Bitmap.Config.ARGB_8888);
|
||||
}
|
||||
mCanvas.setBitmap(bitmap);
|
||||
mCanvas.drawColor(COLORS[level]);
|
||||
mPaint.setColor(Color.BLACK);
|
||||
mPaint.setTextSize(20);
|
||||
mPaint.setTextAlign(Align.CENTER);
|
||||
mCanvas.drawText(x + "x" + y, 128, 128, mPaint);
|
||||
tileSize <<= level;
|
||||
x /= tileSize;
|
||||
y /= tileSize;
|
||||
mCanvas.drawText(x + "x" + y + " @ " + level, 128, 30, mPaint);
|
||||
mCanvas.setBitmap(null);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicTexture getPreview() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user