OSDN Git Service

a881eef0367ff32ec27d1a2d2a02f0198f018ceb
[android-x86/packages-apps-Gallery2.git] / src / com / cooliris / media / CanvasTexture.java
1 package com.cooliris.media;
2
3 import javax.microedition.khronos.opengles.GL11;
4 import javax.microedition.khronos.opengles.GL11Ext;
5
6 import android.graphics.Bitmap;
7 import android.graphics.Canvas;
8 import android.opengl.GLUtils;
9
10 public abstract class CanvasTexture {
11     private int mWidth;
12     private int mHeight;
13     private int mTextureId;
14     private int mTextureWidth;
15     private int mTextureHeight;
16     private float mNormalizedWidth;
17     private float mNormalizedHeight;
18
19     private final Canvas mCanvas = new Canvas();
20     private final Bitmap.Config mBitmapConfig;
21     private Bitmap mBitmap = null;
22     private boolean mNeedsDraw = false;
23     private boolean mNeedsResize = false;
24     private GL11 mCachedGL = null;
25
26     public CanvasTexture(Bitmap.Config bitmapConfig) {
27         mBitmapConfig = bitmapConfig;
28     }
29
30     public final void setNeedsDraw() {
31         mNeedsDraw = true;
32     }
33
34     public final int getWidth() {
35         return mWidth;
36     }
37
38     public final int getHeight() {
39         return mHeight;
40     }
41
42     public final float getNormalizedWidth() {
43         return mNormalizedWidth;
44     }
45
46     public final float getNormalizedHeight() {
47         return mNormalizedHeight;
48     }
49
50     public final void setSize(int width, int height) {
51         mWidth = width;
52         mHeight = height;
53         mNeedsResize = true;
54         mTextureWidth = -1;
55         mTextureHeight = -1;
56         onSizeChanged();
57     }
58
59     public void resetTexture() {
60         // Happens when restoring the scene. Need to manage this more automatically.
61         mTextureId = 0;
62         mNeedsResize = true;
63     }
64
65     // This code seems largely a dup of CanvasLayer.
66     public boolean bind(GL11 gl) {
67         if (mCachedGL != gl) {
68             mCachedGL = gl;
69             resetTexture();
70         }
71         int width = (int) mWidth;
72         int height = (int) mHeight;
73         int textureId = mTextureId;
74         int textureWidth = mTextureWidth;
75         int textureHeight = mTextureHeight;
76         Canvas canvas = mCanvas;
77         Bitmap bitmap = mBitmap;
78
79         if (mNeedsResize || mTextureId == 0) {
80             // Clear the resize flag and mark as needing draw.
81             mNeedsDraw = true;
82
83             // Compute the power-of-2 padded size for the texture.
84             int newTextureWidth = Shared.nextPowerOf2(width);
85             int newTextureHeight = Shared.nextPowerOf2(height);
86
87             // Reallocate the bitmap only if the padded size has changed.
88             // TODO: reuse same texture if it is already large enough, just
89             // change clip rect.
90             if (textureWidth != newTextureWidth || textureHeight != newTextureHeight || mTextureId == 0) {
91                 // Allocate a texture if needed.
92                 if (textureId == 0) {
93                     int[] textureIdOut = new int[1];
94                     gl.glGenTextures(1, textureIdOut, 0);
95                     textureId = textureIdOut[0];
96                     mNeedsResize = false;
97                     mTextureId = textureId;
98
99                     // Set texture parameters.
100                     gl.glBindTexture(GL11.GL_TEXTURE_2D, textureId);
101                     gl.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP_TO_EDGE);
102                     gl.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP_TO_EDGE);
103                     gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
104                     gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
105                 }
106
107                 // Set the new texture width and height.
108                 textureWidth = newTextureWidth;
109                 textureHeight = newTextureHeight;
110                 mTextureWidth = newTextureWidth;
111                 mTextureHeight = newTextureHeight;
112                 mNormalizedWidth = (float) width / textureWidth;
113                 mNormalizedHeight = (float) height / textureHeight;
114
115                 // Recycle the existing bitmap and create a new one.
116                 if (bitmap != null)
117                     bitmap.recycle();
118                 if (textureWidth > 0 && textureHeight > 0) {
119                     bitmap = Bitmap.createBitmap(textureWidth, textureHeight, mBitmapConfig);
120                     canvas.setBitmap(bitmap);
121                     mBitmap = bitmap;
122                 }
123             }
124         }
125
126         // Bind the texture to the context.
127         if (textureId == 0) {
128             return false;
129         }
130         gl.glBindTexture(GL11.GL_TEXTURE_2D, textureId);
131
132         // Redraw the contents of the texture if needed.
133         if (mNeedsDraw) {
134             mNeedsDraw = false;
135             renderCanvas(canvas, bitmap, width, height);
136             int[] cropRect = { 0, height, width, -height };
137             gl.glTexParameteriv(GL11.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, cropRect, 0);
138             GLUtils.texImage2D(GL11.GL_TEXTURE_2D, 0, bitmap, 0);
139
140         }
141
142         return true;
143     }
144
145     public void draw(RenderView view, GL11 gl, int x, int y) {
146         if (bind(gl)) {
147             view.draw2D(x, y, 0, mWidth, mHeight);
148         }
149     }
150
151     public void drawWithEffect(RenderView view, GL11 gl, float x, float y, float anchorX, float anchorY, float alpha, float scale) {
152         if (bind(gl)) {
153             float width = mWidth;
154             float height = mHeight;
155
156             // Apply scale transform if not identity.
157             if (scale != 1) { // CR: 1.0f
158                 float originX = x + anchorX * width;
159                 float originY = y + anchorY * height;
160                 width *= scale;
161                 height *= scale;
162                 x = originX - anchorX * width;
163                 y = originY - anchorY * height;
164             }
165
166             // Set alpha if needed.
167             if (alpha != 1f) { // CR: 1.0f
168                 view.setAlpha(alpha);
169             }
170             view.draw2D(x, y, 0, width, height);
171             if (alpha != 1f) {
172                 view.resetColor();
173             }
174         }
175     }
176
177     protected abstract void onSizeChanged();
178
179     protected abstract void renderCanvas(Canvas canvas, Bitmap backing, int width, int height);
180
181 } // CR: superfluous newline above.