Home | History | Annotate | Download | only in ui
      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