1 package com.android.camera.ui; 2 3 import com.android.camera.Util; 4 5 import android.graphics.Bitmap; 6 import android.opengl.GLUtils; 7 8 import javax.microedition.khronos.opengles.GL11; 9 import javax.microedition.khronos.opengles.GL11Ext; 10 11 abstract class BitmapTexture extends BasicTexture { 12 13 @SuppressWarnings("unused") 14 private static final String TAG = "Texture"; 15 16 protected BitmapTexture() { 17 super(null, 0, STATE_UNLOADED); 18 } 19 20 @Override 21 public int getWidth() { 22 if (mWidth == UNSPECIFIED) getBitmap(); 23 return mWidth; 24 } 25 26 @Override 27 public int getHeight() { 28 if (mWidth == UNSPECIFIED) getBitmap(); 29 return mHeight; 30 } 31 32 protected abstract Bitmap getBitmap(); 33 34 protected abstract void freeBitmap(Bitmap bitmap); 35 36 private void uploadToGL(GL11 gl) throws GLOutOfMemoryException { 37 Bitmap bitmap = getBitmap(); 38 int glError = GL11.GL_NO_ERROR; 39 if (bitmap != null) { 40 int[] textureId = new int[1]; 41 try { 42 // Define a vertically flipped crop rectangle for 43 // OES_draw_texture. 44 int width = bitmap.getWidth(); 45 int height = bitmap.getHeight(); 46 int[] cropRect = {0, height, width, -height}; 47 48 // Upload the bitmap to a new texture. 49 gl.glGenTextures(1, textureId, 0); 50 gl.glBindTexture(GL11.GL_TEXTURE_2D, textureId[0]); 51 gl.glTexParameteriv(GL11.GL_TEXTURE_2D, 52 GL11Ext.GL_TEXTURE_CROP_RECT_OES, cropRect, 0); 53 gl.glTexParameteri(GL11.GL_TEXTURE_2D, 54 GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP_TO_EDGE); 55 gl.glTexParameteri(GL11.GL_TEXTURE_2D, 56 GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP_TO_EDGE); 57 gl.glTexParameterf(GL11.GL_TEXTURE_2D, 58 GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); 59 gl.glTexParameterf(GL11.GL_TEXTURE_2D, 60 GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); 61 62 int widthExt = Util.nextPowerOf2(width); 63 int heightExt = Util.nextPowerOf2(height); 64 int format = GLUtils.getInternalFormat(bitmap); 65 int type = GLUtils.getType(bitmap); 66 67 mTextureWidth = widthExt; 68 mTextureHeight = heightExt; 69 gl.glTexImage2D(GL11.GL_TEXTURE_2D, 0, format, 70 widthExt, heightExt, 0, format, type, null); 71 GLUtils.texSubImage2D( 72 GL11.GL_TEXTURE_2D, 0, 0, 0, bitmap, format, type); 73 } finally { 74 freeBitmap(bitmap); 75 } 76 if (glError == GL11.GL_OUT_OF_MEMORY) { 77 throw new GLOutOfMemoryException(); 78 } 79 if (glError != GL11.GL_NO_ERROR) { 80 mId = 0; 81 mState = STATE_UNLOADED; 82 throw new RuntimeException( 83 "Texture upload fail, glError " + glError); 84 } else { 85 // Update texture state. 86 mGL = gl; 87 mId = textureId[0]; 88 mState = BitmapTexture.STATE_LOADED; 89 } 90 } else { 91 mState = STATE_ERROR; 92 throw new RuntimeException("Texture load fail, no bitmap"); 93 } 94 } 95 96 @Override 97 protected boolean bind(GLRootView root, GL11 gl) { 98 if (mState == BitmapTexture.STATE_UNLOADED || mGL != gl) { 99 mState = BitmapTexture.STATE_UNLOADED; 100 try { 101 uploadToGL(gl); 102 } catch (GLOutOfMemoryException e) { 103 root.handleLowMemory(); 104 return false; 105 } 106 } else { 107 gl.glBindTexture(GL11.GL_TEXTURE_2D, getId()); 108 } 109 return true; 110 } 111 } 112