• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.cooliris.media;
18 
19 import javax.microedition.khronos.opengles.GL11;
20 import javax.microedition.khronos.opengles.GL11Ext;
21 
22 import android.graphics.Bitmap;
23 import android.graphics.Canvas;
24 import android.opengl.GLUtils;
25 
26 public abstract class CanvasTexture {
27     private int mWidth;
28     private int mHeight;
29     private int mTextureId;
30     private int mTextureWidth;
31     private int mTextureHeight;
32     private float mNormalizedWidth;
33     private float mNormalizedHeight;
34 
35     private final Canvas mCanvas = new Canvas();
36     private final Bitmap.Config mBitmapConfig;
37     private Bitmap mBitmap = null;
38     private boolean mNeedsDraw = false;
39     private boolean mNeedsResize = false;
40     private GL11 mCachedGL = null;
41 
CanvasTexture(Bitmap.Config bitmapConfig)42     public CanvasTexture(Bitmap.Config bitmapConfig) {
43         mBitmapConfig = bitmapConfig;
44     }
45 
setNeedsDraw()46     public final void setNeedsDraw() {
47         mNeedsDraw = true;
48     }
49 
getWidth()50     public final int getWidth() {
51         return mWidth;
52     }
53 
getHeight()54     public final int getHeight() {
55         return mHeight;
56     }
57 
getNormalizedWidth()58     public final float getNormalizedWidth() {
59         return mNormalizedWidth;
60     }
61 
getNormalizedHeight()62     public final float getNormalizedHeight() {
63         return mNormalizedHeight;
64     }
65 
setSize(int width, int height)66     public final void setSize(int width, int height) {
67         mWidth = width;
68         mHeight = height;
69         mNeedsResize = true;
70         mTextureWidth = -1;
71         mTextureHeight = -1;
72         onSizeChanged();
73     }
74 
resetTexture()75     public void resetTexture() {
76         // Happens when restoring the scene. Need to manage this more
77         // automatically.
78         mTextureId = 0;
79         mNeedsResize = true;
80     }
81 
82     // This code seems largely a dup of CanvasLayer.
bind(GL11 gl)83     public boolean bind(GL11 gl) {
84         if (mCachedGL != gl) {
85             mCachedGL = gl;
86             resetTexture();
87         }
88         int width = (int) mWidth;
89         int height = (int) mHeight;
90         int textureId = mTextureId;
91         int textureWidth = mTextureWidth;
92         int textureHeight = mTextureHeight;
93         Canvas canvas = mCanvas;
94         Bitmap bitmap = mBitmap;
95 
96         if (mNeedsResize || mTextureId == 0) {
97             // Clear the resize flag and mark as needing draw.
98             mNeedsDraw = true;
99 
100             // Compute the power-of-2 padded size for the texture.
101             int newTextureWidth = Shared.nextPowerOf2(width);
102             int newTextureHeight = Shared.nextPowerOf2(height);
103 
104             // Reallocate the bitmap only if the padded size has changed.
105             // TODO: reuse same texture if it is already large enough, just
106             // change clip rect.
107             if (textureWidth != newTextureWidth || textureHeight != newTextureHeight || mTextureId == 0) {
108                 // Allocate a texture if needed.
109                 if (textureId == 0) {
110                     int[] textureIdOut = new int[1];
111                     gl.glGenTextures(1, textureIdOut, 0);
112                     textureId = textureIdOut[0];
113                     mNeedsResize = false;
114                     mTextureId = textureId;
115 
116                     // Set texture parameters.
117                     gl.glBindTexture(GL11.GL_TEXTURE_2D, textureId);
118                     gl.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP_TO_EDGE);
119                     gl.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP_TO_EDGE);
120                     gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
121                     gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
122                 }
123 
124                 // Set the new texture width and height.
125                 textureWidth = newTextureWidth;
126                 textureHeight = newTextureHeight;
127                 mTextureWidth = newTextureWidth;
128                 mTextureHeight = newTextureHeight;
129                 mNormalizedWidth = (float) width / textureWidth;
130                 mNormalizedHeight = (float) height / textureHeight;
131 
132                 // Recycle the existing bitmap and create a new one.
133                 if (bitmap != null)
134                     bitmap.recycle();
135                 if (textureWidth > 0 && textureHeight > 0) {
136                     bitmap = Bitmap.createBitmap(textureWidth, textureHeight, mBitmapConfig);
137                     canvas.setBitmap(bitmap);
138                     mBitmap = bitmap;
139                 }
140             }
141         }
142 
143         // Bind the texture to the context.
144         if (textureId == 0) {
145             return false;
146         }
147         gl.glBindTexture(GL11.GL_TEXTURE_2D, textureId);
148 
149         // Redraw the contents of the texture if needed.
150         if (mNeedsDraw) {
151             mNeedsDraw = false;
152             renderCanvas(canvas, bitmap, width, height);
153             int[] cropRect = { 0, height, width, -height };
154             gl.glTexParameteriv(GL11.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, cropRect, 0);
155             GLUtils.texImage2D(GL11.GL_TEXTURE_2D, 0, bitmap, 0);
156 
157         }
158 
159         return true;
160     }
161 
draw(RenderView view, GL11 gl, int x, int y)162     public void draw(RenderView view, GL11 gl, int x, int y) {
163         if (bind(gl)) {
164             view.draw2D(x, y, 0, mWidth, mHeight);
165         }
166     }
167 
drawWithEffect(RenderView view, GL11 gl, float x, float y, float anchorX, float anchorY, float alpha, float scale)168     public void drawWithEffect(RenderView view, GL11 gl, float x, float y, float anchorX, float anchorY, float alpha, float scale) {
169         if (bind(gl)) {
170             float width = mWidth;
171             float height = mHeight;
172 
173             // Apply scale transform if not identity.
174             if (scale != 1) { // CR: 1.0f
175                 float originX = x + anchorX * width;
176                 float originY = y + anchorY * height;
177                 width *= scale;
178                 height *= scale;
179                 x = originX - anchorX * width;
180                 y = originY - anchorY * height;
181             }
182 
183             // Set alpha if needed.
184             if (alpha != 1f) { // CR: 1.0f
185                 view.setAlpha(alpha);
186             }
187             view.draw2D(x, y, 0, width, height);
188             if (alpha != 1f) {
189                 view.resetColor();
190             }
191         }
192     }
193 
onSizeChanged()194     protected abstract void onSizeChanged();
195 
renderCanvas(Canvas canvas, Bitmap backing, int width, int height)196     protected abstract void renderCanvas(Canvas canvas, Bitmap backing, int width, int height);
197 
198 } // CR: superfluous newline above.
199