From 4ad1c1729d0ba95b5e96081759a96072e611df1f Mon Sep 17 00:00:00 2001 From: Owen Lin Date: Fri, 14 May 2010 14:13:02 +0800 Subject: [PATCH] Refactor the code. Improve the inheritance structure of Textures. Change-Id: I72a78f97cf54a6505cd7bff98e1db1bdf5fa84c9 --- src/com/android/camera/ui/AbstractIndicator.java | 6 +- src/com/android/camera/ui/BasicTexture.java | 77 ++++++++++ src/com/android/camera/ui/BitmapTexture.java | 111 ++++++++++++++ src/com/android/camera/ui/CanvasTexture.java | 2 +- src/com/android/camera/ui/ColorTexture.java | 25 +--- src/com/android/camera/ui/FrameTexture.java | 38 ----- src/com/android/camera/ui/GLListView.java | 23 +-- src/com/android/camera/ui/GLOptionHeader.java | 7 +- src/com/android/camera/ui/GLRootView.java | 34 ++--- src/com/android/camera/ui/IndicatorBar.java | 11 +- src/com/android/camera/ui/NinePatchTexture.java | 43 +----- src/com/android/camera/ui/PopupWindow.java | 22 +-- src/com/android/camera/ui/RawTexture.java | 17 +-- src/com/android/camera/ui/ResourceTexture.java | 25 +--- src/com/android/camera/ui/Texture.java | 180 +---------------------- src/com/android/camera/ui/ZoomController.java | 15 +- src/com/android/camera/ui/ZoomIndicator.java | 4 +- 17 files changed, 269 insertions(+), 371 deletions(-) create mode 100644 src/com/android/camera/ui/BasicTexture.java create mode 100644 src/com/android/camera/ui/BitmapTexture.java delete mode 100644 src/com/android/camera/ui/FrameTexture.java diff --git a/src/com/android/camera/ui/AbstractIndicator.java b/src/com/android/camera/ui/AbstractIndicator.java index d0766ff..1608e80 100644 --- a/src/com/android/camera/ui/AbstractIndicator.java +++ b/src/com/android/camera/ui/AbstractIndicator.java @@ -28,7 +28,7 @@ abstract class AbstractIndicator extends GLView { private static final int DEFAULT_PADDING = 3; private int mOrientation = 0; - abstract protected Texture getIcon(); + abstract protected BitmapTexture getIcon(); public AbstractIndicator(Context context) { int padding = GLRootView.dpToPixel(context, DEFAULT_PADDING); @@ -37,7 +37,7 @@ abstract class AbstractIndicator extends GLView { @Override protected void onMeasure(int widthSpec, int heightSpec) { - Texture icon = getIcon(); + BitmapTexture icon = getIcon(); new MeasureHelper(this) .setPreferredContentSize(icon.getWidth(), icon.getHeight()) .measure(widthSpec, heightSpec); @@ -45,7 +45,7 @@ abstract class AbstractIndicator extends GLView { @Override protected void render(GLRootView root, GL11 gl) { - Texture icon = getIcon(); + BitmapTexture icon = getIcon(); if (icon != null) { Rect p = mPaddings; int width = getWidth() - p.left - p.right; diff --git a/src/com/android/camera/ui/BasicTexture.java b/src/com/android/camera/ui/BasicTexture.java new file mode 100644 index 0000000..291b84a --- /dev/null +++ b/src/com/android/camera/ui/BasicTexture.java @@ -0,0 +1,77 @@ +package com.android.camera.ui; + +import javax.microedition.khronos.opengles.GL11; + +abstract class BasicTexture implements Texture { + + protected static final int UNSPECIFIED = -1; + + public static final int STATE_UNLOADED = 0; + public static final int STATE_LOADED = 1; + public static final int STATE_ERROR = -1; + + protected GL11 mGL; + + protected int mId; + protected int mState; + + protected int mWidth = UNSPECIFIED; + protected int mHeight = UNSPECIFIED; + + protected int mTextureWidth; + protected int mTextureHeight; + + protected BasicTexture(GL11 gl, int id, int state) { + mGL = gl; + mId = id; + mState = state; + } + + protected BasicTexture() { + this(null, 0, STATE_UNLOADED); + } + + protected void setSize(int width, int height) { + mWidth = width; + mHeight = height; + } + + /** + * Sets the size of the texture. Due to the limit of OpenGL, the texture + * size must be of power of 2, the size of the content may not be the size + * of the texture. + */ + protected void setTextureSize(int width, int height) { + mTextureWidth = width; + mTextureHeight = height; + } + + public int getId() { + return mId; + } + + public int getWidth() { + return mWidth; + } + + public int getHeight() { + return mHeight; + } + + public void deleteFromGL() { + if (mState == STATE_LOADED) { + mGL.glDeleteTextures(1, new int[]{mId}, 0); + } + mState = STATE_UNLOADED; + } + + public void draw(GLRootView root, int x, int y) { + root.drawTexture(this, x, y, mWidth, mHeight); + } + + public void draw(GLRootView root, int x, int y, int w, int h) { + root.drawTexture(this, x, y, w, h); + } + + abstract protected boolean bind(GLRootView root, GL11 gl); +} diff --git a/src/com/android/camera/ui/BitmapTexture.java b/src/com/android/camera/ui/BitmapTexture.java new file mode 100644 index 0000000..c3a4139 --- /dev/null +++ b/src/com/android/camera/ui/BitmapTexture.java @@ -0,0 +1,111 @@ +package com.android.camera.ui; + +import com.android.camera.Util; + +import android.graphics.Bitmap; +import android.opengl.GLUtils; + +import javax.microedition.khronos.opengles.GL11; +import javax.microedition.khronos.opengles.GL11Ext; + +abstract class BitmapTexture extends BasicTexture { + + @SuppressWarnings("unused") + private static final String TAG = "Texture"; + + protected BitmapTexture() { + super(null, 0, STATE_UNLOADED); + } + + @Override + public int getWidth() { + if (mWidth == UNSPECIFIED) getBitmap(); + return mWidth; + } + + @Override + public int getHeight() { + if (mWidth == UNSPECIFIED) getBitmap(); + return mHeight; + } + + protected abstract Bitmap getBitmap(); + + protected abstract void freeBitmap(Bitmap bitmap); + + private void uploadToGL(GL11 gl) throws GLOutOfMemoryException { + Bitmap bitmap = getBitmap(); + int glError = GL11.GL_NO_ERROR; + if (bitmap != null) { + int[] textureId = new int[1]; + try { + // Define a vertically flipped crop rectangle for + // OES_draw_texture. + int width = bitmap.getWidth(); + int height = bitmap.getHeight(); + int[] cropRect = {0, height, width, -height}; + + // Upload the bitmap to a new texture. + gl.glGenTextures(1, textureId, 0); + gl.glBindTexture(GL11.GL_TEXTURE_2D, textureId[0]); + gl.glTexParameteriv(GL11.GL_TEXTURE_2D, + GL11Ext.GL_TEXTURE_CROP_RECT_OES, cropRect, 0); + gl.glTexParameteri(GL11.GL_TEXTURE_2D, + GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP_TO_EDGE); + gl.glTexParameteri(GL11.GL_TEXTURE_2D, + GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP_TO_EDGE); + gl.glTexParameterf(GL11.GL_TEXTURE_2D, + GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); + gl.glTexParameterf(GL11.GL_TEXTURE_2D, + GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); + + int widthExt = Util.nextPowerOf2(width); + int heightExt = Util.nextPowerOf2(height); + int format = GLUtils.getInternalFormat(bitmap); + int type = GLUtils.getType(bitmap); + + mTextureWidth = widthExt; + mTextureHeight = heightExt; + gl.glTexImage2D(GL11.GL_TEXTURE_2D, 0, format, + widthExt, heightExt, 0, format, type, null); + GLUtils.texSubImage2D( + GL11.GL_TEXTURE_2D, 0, 0, 0, bitmap, format, type); + } finally { + freeBitmap(bitmap); + } + if (glError == GL11.GL_OUT_OF_MEMORY) { + throw new GLOutOfMemoryException(); + } + if (glError != GL11.GL_NO_ERROR) { + mId = 0; + mState = STATE_UNLOADED; + throw new RuntimeException( + "Texture upload fail, glError " + glError); + } else { + // Update texture state. + mGL = gl; + mId = textureId[0]; + mState = BitmapTexture.STATE_LOADED; + } + } else { + mState = STATE_ERROR; + throw new RuntimeException("Texture load fail, no bitmap"); + } + } + + @Override + protected boolean bind(GLRootView root, GL11 gl) { + if (mState == BitmapTexture.STATE_UNLOADED || mGL != gl) { + mState = BitmapTexture.STATE_UNLOADED; + try { + uploadToGL(gl); + } catch (GLOutOfMemoryException e) { + root.handleLowMemory(); + return false; + } + } else { + gl.glBindTexture(GL11.GL_TEXTURE_2D, getId()); + } + return true; + } +} diff --git a/src/com/android/camera/ui/CanvasTexture.java b/src/com/android/camera/ui/CanvasTexture.java index 121de28..e7c805f 100644 --- a/src/com/android/camera/ui/CanvasTexture.java +++ b/src/com/android/camera/ui/CanvasTexture.java @@ -21,7 +21,7 @@ import android.graphics.Canvas; import android.graphics.Bitmap.Config; /** Using a canvas to draw the texture */ -abstract class CanvasTexture extends Texture { +abstract class CanvasTexture extends BitmapTexture { protected Canvas mCanvas; public CanvasTexture(int width, int height) { diff --git a/src/com/android/camera/ui/ColorTexture.java b/src/com/android/camera/ui/ColorTexture.java index 12985a1..252df87 100644 --- a/src/com/android/camera/ui/ColorTexture.java +++ b/src/com/android/camera/ui/ColorTexture.java @@ -16,35 +16,18 @@ package com.android.camera.ui; -import android.graphics.Bitmap; -import android.graphics.Rect; +class ColorTexture implements Texture { -class ColorTexture extends FrameTexture { - - private static final Rect EMPTY_PADDINGS = new Rect(); private int mColor; public ColorTexture(int color) { mColor = color; } - @Override - public Rect getPaddings() { - return EMPTY_PADDINGS; - } - - @Override - protected void freeBitmap(Bitmap bitmap) { - throw new UnsupportedOperationException(); - } - - @Override - protected Bitmap getBitmap() { - throw new UnsupportedOperationException(); + public void draw(GLRootView root, int x, int y) { } - @Override - public void draw(GLRootView root, int x, int y) { - root.drawColor(x, y, mWidth, mHeight, mColor); + public void draw(GLRootView root, int x, int y, int w, int h) { + root.drawColor(x, y, w, h, mColor); } } diff --git a/src/com/android/camera/ui/FrameTexture.java b/src/com/android/camera/ui/FrameTexture.java deleted file mode 100644 index a540240..0000000 --- a/src/com/android/camera/ui/FrameTexture.java +++ /dev/null @@ -1,38 +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.camera.ui; - -import android.graphics.Rect; - -import javax.microedition.khronos.opengles.GL11; - -abstract class FrameTexture extends Texture { - - public FrameTexture() { - } - - public FrameTexture(GL11 gl, int id, int state) { - super(gl, id, state); - } - - @Override - public void setSize(int width, int height) { - super.setSize(width, height); - } - - abstract public Rect getPaddings(); -} diff --git a/src/com/android/camera/ui/GLListView.java b/src/com/android/camera/ui/GLListView.java index 412ed8a..c1bc11a 100644 --- a/src/com/android/camera/ui/GLListView.java +++ b/src/com/android/camera/ui/GLListView.java @@ -48,7 +48,7 @@ class GLListView extends GLView { private int mHighlightIndex = INDEX_NONE; private GLView mHighlightView; - private FrameTexture mHighLight; + private Texture mHighLight; private NinePatchTexture mScrollbar; private int mVisibleStart = 0; // inclusive @@ -125,7 +125,7 @@ class GLListView extends GLView { invalidate(); } - public void setHighLight(FrameTexture highLight) { + public void setHighLight(Texture highLight) { mHighLight = highLight; } @@ -140,13 +140,13 @@ class GLListView extends GLView { } private boolean drawWithAnimation(GLRootView root, - Texture texture, int x, int y, Animation anim) { + Texture texture, int x, int y, int w, int h, Animation anim) { long now = root.currentAnimationTimeMillis(); Transformation temp = root.obtainTransformation(); boolean more = anim.getTransformation(now, temp); Transformation transformation = root.pushTransform(); transformation.compose(temp); - texture.draw(root, x, y); + texture.draw(root, x, y, w, h); invalidate(); root.popTransform(); return more; @@ -161,26 +161,27 @@ class GLListView extends GLView { if (mHighLight != null) { int width = bounds.width(); int height = bounds.height(); - mHighLight.setSize(width, height); mHighLight.draw(root, - bounds.left - mScrollX, bounds.top - mScrollY); + bounds.left - mScrollX, bounds.top - mScrollY, + width, height); } } super.render(root, gl); root.clearClip(); if (mScrollBarAnimation != null || mScrollBarVisible) { - int width = mScrollbar.getIntrinsicWidth(); + int width = mScrollbar.getWidth(); int height = getHeight() * getHeight() / mScrollHeight; int yoffset = mScrollY * getHeight() / mScrollHeight; - mScrollbar.setSize(width, height); if (mScrollBarAnimation != null) { - if (!drawWithAnimation(root, mScrollbar, - getWidth() - width, yoffset, mScrollBarAnimation)) { + if (!drawWithAnimation( + root, mScrollbar, getWidth() - width, yoffset, + width, height, mScrollBarAnimation)) { mScrollBarAnimation = null; } } else { - mScrollbar.draw(root, getWidth() - width, yoffset); + mScrollbar.draw( + root, getWidth() - width, yoffset, width, height); } } if (mScroller.computeScrollOffset()) { diff --git a/src/com/android/camera/ui/GLOptionHeader.java b/src/com/android/camera/ui/GLOptionHeader.java index fa91284..c702943 100644 --- a/src/com/android/camera/ui/GLOptionHeader.java +++ b/src/com/android/camera/ui/GLOptionHeader.java @@ -33,7 +33,7 @@ class GLOptionHeader extends GLView { private static int sVerticalPaddings; private final StringTexture mTitle; - private FrameTexture mBackground; + private Texture mBackground; private static void initializeStaticVariables(Context context) { if (sHorizontalPaddings >= 0) return; @@ -51,7 +51,7 @@ class GLOptionHeader extends GLView { sVerticalPaddings, sHorizontalPaddings, sVerticalPaddings); } - public void setBackground(FrameTexture background) { + public void setBackground(Texture background) { if (mBackground == background) return; mBackground = background; invalidate(); @@ -67,8 +67,7 @@ class GLOptionHeader extends GLView { @Override protected void render(GLRootView root, GL11 gl) { if (mBackground != null) { - mBackground.setSize(getWidth(), getHeight()); - mBackground.draw(root, 0, 0); + mBackground.draw(root, 0, 0, getWidth(), getHeight()); } Rect p = mPaddings; mTitle.draw(root, p.left, p.top); diff --git a/src/com/android/camera/ui/GLRootView.java b/src/com/android/camera/ui/GLRootView.java index dc65c85..e7ac5e3 100644 --- a/src/com/android/camera/ui/GLRootView.java +++ b/src/com/android/camera/ui/GLRootView.java @@ -323,7 +323,7 @@ public class GLRootView extends GLSurfaceView drawRect(x, y, width, height, matrix); } - private static void putRectengle(float x, float y, + private static void putRectangle(float x, float y, float width, float height, float[] buffer, ByteBuffer pointer) { buffer[0] = x; buffer[1] = y; @@ -341,7 +341,7 @@ public class GLRootView extends GLSurfaceView GL11 gl = mGL; gl.glPushMatrix(); gl.glMultMatrixf(toGLMatrix(matrix), 0); - putRectengle(x, y, width, height, mXyBuffer, mXyPointer); + putRectangle(x, y, width, height, mXyBuffer, mXyPointer); gl.glDrawArrays(GL11.GL_TRIANGLE_STRIP, 0, 4); gl.glPopMatrix(); } @@ -367,8 +367,8 @@ public class GLRootView extends GLSurfaceView float divU[] = mNinePatchU; float divV[] = mNinePatchV; - int nx = stretch(divX, divU, chunk.mDivX, tex.getIntrinsicWidth(), width); - int ny = stretch(divY, divV, chunk.mDivY, tex.getIntrinsicHeight(), height); + int nx = stretch(divX, divU, chunk.mDivX, tex.getWidth(), width); + int ny = stretch(divY, divV, chunk.mDivY, tex.getHeight(), height); setAlphaValue(mTransformation.getAlpha()); Matrix matrix = mTransformation.getMatrix(); @@ -566,17 +566,13 @@ public class GLRootView extends GLSurfaceView } public void drawColor(int x, int y, int width, int height, int color) { - drawColor(x, y, width, height, color, mTransformation.getAlpha()); - } - - public void drawColor(int x, int y, - int width, int height, int color, float alpha) { + float alpha = mTransformation.getAlpha(); GL11 gl = mGL; if (mTexture2DEnabled) { // Set mLastAlpha to an invalid value, so that it will reset again // in setAlphaValue(float) later. mLastAlpha = -1.0f; - mGL.glDisable(GL11.GL_TEXTURE_2D); + gl.glDisable(GL11.GL_TEXTURE_2D); mTexture2DEnabled = false; } alpha /= 256.0f; @@ -586,7 +582,12 @@ public class GLRootView extends GLSurfaceView } public void drawTexture( - Texture texture, int x, int y, int width, int height, float alpha) { + BasicTexture texture, int x, int y, int width, int height) { + drawTexture(texture, x, y, width, height, mTransformation.getAlpha()); + } + + public void drawTexture(BasicTexture texture, + int x, int y, int width, int height, float alpha) { if (!mTexture2DEnabled) { mGL.glEnable(GL11.GL_TEXTURE_2D); @@ -604,8 +605,10 @@ public class GLRootView extends GLSurfaceView // Test whether it has been rotated or flipped, if so, glDrawTexiOES // won't work if (isMatrixRotatedOrFlipped(mMatrixValues)) { - texture.getTextureCoords(mUvBuffer, 0); - mUvPointer.asFloatBuffer().put(mUvBuffer, 0, 8).position(0); + putRectangle(0, 0, + (texture.mWidth - 0.5f) / texture.mTextureWidth, + (texture.mHeight - 0.5f) / texture.mTextureHeight, + mUvBuffer, mUvPointer); setAlphaValue(alpha); drawRect(x, y, width, height, mMatrixValues); } else { @@ -627,11 +630,6 @@ public class GLRootView extends GLSurfaceView || matrix[Matrix.MSCALE_X] < 0 || matrix[Matrix.MSCALE_Y] > 0; } - public void drawTexture( - Texture texture, int x, int y, int width, int height) { - drawTexture(texture, x, y, width, height, mTransformation.getAlpha()); - } - public synchronized void onDrawFrame(GL10 gl) { if (ENABLE_FPS_TEST) { long now = System.nanoTime(); diff --git a/src/com/android/camera/ui/IndicatorBar.java b/src/com/android/camera/ui/IndicatorBar.java index 4a07966..95098b9 100644 --- a/src/com/android/camera/ui/IndicatorBar.java +++ b/src/com/android/camera/ui/IndicatorBar.java @@ -28,7 +28,7 @@ class IndicatorBar extends GLView { public static final int INDEX_NONE = -1; private NinePatchTexture mBackground; - private FrameTexture mHighlight; + private Texture mHighlight; private int mSelectedIndex = INDEX_NONE; private OnItemSelectedListener mSelectedListener; @@ -39,15 +39,14 @@ class IndicatorBar extends GLView { private class Background extends GLView { @Override protected void render(GLRootView root, GL11 gl) { - mBackground.setSize(getWidth(), getHeight()); - mBackground.draw(root, 0, 0); + mBackground.draw(root, 0, 0, getWidth(), getHeight()); if (mActivated && mSelectedIndex != INDEX_NONE && mHighlight != null) { Rect bounds = IndicatorBar.this.getComponent( mSelectedIndex + 1).mBounds; - mHighlight.setSize(bounds.width(), bounds.height()); - mHighlight.draw(root, bounds.left, bounds.top); + mHighlight.draw(root, bounds.left, bounds.top, + bounds.width(), bounds.height()); } } } @@ -85,7 +84,7 @@ class IndicatorBar extends GLView { invalidate(); } - public void setHighlight(FrameTexture highlight) { + public void setHighlight(Texture highlight) { if (mHighlight == highlight) return; mHighlight = highlight; invalidate(); diff --git a/src/com/android/camera/ui/NinePatchTexture.java b/src/com/android/camera/ui/NinePatchTexture.java index 1fae5f8..1321ed8 100644 --- a/src/com/android/camera/ui/NinePatchTexture.java +++ b/src/com/android/camera/ui/NinePatchTexture.java @@ -16,30 +16,16 @@ package com.android.camera.ui; -import com.android.camera.Util; - import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Rect; -class NinePatchTexture extends FrameTexture { - private final Context mContext; - private final int mResId; - - private Bitmap mBitmap; +class NinePatchTexture extends ResourceTexture { private NinePatchChunk mChunk; - private int mIntrinsicWidth = -1; - private int mIntrinsicHeight = -1; public NinePatchTexture(Context context, int resId) { - this.mContext = context; - this.mResId = resId; - } - - @Override - public void getTextureCoords(float coord[], int offset) { - throw new UnsupportedOperationException(); + super(context, resId); } @Override @@ -51,8 +37,7 @@ class NinePatchTexture extends FrameTexture { Bitmap bitmap = BitmapFactory.decodeResource( mContext.getResources(), mResId, options); mBitmap = bitmap; - mIntrinsicWidth = bitmap.getWidth(); - mIntrinsicHeight = bitmap.getHeight(); + setSize(bitmap.getWidth(), bitmap.getHeight()); mChunk = NinePatchChunk.deserialize(bitmap.getNinePatchChunk()); if (mChunk == null) { throw new RuntimeException("invalid nine-patch image: " + mResId); @@ -60,24 +45,6 @@ class NinePatchTexture extends FrameTexture { return bitmap; } - @Override - protected void freeBitmap(Bitmap bitmap) { - Util.Assert(bitmap == mBitmap); - mBitmap.recycle(); - mBitmap = null; - } - - public int getIntrinsicWidth() { - if (mIntrinsicWidth < 0) getBitmap(); - return mIntrinsicWidth; - } - - public int getIntrinsicHeight() { - if (mIntrinsicHeight < 0) getBitmap(); - return mIntrinsicHeight; - } - - @Override public Rect getPaddings() { // get the paddings from nine patch if (mChunk == null) getBitmap(); @@ -90,7 +57,7 @@ class NinePatchTexture extends FrameTexture { } @Override - public void draw(GLRootView root, int x, int y) { - root.drawNinePatch(this, x, y, mWidth, mHeight); + public void draw(GLRootView root, int x, int y, int w, int h) { + root.drawNinePatch(this, x, y, w, h); } } diff --git a/src/com/android/camera/ui/PopupWindow.java b/src/com/android/camera/ui/PopupWindow.java index e2fb5cd..c2bf533 100644 --- a/src/com/android/camera/ui/PopupWindow.java +++ b/src/com/android/camera/ui/PopupWindow.java @@ -28,14 +28,14 @@ import javax.microedition.khronos.opengles.GL11; class PopupWindow extends GLView { - protected Texture mAnchor; + protected BitmapTexture mAnchor; protected int mAnchorOffset; protected int mAnchorPosition; private final RotatePane mRotatePane = new RotatePane(); private RawTexture mBackupTexture; - protected FrameTexture mBackground; + protected Texture mBackground; private boolean mUsingStencil; public PopupWindow() { @@ -48,18 +48,18 @@ class PopupWindow extends GLView { mUsingStencil = root.getEGLConfigChooser().getStencilBits() > 0; } - public void setBackground(FrameTexture background) { + public void setBackground(Texture background) { if (background == mBackground) return; mBackground = background; - if (background != null) { - setPaddings(mBackground.getPaddings()); + if (background != null && background instanceof NinePatchTexture) { + setPaddings(((NinePatchTexture) mBackground).getPaddings()); } else { setPaddings(0, 0, 0, 0); } invalidate(); } - public void setAnchor(Texture anchor, int offset) { + public void setAnchor(BitmapTexture anchor, int offset) { mAnchor = anchor; mAnchorOffset = offset; } @@ -129,8 +129,8 @@ class PopupWindow extends GLView { } if (mBackground != null) { - mBackground.setSize(width - aWidth + mAnchorOffset, height); - mBackground.draw(root, 0, 0); + mBackground.draw(root, 0, 0, + width - aWidth + mAnchorOffset, height); } } @@ -164,12 +164,12 @@ class PopupWindow extends GLView { } if (mBackground != null) { - mBackground.setSize(width - aWidth + mAnchorOffset, height); - mBackground.draw(root, 0, 0); + mBackground.draw(root, 0, 0, + width - aWidth + mAnchorOffset, height); } gl.glBlendFunc(GL11.GL_ONE, GL11.GL_ZERO); - backup.draw(root, aXoffset, aYoffset, aWidth, aHeight, 1); + backup.drawBack(root, aXoffset, aYoffset, aWidth, aHeight); gl.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA); } diff --git a/src/com/android/camera/ui/RawTexture.java b/src/com/android/camera/ui/RawTexture.java index c42cd93..c6073a1 100644 --- a/src/com/android/camera/ui/RawTexture.java +++ b/src/com/android/camera/ui/RawTexture.java @@ -16,11 +16,10 @@ package com.android.camera.ui; -import android.graphics.Bitmap; import javax.microedition.khronos.opengles.GL11; -class RawTexture extends Texture { +class RawTexture extends BasicTexture { private RawTexture(GL11 gl, int id) { super(gl, id, STATE_LOADED); @@ -41,16 +40,6 @@ class RawTexture extends Texture { } @Override - protected void freeBitmap(Bitmap bitmap) { - throw new UnsupportedOperationException(); - } - - @Override - protected Bitmap getBitmap() { - throw new UnsupportedOperationException(); - } - - @Override protected boolean bind(GLRootView glRootView, GL11 gl) { if (mGL == gl) { gl.glBindTexture(GL11.GL_TEXTURE_2D, getId()); @@ -58,4 +47,8 @@ class RawTexture extends Texture { } return false; } + + public void drawBack(GLRootView root, int x, int y, int w, int h) { + root.drawTexture(this, x, y, w, h, 1f); + } } diff --git a/src/com/android/camera/ui/ResourceTexture.java b/src/com/android/camera/ui/ResourceTexture.java index b0d6cd5..4136dfa 100644 --- a/src/com/android/camera/ui/ResourceTexture.java +++ b/src/com/android/camera/ui/ResourceTexture.java @@ -22,11 +22,11 @@ import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; -class ResourceTexture extends Texture { +class ResourceTexture extends BitmapTexture { - private final Context mContext; - private final int mResId; - private Bitmap mBitmap; + protected final Context mContext; + protected final int mResId; + protected Bitmap mBitmap; public ResourceTexture(Context context, int resId) { mContext = Util.checkNotNull(context); @@ -45,26 +45,9 @@ class ResourceTexture extends Texture { } @Override - public int getHeight() { - if (mHeight == UNSPECIFIED) { - getBitmap(); - } - return mHeight; - } - - @Override - public int getWidth() { - if (mHeight == UNSPECIFIED) { - getBitmap(); - } - return mWidth; - } - - @Override protected void freeBitmap(Bitmap bitmap) { Util.Assert(bitmap == mBitmap); bitmap.recycle(); mBitmap = null; } - } diff --git a/src/com/android/camera/ui/Texture.java b/src/com/android/camera/ui/Texture.java index ba3a3d2..c0d841b 100644 --- a/src/com/android/camera/ui/Texture.java +++ b/src/com/android/camera/ui/Texture.java @@ -16,181 +16,7 @@ package com.android.camera.ui; -import com.android.camera.Util; - -import android.graphics.Bitmap; -import android.opengl.GLUtils; - -import javax.microedition.khronos.opengles.GL11; -import javax.microedition.khronos.opengles.GL11Ext; - -abstract class Texture { - - @SuppressWarnings("unused") - private static final String TAG = "Texture"; - protected static final int UNSPECIFIED = -1; - - public static final int STATE_UNLOADED = 0; - public static final int STATE_LOADED = 1; - public static final int STATE_ERROR = -1; - - protected GL11 mGL; - - protected int mId; - protected int mState; - - protected int mWidth = UNSPECIFIED; - protected int mHeight = UNSPECIFIED; - - protected int mTextureWidth; - protected int mTextureHeight; - - protected Texture(GL11 gl, int id, int state) { - mGL = gl; - mId = id; - mState = state; - } - - protected Texture() { - this(null, 0, STATE_UNLOADED); - } - - protected void setSize(int width, int height) { - mWidth = width; - mHeight = height; - } - - /** - * Sets the size of the texture. Due to the limit of OpenGL, the texture - * size must be of power of 2, the size of the content may not be the size - * of the texture. - */ - protected void setTextureSize(int width, int height) { - mTextureWidth = width; - mTextureHeight = height; - } - - public int getId() { - return mId; - } - - public int getWidth() { - return mWidth; - } - - public int getHeight() { - return mHeight; - } - - protected abstract Bitmap getBitmap(); - - protected abstract void freeBitmap(Bitmap bitmap); - - public void deleteFromGL() { - if (mState == STATE_LOADED) { - mGL.glDeleteTextures(1, new int[]{mId}, 0); - } - mState = STATE_UNLOADED; - } - - private void uploadToGL(GL11 gl) throws GLOutOfMemoryException { - Bitmap bitmap = getBitmap(); - int glError = GL11.GL_NO_ERROR; - if (bitmap != null) { - int[] textureId = new int[1]; - try { - // Define a vertically flipped crop rectangle for - // OES_draw_texture. - int width = bitmap.getWidth(); - int height = bitmap.getHeight(); - int[] cropRect = {0, height, width, -height}; - - // Upload the bitmap to a new texture. - gl.glGenTextures(1, textureId, 0); - gl.glBindTexture(GL11.GL_TEXTURE_2D, textureId[0]); - gl.glTexParameteriv(GL11.GL_TEXTURE_2D, - GL11Ext.GL_TEXTURE_CROP_RECT_OES, cropRect, 0); - gl.glTexParameteri(GL11.GL_TEXTURE_2D, - GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP_TO_EDGE); - gl.glTexParameteri(GL11.GL_TEXTURE_2D, - GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP_TO_EDGE); - gl.glTexParameterf(GL11.GL_TEXTURE_2D, - GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); - gl.glTexParameterf(GL11.GL_TEXTURE_2D, - GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); - - int widthExt = Util.nextPowerOf2(width); - int heightExt = Util.nextPowerOf2(height); - int format = GLUtils.getInternalFormat(bitmap); - int type = GLUtils.getType(bitmap); - - mTextureWidth = widthExt; - mTextureHeight = heightExt; - gl.glTexImage2D(GL11.GL_TEXTURE_2D, 0, format, - widthExt, heightExt, 0, format, type, null); - GLUtils.texSubImage2D( - GL11.GL_TEXTURE_2D, 0, 0, 0, bitmap, format, type); - } finally { - freeBitmap(bitmap); - } - if (glError == GL11.GL_OUT_OF_MEMORY) { - throw new GLOutOfMemoryException(); - } - if (glError != GL11.GL_NO_ERROR) { - mId = 0; - mState = STATE_UNLOADED; - throw new RuntimeException( - "Texture upload fail, glError " + glError); - } else { - // Update texture state. - mGL = gl; - mId = textureId[0]; - mState = Texture.STATE_LOADED; - } - } else { - mState = STATE_ERROR; - throw new RuntimeException("Texture load fail, no bitmap"); - } - } - - public void draw(GLRootView root, int x, int y) { - root.drawTexture(this, x, y, mWidth, mHeight); - } - - public void draw(GLRootView root, int x, int y, int w, int h, float alpha) { - root.drawTexture(this, x, y, w, h, alpha); - } - - protected boolean bind(GLRootView root, GL11 gl) { - if (mState == Texture.STATE_UNLOADED || mGL != gl) { - mState = Texture.STATE_UNLOADED; - try { - uploadToGL(gl); - } catch (GLOutOfMemoryException e) { - root.handleLowMemory(); - return false; - } - } else { - gl.glBindTexture(GL11.GL_TEXTURE_2D, getId()); - } - return true; - } - - public void getTextureCoords(float coord[], int offset) { - // Shrinks the texture coordinates inner by 0.5 pixel so that GL won't - // sample on garbage data. - float left = 0.5f / mTextureWidth; - float right = (mWidth - 0.5f) / mTextureWidth; - float top = 0.5f / mTextureHeight; - float bottom = (mHeight - 0.5f) / mTextureHeight; - - coord[offset++] = left; - coord[offset++] = top; - coord[offset++] = right; - coord[offset++] = top; - coord[offset++] = left; - coord[offset++] = bottom; - coord[offset++] = right; - coord[offset] = bottom; - } +interface Texture { + public void draw(GLRootView root, int x, int y); + public void draw(GLRootView root, int x, int y, int w, int h); } diff --git a/src/com/android/camera/ui/ZoomController.java b/src/com/android/camera/ui/ZoomController.java index 3ef1ca0..9b9c2f1 100644 --- a/src/com/android/camera/ui/ZoomController.java +++ b/src/com/android/camera/ui/ZoomController.java @@ -49,9 +49,9 @@ class ZoomController extends GLView { private static float sToleranceRadius; private static NinePatchTexture sBackground; - private static Texture sSlider; - private static Texture sTickMark; - private static Texture sFineTickMark; + private static BitmapTexture sSlider; + private static BitmapTexture sTickMark; + private static BitmapTexture sFineTickMark; private StringTexture mTickLabels[]; private float mRatios[]; @@ -199,7 +199,7 @@ class ZoomController extends GLView { + Math.max(sSlider.getHeight(), mMaxLabelHeight); int width = mMaxLabelWidth + sHorizontalPadding + sTickMark.getWidth() - + sHorizontalPadding + sBackground.getIntrinsicWidth(); + + sHorizontalPadding + sBackground.getWidth(); height = Math.max(sMinimalHeight, height); new MeasureHelper(this) @@ -221,14 +221,14 @@ class ZoomController extends GLView { int xoffset = mPaddings.left + mMaxLabelWidth; float yoffset = mSliderBottom - sSlider.getHeight() / 2; for (int i = 0, n = mTickLabels.length; i < n; ++i) { - Texture t = mTickLabels[i]; + BitmapTexture t = mTickLabels[i]; t.draw(root, xoffset - t.getWidth(), (int) (yoffset - t.getHeight() / 2)); yoffset -= labelStep * gap; } // render the main tick marks - Texture tickMark = sTickMark; + BitmapTexture tickMark = sTickMark; xoffset += sHorizontalPadding; yoffset = mSliderBottom - sSlider.getHeight() / 2; int halfHeight = tickMark.getHeight() / 2; @@ -256,8 +256,7 @@ class ZoomController extends GLView { int left = mSliderLeft; int bottom = mSliderBottom; int top = mSliderTop; - sBackground.setSize(sBackground.getIntrinsicWidth(), bottom - top); - sBackground.draw(root, left, top); + sBackground.draw(root, left, top, sBackground.getWidth(), bottom - top); if (mSliderPosition == INVALID_POSITION) { sSlider.draw(root, left, (int) diff --git a/src/com/android/camera/ui/ZoomIndicator.java b/src/com/android/camera/ui/ZoomIndicator.java index 9b2e7f3..ce6bef8 100644 --- a/src/com/android/camera/ui/ZoomIndicator.java +++ b/src/com/android/camera/ui/ZoomIndicator.java @@ -54,7 +54,7 @@ class ZoomIndicator extends AbstractIndicator { int n = mZoomRatios == null ? 0: mZoomRatios.length; for (int i = 0; i < n; ++i) { float value = mZoomRatios[i]; - Texture tex = StringTexture.newInstance( + BitmapTexture tex = StringTexture.newInstance( sZoomFormat.format(value), mFontSize, FONT_COLOR); if (maxWidth < tex.getWidth()) maxWidth = tex.getWidth(); if (maxHeight < tex.getHeight()) maxHeight = tex.getHeight(); @@ -65,7 +65,7 @@ class ZoomIndicator extends AbstractIndicator { } @Override - protected Texture getIcon() { + protected BitmapTexture getIcon() { if (mDrawIndex != mZoomIndex) { mDrawIndex = mZoomIndex; if (mTitle != null) mTitle.deleteFromGL(); -- 2.11.0