summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d/ui
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/gallery3d/ui')
-rw-r--r--src/com/android/gallery3d/ui/AbstractSlotRenderer.java5
-rw-r--r--src/com/android/gallery3d/ui/ActionModeHandler.java14
-rw-r--r--src/com/android/gallery3d/ui/AlbumSetSlidingWindow.java4
-rw-r--r--src/com/android/gallery3d/ui/AlbumSetSlotRenderer.java7
-rw-r--r--src/com/android/gallery3d/ui/AlbumSlidingWindow.java2
-rw-r--r--src/com/android/gallery3d/ui/AlbumSlotRenderer.java5
-rw-r--r--src/com/android/gallery3d/ui/BasicTexture.java205
-rw-r--r--src/com/android/gallery3d/ui/BitmapScreenNail.java3
-rw-r--r--src/com/android/gallery3d/ui/BitmapTexture.java54
-rw-r--r--src/com/android/gallery3d/ui/BitmapTileProvider.java11
-rw-r--r--src/com/android/gallery3d/ui/CanvasTexture.java52
-rw-r--r--src/com/android/gallery3d/ui/ColorTexture.java63
-rw-r--r--src/com/android/gallery3d/ui/CropView.java801
-rw-r--r--src/com/android/gallery3d/ui/DetailsHelper.java12
-rw-r--r--src/com/android/gallery3d/ui/DialogDetailsView.java46
-rw-r--r--src/com/android/gallery3d/ui/EdgeEffect.java2
-rw-r--r--src/com/android/gallery3d/ui/EdgeView.java2
-rw-r--r--src/com/android/gallery3d/ui/ExtTexture.java89
-rw-r--r--src/com/android/gallery3d/ui/FadeInTexture.java42
-rw-r--r--src/com/android/gallery3d/ui/FadeOutTexture.java41
-rw-r--r--src/com/android/gallery3d/ui/FadeTexture.java80
-rw-r--r--src/com/android/gallery3d/ui/GLCanvas.java132
-rw-r--r--src/com/android/gallery3d/ui/GLCanvasImpl.java920
-rw-r--r--src/com/android/gallery3d/ui/GLId.java50
-rw-r--r--src/com/android/gallery3d/ui/GLPaint.java42
-rw-r--r--src/com/android/gallery3d/ui/GLRoot.java1
-rw-r--r--src/com/android/gallery3d/ui/GLRootView.java7
-rw-r--r--src/com/android/gallery3d/ui/GLView.java1
-rw-r--r--src/com/android/gallery3d/ui/GalleryEGLConfigChooser.java32
-rw-r--r--src/com/android/gallery3d/ui/GestureRecognizer.java4
-rw-r--r--src/com/android/gallery3d/ui/Log.java1
-rw-r--r--src/com/android/gallery3d/ui/ManageCacheDrawer.java3
-rw-r--r--src/com/android/gallery3d/ui/MenuExecutor.java20
-rw-r--r--src/com/android/gallery3d/ui/MultiLineTexture.java51
-rw-r--r--src/com/android/gallery3d/ui/NinePatchChunk.java82
-rw-r--r--src/com/android/gallery3d/ui/NinePatchTexture.java440
-rw-r--r--src/com/android/gallery3d/ui/PhotoFallbackEffect.java2
-rw-r--r--src/com/android/gallery3d/ui/PhotoView.java27
-rw-r--r--src/com/android/gallery3d/ui/PreparePageFadeoutTexture.java2
-rw-r--r--src/com/android/gallery3d/ui/ProgressSpinner.java2
-rw-r--r--src/com/android/gallery3d/ui/RawTexture.java91
-rw-r--r--src/com/android/gallery3d/ui/ResourceTexture.java52
-rw-r--r--src/com/android/gallery3d/ui/ScreenNail.java2
-rw-r--r--src/com/android/gallery3d/ui/ScrollBarView.java3
-rw-r--r--src/com/android/gallery3d/ui/SlideshowView.java11
-rw-r--r--src/com/android/gallery3d/ui/SlotView.java1
-rw-r--r--src/com/android/gallery3d/ui/StringTexture.java88
-rw-r--r--src/com/android/gallery3d/ui/SurfaceTextureScreenNail.java2
-rw-r--r--src/com/android/gallery3d/ui/Texture.java43
-rw-r--r--src/com/android/gallery3d/ui/TextureUploader.java104
-rw-r--r--src/com/android/gallery3d/ui/TileImageView.java83
-rw-r--r--src/com/android/gallery3d/ui/TileImageViewAdapter.java21
-rw-r--r--src/com/android/gallery3d/ui/TiledScreenNail.java2
-rw-r--r--src/com/android/gallery3d/ui/TiledTexture.java348
-rw-r--r--src/com/android/gallery3d/ui/UndoBarView.java4
-rw-r--r--src/com/android/gallery3d/ui/UploadedTexture.java331
56 files changed, 261 insertions, 4284 deletions
diff --git a/src/com/android/gallery3d/ui/AbstractSlotRenderer.java b/src/com/android/gallery3d/ui/AbstractSlotRenderer.java
index 10b710d2d..729439dc3 100644
--- a/src/com/android/gallery3d/ui/AbstractSlotRenderer.java
+++ b/src/com/android/gallery3d/ui/AbstractSlotRenderer.java
@@ -20,6 +20,11 @@ import android.content.Context;
import android.graphics.Rect;
import com.android.gallery3d.R;
+import com.android.gallery3d.glrenderer.FadeOutTexture;
+import com.android.gallery3d.glrenderer.GLCanvas;
+import com.android.gallery3d.glrenderer.NinePatchTexture;
+import com.android.gallery3d.glrenderer.ResourceTexture;
+import com.android.gallery3d.glrenderer.Texture;
public abstract class AbstractSlotRenderer implements SlotView.SlotRenderer {
diff --git a/src/com/android/gallery3d/ui/ActionModeHandler.java b/src/com/android/gallery3d/ui/ActionModeHandler.java
index 7191599ad..9b84bf75c 100644
--- a/src/com/android/gallery3d/ui/ActionModeHandler.java
+++ b/src/com/android/gallery3d/ui/ActionModeHandler.java
@@ -408,6 +408,15 @@ public class ActionModeHandler implements Callback, PopupList.OnPopupItemClickLi
// Pass1: Deal with unexpanded media object list for menu operation.
ArrayList<MediaObject> selected = getSelectedMediaObjects(jc);
if (selected == null) {
+ mMainHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mMenuTask = null;
+ if (jc.isCancelled()) return;
+ // Disable all the operations when no item is selected
+ MenuExecutor.updateMenuOperation(mMenu, 0);
+ }
+ });
return null;
}
final int operation = computeMenuOptions(selected);
@@ -466,7 +475,12 @@ public class ActionModeHandler implements Callback, PopupList.OnPopupItemClickLi
mMenuExecutor.pause();
}
+ public void destroy() {
+ mMenuExecutor.destroy();
+ }
+
public void resume() {
if (mSelectionManager.inSelectionMode()) updateSupportedOperation();
+ mMenuExecutor.resume();
}
}
diff --git a/src/com/android/gallery3d/ui/AlbumSetSlidingWindow.java b/src/com/android/gallery3d/ui/AlbumSetSlidingWindow.java
index 80dfc919f..d5a15b4ac 100644
--- a/src/com/android/gallery3d/ui/AlbumSetSlidingWindow.java
+++ b/src/com/android/gallery3d/ui/AlbumSetSlidingWindow.java
@@ -29,6 +29,10 @@ import com.android.gallery3d.data.MediaItem;
import com.android.gallery3d.data.MediaObject;
import com.android.gallery3d.data.MediaSet;
import com.android.gallery3d.data.Path;
+import com.android.gallery3d.glrenderer.BitmapTexture;
+import com.android.gallery3d.glrenderer.Texture;
+import com.android.gallery3d.glrenderer.TextureUploader;
+import com.android.gallery3d.glrenderer.TiledTexture;
import com.android.gallery3d.util.Future;
import com.android.gallery3d.util.FutureListener;
import com.android.gallery3d.util.ThreadPool;
diff --git a/src/com/android/gallery3d/ui/AlbumSetSlotRenderer.java b/src/com/android/gallery3d/ui/AlbumSetSlotRenderer.java
index 70d7c273a..5332ef89a 100644
--- a/src/com/android/gallery3d/ui/AlbumSetSlotRenderer.java
+++ b/src/com/android/gallery3d/ui/AlbumSetSlotRenderer.java
@@ -21,6 +21,13 @@ import com.android.gallery3d.app.AbstractGalleryActivity;
import com.android.gallery3d.app.AlbumSetDataLoader;
import com.android.gallery3d.data.MediaObject;
import com.android.gallery3d.data.Path;
+import com.android.gallery3d.glrenderer.ColorTexture;
+import com.android.gallery3d.glrenderer.FadeInTexture;
+import com.android.gallery3d.glrenderer.GLCanvas;
+import com.android.gallery3d.glrenderer.ResourceTexture;
+import com.android.gallery3d.glrenderer.Texture;
+import com.android.gallery3d.glrenderer.TiledTexture;
+import com.android.gallery3d.glrenderer.UploadedTexture;
import com.android.gallery3d.ui.AlbumSetSlidingWindow.AlbumSetEntry;
public class AlbumSetSlotRenderer extends AbstractSlotRenderer {
diff --git a/src/com/android/gallery3d/ui/AlbumSlidingWindow.java b/src/com/android/gallery3d/ui/AlbumSlidingWindow.java
index 678c43251..8cd2cf500 100644
--- a/src/com/android/gallery3d/ui/AlbumSlidingWindow.java
+++ b/src/com/android/gallery3d/ui/AlbumSlidingWindow.java
@@ -27,6 +27,8 @@ import com.android.gallery3d.data.MediaItem;
import com.android.gallery3d.data.MediaObject;
import com.android.gallery3d.data.Path;
import com.android.gallery3d.data.MediaObject.PanoramaSupportCallback;
+import com.android.gallery3d.glrenderer.Texture;
+import com.android.gallery3d.glrenderer.TiledTexture;
import com.android.gallery3d.util.Future;
import com.android.gallery3d.util.FutureListener;
import com.android.gallery3d.util.JobLimiter;
diff --git a/src/com/android/gallery3d/ui/AlbumSlotRenderer.java b/src/com/android/gallery3d/ui/AlbumSlotRenderer.java
index ce5b7ac24..dc6c89b0e 100644
--- a/src/com/android/gallery3d/ui/AlbumSlotRenderer.java
+++ b/src/com/android/gallery3d/ui/AlbumSlotRenderer.java
@@ -20,6 +20,11 @@ import com.android.gallery3d.app.AbstractGalleryActivity;
import com.android.gallery3d.app.AlbumDataLoader;
import com.android.gallery3d.data.MediaObject;
import com.android.gallery3d.data.Path;
+import com.android.gallery3d.glrenderer.ColorTexture;
+import com.android.gallery3d.glrenderer.FadeInTexture;
+import com.android.gallery3d.glrenderer.GLCanvas;
+import com.android.gallery3d.glrenderer.Texture;
+import com.android.gallery3d.glrenderer.TiledTexture;
public class AlbumSlotRenderer extends AbstractSlotRenderer {
@SuppressWarnings("unused")
diff --git a/src/com/android/gallery3d/ui/BasicTexture.java b/src/com/android/gallery3d/ui/BasicTexture.java
deleted file mode 100644
index 99cf0571c..000000000
--- a/src/com/android/gallery3d/ui/BasicTexture.java
+++ /dev/null
@@ -1,205 +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.gallery3d.ui;
-
-import com.android.gallery3d.common.Utils;
-
-import java.util.WeakHashMap;
-
-// BasicTexture is a Texture corresponds to a real GL texture.
-// The state of a BasicTexture indicates whether its data is loaded to GL memory.
-// If a BasicTexture is loaded into GL memory, it has a GL texture id.
-abstract class BasicTexture implements Texture {
-
- @SuppressWarnings("unused")
- private static final String TAG = "BasicTexture";
- protected static final int UNSPECIFIED = -1;
-
- protected static final int STATE_UNLOADED = 0;
- protected static final int STATE_LOADED = 1;
- protected static final int STATE_ERROR = -1;
-
- // Log a warning if a texture is larger along a dimension
- private static final int MAX_TEXTURE_SIZE = 4096;
-
- protected int mId;
- protected int mState;
-
- protected int mWidth = UNSPECIFIED;
- protected int mHeight = UNSPECIFIED;
-
- protected int mTextureWidth;
- protected int mTextureHeight;
-
- private boolean mHasBorder;
-
- protected GLCanvas mCanvasRef = null;
- private static WeakHashMap<BasicTexture, Object> sAllTextures
- = new WeakHashMap<BasicTexture, Object>();
- private static ThreadLocal sInFinalizer = new ThreadLocal();
-
- protected BasicTexture(GLCanvas canvas, int id, int state) {
- setAssociatedCanvas(canvas);
- mId = id;
- mState = state;
- synchronized (sAllTextures) {
- sAllTextures.put(this, null);
- }
- }
-
- protected BasicTexture() {
- this(null, 0, STATE_UNLOADED);
- }
-
- protected void setAssociatedCanvas(GLCanvas canvas) {
- mCanvasRef = canvas;
- }
-
- /**
- * Sets the content size of this texture. In OpenGL, the actual texture
- * size must be of power of 2, the size of the content may be smaller.
- */
- protected void setSize(int width, int height) {
- mWidth = width;
- mHeight = height;
- mTextureWidth = Utils.nextPowerOf2(width);
- mTextureHeight = Utils.nextPowerOf2(height);
- if (mTextureWidth > MAX_TEXTURE_SIZE || mTextureHeight > MAX_TEXTURE_SIZE) {
- Log.w(TAG, String.format("texture is too large: %d x %d",
- mTextureWidth, mTextureHeight), new Exception());
- }
- }
-
- public int getId() {
- return mId;
- }
-
- @Override
- public int getWidth() {
- return mWidth;
- }
-
- @Override
- public int getHeight() {
- return mHeight;
- }
-
- // Returns the width rounded to the next power of 2.
- public int getTextureWidth() {
- return mTextureWidth;
- }
-
- // Returns the height rounded to the next power of 2.
- public int getTextureHeight() {
- return mTextureHeight;
- }
-
- // Returns true if the texture has one pixel transparent border around the
- // actual content. This is used to avoid jigged edges.
- //
- // The jigged edges appear because we use GL_CLAMP_TO_EDGE for texture wrap
- // mode (GL_CLAMP is not available in OpenGL ES), so a pixel partially
- // covered by the texture will use the color of the edge texel. If we add
- // the transparent border, the color of the edge texel will be mixed with
- // appropriate amount of transparent.
- //
- // Currently our background is black, so we can draw the thumbnails without
- // enabling blending.
- public boolean hasBorder() {
- return mHasBorder;
- }
-
- protected void setBorder(boolean hasBorder) {
- mHasBorder = hasBorder;
- }
-
- @Override
- public void draw(GLCanvas canvas, int x, int y) {
- canvas.drawTexture(this, x, y, getWidth(), getHeight());
- }
-
- @Override
- public void draw(GLCanvas canvas, int x, int y, int w, int h) {
- canvas.drawTexture(this, x, y, w, h);
- }
-
- // onBind is called before GLCanvas binds this texture.
- // It should make sure the data is uploaded to GL memory.
- abstract protected boolean onBind(GLCanvas canvas);
-
- // Returns the GL texture target for this texture (e.g. GL_TEXTURE_2D).
- abstract protected int getTarget();
-
- public boolean isLoaded() {
- return mState == STATE_LOADED;
- }
-
- // recycle() is called when the texture will never be used again,
- // so it can free all resources.
- public void recycle() {
- freeResource();
- }
-
- // yield() is called when the texture will not be used temporarily,
- // so it can free some resources.
- // The default implementation unloads the texture from GL memory, so
- // the subclass should make sure it can reload the texture to GL memory
- // later, or it will have to override this method.
- public void yield() {
- freeResource();
- }
-
- private void freeResource() {
- GLCanvas canvas = mCanvasRef;
- if (canvas != null && isLoaded()) {
- canvas.unloadTexture(this);
- }
- mState = STATE_UNLOADED;
- setAssociatedCanvas(null);
- }
-
- @Override
- protected void finalize() {
- sInFinalizer.set(BasicTexture.class);
- recycle();
- sInFinalizer.set(null);
- }
-
- // This is for deciding if we can call Bitmap's recycle().
- // We cannot call Bitmap's recycle() in finalizer because at that point
- // the finalizer of Bitmap may already be called so recycle() will crash.
- public static boolean inFinalizer() {
- return sInFinalizer.get() != null;
- }
-
- public static void yieldAllTextures() {
- synchronized (sAllTextures) {
- for (BasicTexture t : sAllTextures.keySet()) {
- t.yield();
- }
- }
- }
-
- public static void invalidateAllTextures() {
- synchronized (sAllTextures) {
- for (BasicTexture t : sAllTextures.keySet()) {
- t.mState = STATE_UNLOADED;
- t.setAssociatedCanvas(null);
- }
- }
- }
-}
diff --git a/src/com/android/gallery3d/ui/BitmapScreenNail.java b/src/com/android/gallery3d/ui/BitmapScreenNail.java
index 741eefbe3..a3d403946 100644
--- a/src/com/android/gallery3d/ui/BitmapScreenNail.java
+++ b/src/com/android/gallery3d/ui/BitmapScreenNail.java
@@ -19,6 +19,9 @@ package com.android.gallery3d.ui;
import android.graphics.Bitmap;
import android.graphics.RectF;
+import com.android.gallery3d.glrenderer.BitmapTexture;
+import com.android.gallery3d.glrenderer.GLCanvas;
+
public class BitmapScreenNail implements ScreenNail {
private final BitmapTexture mBitmapTexture;
diff --git a/src/com/android/gallery3d/ui/BitmapTexture.java b/src/com/android/gallery3d/ui/BitmapTexture.java
deleted file mode 100644
index 607544907..000000000
--- a/src/com/android/gallery3d/ui/BitmapTexture.java
+++ /dev/null
@@ -1,54 +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.gallery3d.ui;
-
-import android.graphics.Bitmap;
-
-import com.android.gallery3d.common.Utils;
-
-// BitmapTexture is a texture whose content is specified by a fixed Bitmap.
-//
-// The texture does not own the Bitmap. The user should make sure the Bitmap
-// is valid during the texture's lifetime. When the texture is recycled, it
-// does not free the Bitmap.
-public class BitmapTexture extends UploadedTexture {
- protected Bitmap mContentBitmap;
-
- public BitmapTexture(Bitmap bitmap) {
- this(bitmap, false);
- }
-
- public BitmapTexture(Bitmap bitmap, boolean hasBorder) {
- super(hasBorder);
- Utils.assertTrue(bitmap != null && !bitmap.isRecycled());
- mContentBitmap = bitmap;
- }
-
- @Override
- protected void onFreeBitmap(Bitmap bitmap) {
- // Do nothing.
- }
-
- @Override
- protected Bitmap onGetBitmap() {
- return mContentBitmap;
- }
-
- public Bitmap getBitmap() {
- return mContentBitmap;
- }
-}
diff --git a/src/com/android/gallery3d/ui/BitmapTileProvider.java b/src/com/android/gallery3d/ui/BitmapTileProvider.java
index d4c9b1d30..c3466e7fe 100644
--- a/src/com/android/gallery3d/ui/BitmapTileProvider.java
+++ b/src/com/android/gallery3d/ui/BitmapTileProvider.java
@@ -25,7 +25,7 @@ import com.android.gallery3d.data.BitmapPool;
import java.util.ArrayList;
-public class BitmapTileProvider implements TileImageView.Model {
+public class BitmapTileProvider implements TileImageView.TileSource {
private final ScreenNail mScreenNail;
private final Bitmap[] mMipmaps;
private final Config mConfig;
@@ -72,22 +72,21 @@ public class BitmapTileProvider implements TileImageView.Model {
@Override
public Bitmap getTile(int level, int x, int y, int tileSize,
- int borderSize, BitmapPool pool) {
+ BitmapPool pool) {
x >>= level;
y >>= level;
- int size = tileSize + 2 * borderSize;
Bitmap result = pool == null ? null : pool.getBitmap();
if (result == null) {
- result = Bitmap.createBitmap(size, size, mConfig);
+ result = Bitmap.createBitmap(tileSize, tileSize, mConfig);
} else {
result.eraseColor(0);
}
Bitmap mipmap = mMipmaps[level];
Canvas canvas = new Canvas(result);
- int offsetX = -x + borderSize;
- int offsetY = -y + borderSize;
+ int offsetX = -x;
+ int offsetY = -y;
canvas.drawBitmap(mipmap, offsetX, offsetY, null);
return result;
}
diff --git a/src/com/android/gallery3d/ui/CanvasTexture.java b/src/com/android/gallery3d/ui/CanvasTexture.java
deleted file mode 100644
index a2e9e48ad..000000000
--- a/src/com/android/gallery3d/ui/CanvasTexture.java
+++ /dev/null
@@ -1,52 +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.gallery3d.ui;
-
-import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
-import android.graphics.Canvas;
-
-// CanvasTexture is a texture whose content is the drawing on a Canvas.
-// The subclasses should override onDraw() to draw on the bitmap.
-// By default CanvasTexture is not opaque.
-abstract class CanvasTexture extends UploadedTexture {
- protected Canvas mCanvas;
- private final Config mConfig;
-
- public CanvasTexture(int width, int height) {
- mConfig = Config.ARGB_8888;
- setSize(width, height);
- setOpaque(false);
- }
-
- @Override
- protected Bitmap onGetBitmap() {
- Bitmap bitmap = Bitmap.createBitmap(mWidth, mHeight, mConfig);
- mCanvas = new Canvas(bitmap);
- onDraw(mCanvas, bitmap);
- return bitmap;
- }
-
- @Override
- protected void onFreeBitmap(Bitmap bitmap) {
- if (!inFinalizer()) {
- bitmap.recycle();
- }
- }
-
- abstract protected void onDraw(Canvas canvas, Bitmap backing);
-}
diff --git a/src/com/android/gallery3d/ui/ColorTexture.java b/src/com/android/gallery3d/ui/ColorTexture.java
deleted file mode 100644
index 733c05653..000000000
--- a/src/com/android/gallery3d/ui/ColorTexture.java
+++ /dev/null
@@ -1,63 +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.gallery3d.ui;
-
-import com.android.gallery3d.common.Utils;
-
-// ColorTexture is a texture which fills the rectangle with the specified color.
-public class ColorTexture implements Texture {
-
- private final int mColor;
- private int mWidth;
- private int mHeight;
-
- public ColorTexture(int color) {
- mColor = color;
- mWidth = 1;
- mHeight = 1;
- }
-
- @Override
- public void draw(GLCanvas canvas, int x, int y) {
- draw(canvas, x, y, mWidth, mHeight);
- }
-
- @Override
- public void draw(GLCanvas canvas, int x, int y, int w, int h) {
- canvas.fillRect(x, y, w, h, mColor);
- }
-
- @Override
- public boolean isOpaque() {
- return Utils.isOpaque(mColor);
- }
-
- public void setSize(int width, int height) {
- mWidth = width;
- mHeight = height;
- }
-
- @Override
- public int getWidth() {
- return mWidth;
- }
-
- @Override
- public int getHeight() {
- return mHeight;
- }
-}
diff --git a/src/com/android/gallery3d/ui/CropView.java b/src/com/android/gallery3d/ui/CropView.java
deleted file mode 100644
index 1890c7630..000000000
--- a/src/com/android/gallery3d/ui/CropView.java
+++ /dev/null
@@ -1,801 +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.gallery3d.ui;
-
-import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.PointF;
-import android.graphics.RectF;
-import android.media.FaceDetector;
-import android.os.Handler;
-import android.os.Message;
-import android.util.FloatMath;
-import android.view.MotionEvent;
-import android.view.animation.DecelerateInterpolator;
-import android.widget.Toast;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.anim.Animation;
-import com.android.gallery3d.app.AbstractGalleryActivity;
-import com.android.gallery3d.common.Utils;
-
-import java.util.ArrayList;
-
-import javax.microedition.khronos.opengles.GL11;
-
-/**
- * The activity can crop specific region of interest from an image.
- */
-public class CropView extends GLView {
- @SuppressWarnings("unused")
- private static final String TAG = "CropView";
-
- private static final int FACE_PIXEL_COUNT = 120000; // around 400x300
-
- private static final int COLOR_OUTLINE = 0xFF008AFF;
- private static final int COLOR_FACE_OUTLINE = 0xFF000000;
-
- private static final float OUTLINE_WIDTH = 3f;
-
- private static final int SIZE_UNKNOWN = -1;
- private static final int TOUCH_TOLERANCE = 30;
-
- private static final float MIN_SELECTION_LENGTH = 16f;
- public static final float UNSPECIFIED = -1f;
-
- private static final int MAX_FACE_COUNT = 3;
- private static final float FACE_EYE_RATIO = 2f;
-
- private static final int ANIMATION_DURATION = 1250;
-
- private static final int MOVE_LEFT = 1;
- private static final int MOVE_TOP = 2;
- private static final int MOVE_RIGHT = 4;
- private static final int MOVE_BOTTOM = 8;
- private static final int MOVE_BLOCK = 16;
-
- private static final float MAX_SELECTION_RATIO = 0.8f;
- private static final float MIN_SELECTION_RATIO = 0.4f;
- private static final float SELECTION_RATIO = 0.60f;
- private static final int ANIMATION_TRIGGER = 64;
-
- private static final int MSG_UPDATE_FACES = 1;
-
- private float mAspectRatio = UNSPECIFIED;
- private float mSpotlightRatioX = 0;
- private float mSpotlightRatioY = 0;
-
- private Handler mMainHandler;
-
- private FaceHighlightView mFaceDetectionView;
- private HighlightRectangle mHighlightRectangle;
- private TileImageView mImageView;
- private AnimationController mAnimation = new AnimationController();
-
- private int mImageWidth = SIZE_UNKNOWN;
- private int mImageHeight = SIZE_UNKNOWN;
-
- private AbstractGalleryActivity mActivity;
-
- private GLPaint mPaint = new GLPaint();
- private GLPaint mFacePaint = new GLPaint();
-
- private int mImageRotation;
-
- public CropView(AbstractGalleryActivity activity) {
- mActivity = activity;
- mImageView = new TileImageView(activity);
- mFaceDetectionView = new FaceHighlightView();
- mHighlightRectangle = new HighlightRectangle();
-
- addComponent(mImageView);
- addComponent(mFaceDetectionView);
- addComponent(mHighlightRectangle);
-
- mHighlightRectangle.setVisibility(GLView.INVISIBLE);
-
- mPaint.setColor(COLOR_OUTLINE);
- mPaint.setLineWidth(OUTLINE_WIDTH);
-
- mFacePaint.setColor(COLOR_FACE_OUTLINE);
- mFacePaint.setLineWidth(OUTLINE_WIDTH);
-
- mMainHandler = new SynchronizedHandler(activity.getGLRoot()) {
- @Override
- public void handleMessage(Message message) {
- Utils.assertTrue(message.what == MSG_UPDATE_FACES);
- ((DetectFaceTask) message.obj).updateFaces();
- }
- };
- }
-
- public void setAspectRatio(float ratio) {
- mAspectRatio = ratio;
- }
-
- public void setSpotlightRatio(float ratioX, float ratioY) {
- mSpotlightRatioX = ratioX;
- mSpotlightRatioY = ratioY;
- }
-
- @Override
- public void onLayout(boolean changed, int l, int t, int r, int b) {
- int width = r - l;
- int height = b - t;
-
- mFaceDetectionView.layout(0, 0, width, height);
- mHighlightRectangle.layout(0, 0, width, height);
- mImageView.layout(0, 0, width, height);
- if (mImageHeight != SIZE_UNKNOWN) {
- mAnimation.initialize();
- if (mHighlightRectangle.getVisibility() == GLView.VISIBLE) {
- mAnimation.parkNow(
- mHighlightRectangle.mHighlightRect);
- }
- }
- }
-
- private boolean setImageViewPosition(int centerX, int centerY, float scale) {
- int inverseX = mImageWidth - centerX;
- int inverseY = mImageHeight - centerY;
- TileImageView t = mImageView;
- int rotation = mImageRotation;
- switch (rotation) {
- case 0: return t.setPosition(centerX, centerY, scale, 0);
- case 90: return t.setPosition(centerY, inverseX, scale, 90);
- case 180: return t.setPosition(inverseX, inverseY, scale, 180);
- case 270: return t.setPosition(inverseY, centerX, scale, 270);
- default: throw new IllegalArgumentException(String.valueOf(rotation));
- }
- }
-
- @Override
- public void render(GLCanvas canvas) {
- AnimationController a = mAnimation;
- if (a.calculate(AnimationTime.get())) invalidate();
- setImageViewPosition(a.getCenterX(), a.getCenterY(), a.getScale());
- super.render(canvas);
- }
-
- @Override
- public void renderBackground(GLCanvas canvas) {
- canvas.clearBuffer();
- }
-
- public RectF getCropRectangle() {
- if (mHighlightRectangle.getVisibility() == GLView.INVISIBLE) return null;
- RectF rect = mHighlightRectangle.mHighlightRect;
- RectF result = new RectF(rect.left * mImageWidth, rect.top * mImageHeight,
- rect.right * mImageWidth, rect.bottom * mImageHeight);
- return result;
- }
-
- public int getImageWidth() {
- return mImageWidth;
- }
-
- public int getImageHeight() {
- return mImageHeight;
- }
-
- private class FaceHighlightView extends GLView {
- private static final int INDEX_NONE = -1;
- private ArrayList<RectF> mFaces = new ArrayList<RectF>();
- private RectF mRect = new RectF();
- private int mPressedFaceIndex = INDEX_NONE;
-
- public void addFace(RectF faceRect) {
- mFaces.add(faceRect);
- invalidate();
- }
-
- private void renderFace(GLCanvas canvas, RectF face, boolean pressed) {
- GL11 gl = canvas.getGLInstance();
- if (pressed) {
- gl.glEnable(GL11.GL_STENCIL_TEST);
- gl.glClear(GL11.GL_STENCIL_BUFFER_BIT);
- gl.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_REPLACE);
- gl.glStencilFunc(GL11.GL_ALWAYS, 1, 1);
- }
-
- RectF r = mAnimation.mapRect(face, mRect);
- canvas.fillRect(r.left, r.top, r.width(), r.height(), Color.TRANSPARENT);
- canvas.drawRect(r.left, r.top, r.width(), r.height(), mFacePaint);
-
- if (pressed) {
- gl.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_KEEP);
- }
- }
-
- @Override
- protected void renderBackground(GLCanvas canvas) {
- ArrayList<RectF> faces = mFaces;
- for (int i = 0, n = faces.size(); i < n; ++i) {
- renderFace(canvas, faces.get(i), i == mPressedFaceIndex);
- }
-
- GL11 gl = canvas.getGLInstance();
- if (mPressedFaceIndex != INDEX_NONE) {
- gl.glStencilFunc(GL11.GL_NOTEQUAL, 1, 1);
- canvas.fillRect(0, 0, getWidth(), getHeight(), 0x66000000);
- gl.glDisable(GL11.GL_STENCIL_TEST);
- }
- }
-
- private void setPressedFace(int index) {
- if (mPressedFaceIndex == index) return;
- mPressedFaceIndex = index;
- invalidate();
- }
-
- private int getFaceIndexByPosition(float x, float y) {
- ArrayList<RectF> faces = mFaces;
- for (int i = 0, n = faces.size(); i < n; ++i) {
- RectF r = mAnimation.mapRect(faces.get(i), mRect);
- if (r.contains(x, y)) return i;
- }
- return INDEX_NONE;
- }
-
- @Override
- protected boolean onTouch(MotionEvent event) {
- float x = event.getX();
- float y = event.getY();
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- case MotionEvent.ACTION_MOVE: {
- setPressedFace(getFaceIndexByPosition(x, y));
- break;
- }
- case MotionEvent.ACTION_CANCEL:
- case MotionEvent.ACTION_UP: {
- int index = mPressedFaceIndex;
- setPressedFace(INDEX_NONE);
- if (index != INDEX_NONE) {
- mHighlightRectangle.setRectangle(mFaces.get(index));
- mHighlightRectangle.setVisibility(GLView.VISIBLE);
- setVisibility(GLView.INVISIBLE);
- }
- }
- }
- return true;
- }
- }
-
- private class AnimationController extends Animation {
- private int mCurrentX;
- private int mCurrentY;
- private float mCurrentScale;
- private int mStartX;
- private int mStartY;
- private float mStartScale;
- private int mTargetX;
- private int mTargetY;
- private float mTargetScale;
-
- public AnimationController() {
- setDuration(ANIMATION_DURATION);
- setInterpolator(new DecelerateInterpolator(4));
- }
-
- public void initialize() {
- mCurrentX = mImageWidth / 2;
- mCurrentY = mImageHeight / 2;
- mCurrentScale = Math.min(2, Math.min(
- (float) getWidth() / mImageWidth,
- (float) getHeight() / mImageHeight));
- }
-
- public void startParkingAnimation(RectF highlight) {
- RectF r = mAnimation.mapRect(highlight, new RectF());
- int width = getWidth();
- int height = getHeight();
-
- float wr = r.width() / width;
- float hr = r.height() / height;
- final int d = ANIMATION_TRIGGER;
- if (wr >= MIN_SELECTION_RATIO && wr < MAX_SELECTION_RATIO
- && hr >= MIN_SELECTION_RATIO && hr < MAX_SELECTION_RATIO
- && r.left >= d && r.right < width - d
- && r.top >= d && r.bottom < height - d) return;
-
- mStartX = mCurrentX;
- mStartY = mCurrentY;
- mStartScale = mCurrentScale;
- calculateTarget(highlight);
- start();
- }
-
- public void parkNow(RectF highlight) {
- calculateTarget(highlight);
- forceStop();
- mStartX = mCurrentX = mTargetX;
- mStartY = mCurrentY = mTargetY;
- mStartScale = mCurrentScale = mTargetScale;
- }
-
- public void inverseMapPoint(PointF point) {
- float s = mCurrentScale;
- point.x = Utils.clamp(((point.x - getWidth() * 0.5f) / s
- + mCurrentX) / mImageWidth, 0, 1);
- point.y = Utils.clamp(((point.y - getHeight() * 0.5f) / s
- + mCurrentY) / mImageHeight, 0, 1);
- }
-
- public RectF mapRect(RectF input, RectF output) {
- float offsetX = getWidth() * 0.5f;
- float offsetY = getHeight() * 0.5f;
- int x = mCurrentX;
- int y = mCurrentY;
- float s = mCurrentScale;
- output.set(
- offsetX + (input.left * mImageWidth - x) * s,
- offsetY + (input.top * mImageHeight - y) * s,
- offsetX + (input.right * mImageWidth - x) * s,
- offsetY + (input.bottom * mImageHeight - y) * s);
- return output;
- }
-
- @Override
- protected void onCalculate(float progress) {
- mCurrentX = Math.round(mStartX + (mTargetX - mStartX) * progress);
- mCurrentY = Math.round(mStartY + (mTargetY - mStartY) * progress);
- mCurrentScale = mStartScale + (mTargetScale - mStartScale) * progress;
-
- if (mCurrentX == mTargetX && mCurrentY == mTargetY
- && mCurrentScale == mTargetScale) forceStop();
- }
-
- public int getCenterX() {
- return mCurrentX;
- }
-
- public int getCenterY() {
- return mCurrentY;
- }
-
- public float getScale() {
- return mCurrentScale;
- }
-
- private void calculateTarget(RectF highlight) {
- float width = getWidth();
- float height = getHeight();
-
- if (mImageWidth != SIZE_UNKNOWN) {
- float minScale = Math.min(width / mImageWidth, height / mImageHeight);
- float scale = Utils.clamp(SELECTION_RATIO * Math.min(
- width / (highlight.width() * mImageWidth),
- height / (highlight.height() * mImageHeight)), minScale, 2f);
- int centerX = Math.round(
- mImageWidth * (highlight.left + highlight.right) * 0.5f);
- int centerY = Math.round(
- mImageHeight * (highlight.top + highlight.bottom) * 0.5f);
-
- if (Math.round(mImageWidth * scale) > width) {
- int limitX = Math.round(width * 0.5f / scale);
- centerX = Math.round(
- (highlight.left + highlight.right) * mImageWidth / 2);
- centerX = Utils.clamp(centerX, limitX, mImageWidth - limitX);
- } else {
- centerX = mImageWidth / 2;
- }
- if (Math.round(mImageHeight * scale) > height) {
- int limitY = Math.round(height * 0.5f / scale);
- centerY = Math.round(
- (highlight.top + highlight.bottom) * mImageHeight / 2);
- centerY = Utils.clamp(centerY, limitY, mImageHeight - limitY);
- } else {
- centerY = mImageHeight / 2;
- }
- mTargetX = centerX;
- mTargetY = centerY;
- mTargetScale = scale;
- }
- }
-
- }
-
- private class HighlightRectangle extends GLView {
- private RectF mHighlightRect = new RectF(0.25f, 0.25f, 0.75f, 0.75f);
- private RectF mTempRect = new RectF();
- private PointF mTempPoint = new PointF();
-
- private ResourceTexture mArrow;
-
- private int mMovingEdges = 0;
- private float mReferenceX;
- private float mReferenceY;
-
- public HighlightRectangle() {
- mArrow = new ResourceTexture(mActivity.getAndroidContext(),
- R.drawable.camera_crop_holo);
- }
-
- public void setInitRectangle() {
- float targetRatio = mAspectRatio == UNSPECIFIED
- ? 1f
- : mAspectRatio * mImageHeight / mImageWidth;
- float w = SELECTION_RATIO / 2f;
- float h = SELECTION_RATIO / 2f;
- if (targetRatio > 1) {
- h = w / targetRatio;
- } else {
- w = h * targetRatio;
- }
- mHighlightRect.set(0.5f - w, 0.5f - h, 0.5f + w, 0.5f + h);
- }
-
- public void setRectangle(RectF faceRect) {
- mHighlightRect.set(faceRect);
- mAnimation.startParkingAnimation(faceRect);
- invalidate();
- }
-
- private void moveEdges(MotionEvent event) {
- float scale = mAnimation.getScale();
- float dx = (event.getX() - mReferenceX) / scale / mImageWidth;
- float dy = (event.getY() - mReferenceY) / scale / mImageHeight;
- mReferenceX = event.getX();
- mReferenceY = event.getY();
- RectF r = mHighlightRect;
-
- if ((mMovingEdges & MOVE_BLOCK) != 0) {
- dx = Utils.clamp(dx, -r.left, 1 - r.right);
- dy = Utils.clamp(dy, -r.top , 1 - r.bottom);
- r.top += dy;
- r.bottom += dy;
- r.left += dx;
- r.right += dx;
- } else {
- PointF point = mTempPoint;
- point.set(mReferenceX, mReferenceY);
- mAnimation.inverseMapPoint(point);
- float left = r.left + MIN_SELECTION_LENGTH / mImageWidth;
- float right = r.right - MIN_SELECTION_LENGTH / mImageWidth;
- float top = r.top + MIN_SELECTION_LENGTH / mImageHeight;
- float bottom = r.bottom - MIN_SELECTION_LENGTH / mImageHeight;
- if ((mMovingEdges & MOVE_RIGHT) != 0) {
- r.right = Utils.clamp(point.x, left, 1f);
- }
- if ((mMovingEdges & MOVE_LEFT) != 0) {
- r.left = Utils.clamp(point.x, 0, right);
- }
- if ((mMovingEdges & MOVE_TOP) != 0) {
- r.top = Utils.clamp(point.y, 0, bottom);
- }
- if ((mMovingEdges & MOVE_BOTTOM) != 0) {
- r.bottom = Utils.clamp(point.y, top, 1f);
- }
- if (mAspectRatio != UNSPECIFIED) {
- float targetRatio = mAspectRatio * mImageHeight / mImageWidth;
- if (r.width() / r.height() > targetRatio) {
- float height = r.width() / targetRatio;
- if ((mMovingEdges & MOVE_BOTTOM) != 0) {
- r.bottom = Utils.clamp(r.top + height, top, 1f);
- } else {
- r.top = Utils.clamp(r.bottom - height, 0, bottom);
- }
- } else {
- float width = r.height() * targetRatio;
- if ((mMovingEdges & MOVE_LEFT) != 0) {
- r.left = Utils.clamp(r.right - width, 0, right);
- } else {
- r.right = Utils.clamp(r.left + width, left, 1f);
- }
- }
- if (r.width() / r.height() > targetRatio) {
- float width = r.height() * targetRatio;
- if ((mMovingEdges & MOVE_LEFT) != 0) {
- r.left = Utils.clamp(r.right - width, 0, right);
- } else {
- r.right = Utils.clamp(r.left + width, left, 1f);
- }
- } else {
- float height = r.width() / targetRatio;
- if ((mMovingEdges & MOVE_BOTTOM) != 0) {
- r.bottom = Utils.clamp(r.top + height, top, 1f);
- } else {
- r.top = Utils.clamp(r.bottom - height, 0, bottom);
- }
- }
- }
- }
- invalidate();
- }
-
- private void setMovingEdges(MotionEvent event) {
- RectF r = mAnimation.mapRect(mHighlightRect, mTempRect);
- float x = event.getX();
- float y = event.getY();
-
- if (x > r.left + TOUCH_TOLERANCE && x < r.right - TOUCH_TOLERANCE
- && y > r.top + TOUCH_TOLERANCE && y < r.bottom - TOUCH_TOLERANCE) {
- mMovingEdges = MOVE_BLOCK;
- return;
- }
-
- boolean inVerticalRange = (r.top - TOUCH_TOLERANCE) <= y
- && y <= (r.bottom + TOUCH_TOLERANCE);
- boolean inHorizontalRange = (r.left - TOUCH_TOLERANCE) <= x
- && x <= (r.right + TOUCH_TOLERANCE);
-
- if (inVerticalRange) {
- boolean left = Math.abs(x - r.left) <= TOUCH_TOLERANCE;
- boolean right = Math.abs(x - r.right) <= TOUCH_TOLERANCE;
- if (left && right) {
- left = Math.abs(x - r.left) < Math.abs(x - r.right);
- right = !left;
- }
- if (left) mMovingEdges |= MOVE_LEFT;
- if (right) mMovingEdges |= MOVE_RIGHT;
- if (mAspectRatio != UNSPECIFIED && inHorizontalRange) {
- mMovingEdges |= (y >
- (r.top + r.bottom) / 2) ? MOVE_BOTTOM : MOVE_TOP;
- }
- }
- if (inHorizontalRange) {
- boolean top = Math.abs(y - r.top) <= TOUCH_TOLERANCE;
- boolean bottom = Math.abs(y - r.bottom) <= TOUCH_TOLERANCE;
- if (top && bottom) {
- top = Math.abs(y - r.top) < Math.abs(y - r.bottom);
- bottom = !top;
- }
- if (top) mMovingEdges |= MOVE_TOP;
- if (bottom) mMovingEdges |= MOVE_BOTTOM;
- if (mAspectRatio != UNSPECIFIED && inVerticalRange) {
- mMovingEdges |= (x >
- (r.left + r.right) / 2) ? MOVE_RIGHT : MOVE_LEFT;
- }
- }
- }
-
- @Override
- protected boolean onTouch(MotionEvent event) {
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN: {
- mReferenceX = event.getX();
- mReferenceY = event.getY();
- setMovingEdges(event);
- invalidate();
- return true;
- }
- case MotionEvent.ACTION_MOVE:
- moveEdges(event);
- break;
- case MotionEvent.ACTION_CANCEL:
- case MotionEvent.ACTION_UP: {
- mMovingEdges = 0;
- mAnimation.startParkingAnimation(mHighlightRect);
- invalidate();
- return true;
- }
- }
- return true;
- }
-
- @Override
- protected void renderBackground(GLCanvas canvas) {
- RectF r = mAnimation.mapRect(mHighlightRect, mTempRect);
- drawHighlightRectangle(canvas, r);
-
- float centerY = (r.top + r.bottom) / 2;
- float centerX = (r.left + r.right) / 2;
- boolean notMoving = mMovingEdges == 0;
- if ((mMovingEdges & MOVE_RIGHT) != 0 || notMoving) {
- mArrow.draw(canvas,
- Math.round(r.right - mArrow.getWidth() / 2),
- Math.round(centerY - mArrow.getHeight() / 2));
- }
- if ((mMovingEdges & MOVE_LEFT) != 0 || notMoving) {
- mArrow.draw(canvas,
- Math.round(r.left - mArrow.getWidth() / 2),
- Math.round(centerY - mArrow.getHeight() / 2));
- }
- if ((mMovingEdges & MOVE_TOP) != 0 || notMoving) {
- mArrow.draw(canvas,
- Math.round(centerX - mArrow.getWidth() / 2),
- Math.round(r.top - mArrow.getHeight() / 2));
- }
- if ((mMovingEdges & MOVE_BOTTOM) != 0 || notMoving) {
- mArrow.draw(canvas,
- Math.round(centerX - mArrow.getWidth() / 2),
- Math.round(r.bottom - mArrow.getHeight() / 2));
- }
- }
-
- private void drawHighlightRectangle(GLCanvas canvas, RectF r) {
- GL11 gl = canvas.getGLInstance();
- gl.glLineWidth(3.0f);
- gl.glEnable(GL11.GL_LINE_SMOOTH);
-
- gl.glEnable(GL11.GL_STENCIL_TEST);
- gl.glClear(GL11.GL_STENCIL_BUFFER_BIT);
- gl.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_REPLACE);
- gl.glStencilFunc(GL11.GL_ALWAYS, 1, 1);
-
- if (mSpotlightRatioX == 0 || mSpotlightRatioY == 0) {
- canvas.fillRect(r.left, r.top, r.width(), r.height(), Color.TRANSPARENT);
- canvas.drawRect(r.left, r.top, r.width(), r.height(), mPaint);
- } else {
- float sx = r.width() * mSpotlightRatioX;
- float sy = r.height() * mSpotlightRatioY;
- float cx = r.centerX();
- float cy = r.centerY();
-
- canvas.fillRect(cx - sx / 2, cy - sy / 2, sx, sy, Color.TRANSPARENT);
- canvas.drawRect(cx - sx / 2, cy - sy / 2, sx, sy, mPaint);
- canvas.drawRect(r.left, r.top, r.width(), r.height(), mPaint);
-
- gl.glStencilFunc(GL11.GL_NOTEQUAL, 1, 1);
- gl.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_REPLACE);
-
- canvas.drawRect(cx - sy / 2, cy - sx / 2, sy, sx, mPaint);
- canvas.fillRect(cx - sy / 2, cy - sx / 2, sy, sx, Color.TRANSPARENT);
- canvas.fillRect(r.left, r.top, r.width(), r.height(), 0x80000000);
- }
-
- gl.glStencilFunc(GL11.GL_NOTEQUAL, 1, 1);
- gl.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_KEEP);
-
- canvas.fillRect(0, 0, getWidth(), getHeight(), 0xA0000000);
-
- gl.glDisable(GL11.GL_STENCIL_TEST);
- }
- }
-
- private class DetectFaceTask extends Thread {
- private final FaceDetector.Face[] mFaces = new FaceDetector.Face[MAX_FACE_COUNT];
- private final Bitmap mFaceBitmap;
- private int mFaceCount;
-
- public DetectFaceTask(Bitmap bitmap) {
- mFaceBitmap = bitmap;
- setName("face-detect");
- }
-
- @Override
- public void run() {
- Bitmap bitmap = mFaceBitmap;
- FaceDetector detector = new FaceDetector(
- bitmap.getWidth(), bitmap.getHeight(), MAX_FACE_COUNT);
- mFaceCount = detector.findFaces(bitmap, mFaces);
- mMainHandler.sendMessage(
- mMainHandler.obtainMessage(MSG_UPDATE_FACES, this));
- }
-
- private RectF getFaceRect(FaceDetector.Face face) {
- PointF point = new PointF();
- face.getMidPoint(point);
-
- int width = mFaceBitmap.getWidth();
- int height = mFaceBitmap.getHeight();
- float rx = face.eyesDistance() * FACE_EYE_RATIO;
- float ry = rx;
- float aspect = mAspectRatio;
- if (aspect != UNSPECIFIED) {
- if (aspect > 1) {
- rx = ry * aspect;
- } else {
- ry = rx / aspect;
- }
- }
-
- RectF r = new RectF(
- point.x - rx, point.y - ry, point.x + rx, point.y + ry);
- r.intersect(0, 0, width, height);
-
- if (aspect != UNSPECIFIED) {
- if (r.width() / r.height() > aspect) {
- float w = r.height() * aspect;
- r.left = (r.left + r.right - w) * 0.5f;
- r.right = r.left + w;
- } else {
- float h = r.width() / aspect;
- r.top = (r.top + r.bottom - h) * 0.5f;
- r.bottom = r.top + h;
- }
- }
-
- r.left /= width;
- r.right /= width;
- r.top /= height;
- r.bottom /= height;
- return r;
- }
-
- public void updateFaces() {
- if (mFaceCount > 1) {
- for (int i = 0, n = mFaceCount; i < n; ++i) {
- mFaceDetectionView.addFace(getFaceRect(mFaces[i]));
- }
- mFaceDetectionView.setVisibility(GLView.VISIBLE);
- Toast.makeText(mActivity.getAndroidContext(),
- R.string.multiface_crop_help, Toast.LENGTH_SHORT).show();
- } else if (mFaceCount == 1) {
- mFaceDetectionView.setVisibility(GLView.INVISIBLE);
- mHighlightRectangle.setRectangle(getFaceRect(mFaces[0]));
- mHighlightRectangle.setVisibility(GLView.VISIBLE);
- } else /*mFaceCount == 0*/ {
- mHighlightRectangle.setInitRectangle();
- mHighlightRectangle.setVisibility(GLView.VISIBLE);
- }
- }
- }
-
- public void setDataModel(TileImageView.Model dataModel, int rotation) {
- if (((rotation / 90) & 0x01) != 0) {
- mImageWidth = dataModel.getImageHeight();
- mImageHeight = dataModel.getImageWidth();
- } else {
- mImageWidth = dataModel.getImageWidth();
- mImageHeight = dataModel.getImageHeight();
- }
-
- mImageRotation = rotation;
-
- mImageView.setModel(dataModel);
- mAnimation.initialize();
- }
-
- public void detectFaces(Bitmap bitmap) {
- int rotation = mImageRotation;
- int width = bitmap.getWidth();
- int height = bitmap.getHeight();
- float scale = FloatMath.sqrt((float) FACE_PIXEL_COUNT / (width * height));
-
- // faceBitmap is a correctly rotated bitmap, as viewed by a user.
- Bitmap faceBitmap;
- if (((rotation / 90) & 1) == 0) {
- int w = (Math.round(width * scale) & ~1); // must be even
- int h = Math.round(height * scale);
- faceBitmap = Bitmap.createBitmap(w, h, Config.RGB_565);
- Canvas canvas = new Canvas(faceBitmap);
- canvas.rotate(rotation, w / 2, h / 2);
- canvas.scale((float) w / width, (float) h / height);
- canvas.drawBitmap(bitmap, 0, 0, new Paint(Paint.FILTER_BITMAP_FLAG));
- } else {
- int w = (Math.round(height * scale) & ~1); // must be even
- int h = Math.round(width * scale);
- faceBitmap = Bitmap.createBitmap(w, h, Config.RGB_565);
- Canvas canvas = new Canvas(faceBitmap);
- canvas.translate(w / 2, h / 2);
- canvas.rotate(rotation);
- canvas.translate(-h / 2, -w / 2);
- canvas.scale((float) w / height, (float) h / width);
- canvas.drawBitmap(bitmap, 0, 0, new Paint(Paint.FILTER_BITMAP_FLAG));
- }
- new DetectFaceTask(faceBitmap).start();
- }
-
- public void initializeHighlightRectangle() {
- mHighlightRectangle.setInitRectangle();
- mHighlightRectangle.setVisibility(GLView.VISIBLE);
- }
-
- public void resume() {
- mImageView.prepareTextures();
- }
-
- public void pause() {
- mImageView.freeTextures();
- }
-}
-
diff --git a/src/com/android/gallery3d/ui/DetailsHelper.java b/src/com/android/gallery3d/ui/DetailsHelper.java
index 301601156..47296f655 100644
--- a/src/com/android/gallery3d/ui/DetailsHelper.java
+++ b/src/com/android/gallery3d/ui/DetailsHelper.java
@@ -16,6 +16,8 @@
package com.android.gallery3d.ui;
import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.view.View.MeasureSpec;
import com.android.gallery3d.R;
@@ -44,6 +46,10 @@ public class DetailsHelper {
public void hide();
}
+ public interface ResolutionResolvingListener {
+ public void onResolutionAvailable(int width, int height);
+ }
+
public DetailsHelper(AbstractGalleryActivity activity, GLView rootPane, DetailsSource source) {
mContainer = new DialogDetailsView(activity, source);
}
@@ -75,6 +81,12 @@ public class DetailsHelper {
return sAddressResolver.resolveAddress(latlng, listener);
}
+ public static void resolveResolution(String path, ResolutionResolvingListener listener) {
+ Bitmap bitmap = BitmapFactory.decodeFile(path);
+ if (bitmap == null) return;
+ listener.onResolutionAvailable(bitmap.getWidth(), bitmap.getHeight());
+ }
+
public static void pause() {
if (sAddressResolver != null) sAddressResolver.cancel();
}
diff --git a/src/com/android/gallery3d/ui/DialogDetailsView.java b/src/com/android/gallery3d/ui/DialogDetailsView.java
index 8d96b821a..058c03654 100644
--- a/src/com/android/gallery3d/ui/DialogDetailsView.java
+++ b/src/com/android/gallery3d/ui/DialogDetailsView.java
@@ -37,6 +37,7 @@ import com.android.gallery3d.ui.DetailsAddressResolver.AddressResolvingListener;
import com.android.gallery3d.ui.DetailsHelper.CloseListener;
import com.android.gallery3d.ui.DetailsHelper.DetailsSource;
import com.android.gallery3d.ui.DetailsHelper.DetailsViewContainer;
+import com.android.gallery3d.ui.DetailsHelper.ResolutionResolvingListener;
import java.util.ArrayList;
import java.util.Map.Entry;
@@ -111,9 +112,13 @@ public class DialogDetailsView implements DetailsViewContainer {
});
}
- private class DetailsAdapter extends BaseAdapter implements AddressResolvingListener {
+
+ private class DetailsAdapter extends BaseAdapter
+ implements AddressResolvingListener, ResolutionResolvingListener {
private final ArrayList<String> mItems;
private int mLocationIndex;
+ private int mWidthIndex = -1;
+ private int mHeightIndex = -1;
public DetailsAdapter(MediaDetails details) {
Context context = mActivity.getAndroidContext();
@@ -123,6 +128,8 @@ public class DialogDetailsView implements DetailsViewContainer {
}
private void setDetails(Context context, MediaDetails details) {
+ boolean resolutionIsValid = true;
+ String path = null;
for (Entry<Integer, Object> detail : details) {
String value;
switch (detail.getKey()) {
@@ -170,6 +177,26 @@ public class DialogDetailsView implements DetailsViewContainer {
}
break;
}
+ case MediaDetails.INDEX_WIDTH:
+ mWidthIndex = mItems.size();
+ value = detail.getValue().toString();
+ if (value.equalsIgnoreCase("0")) {
+ value = context.getString(R.string.unknown);
+ resolutionIsValid = false;
+ }
+ break;
+ case MediaDetails.INDEX_HEIGHT: {
+ mHeightIndex = mItems.size();
+ value = detail.getValue().toString();
+ if (value.equalsIgnoreCase("0")) {
+ value = context.getString(R.string.unknown);
+ resolutionIsValid = false;
+ }
+ break;
+ }
+ case MediaDetails.INDEX_PATH:
+ // Get the path and then fall through to the default case
+ path = detail.getValue().toString();
default: {
Object valueObj = detail.getValue();
// This shouldn't happen, log its key to help us diagnose the problem.
@@ -189,6 +216,9 @@ public class DialogDetailsView implements DetailsViewContainer {
context, key), value);
}
mItems.add(value);
+ if (!resolutionIsValid) {
+ DetailsHelper.resolveResolution(path, this);
+ }
}
}
@@ -235,6 +265,20 @@ public class DialogDetailsView implements DetailsViewContainer {
mItems.set(mLocationIndex, address);
notifyDataSetChanged();
}
+
+ @Override
+ public void onResolutionAvailable(int width, int height) {
+ if (width == 0 || height == 0) return;
+ // Update the resolution with the new width and height
+ Context context = mActivity.getAndroidContext();
+ String widthString = String.format("%s: %d", DetailsHelper.getDetailsName(
+ context, MediaDetails.INDEX_WIDTH), width);
+ String heightString = String.format("%s: %d", DetailsHelper.getDetailsName(
+ context, MediaDetails.INDEX_HEIGHT), height);
+ mItems.set(mWidthIndex, String.valueOf(widthString));
+ mItems.set(mHeightIndex, String.valueOf(heightString));
+ notifyDataSetChanged();
+ }
}
@Override
diff --git a/src/com/android/gallery3d/ui/EdgeEffect.java b/src/com/android/gallery3d/ui/EdgeEffect.java
index ed369737b..87ff0c5d3 100644
--- a/src/com/android/gallery3d/ui/EdgeEffect.java
+++ b/src/com/android/gallery3d/ui/EdgeEffect.java
@@ -23,6 +23,8 @@ import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import com.android.gallery3d.R;
+import com.android.gallery3d.glrenderer.GLCanvas;
+import com.android.gallery3d.glrenderer.ResourceTexture;
// This is copied from android.widget.EdgeEffect with some small modifications:
// (1) Copy the images (overscroll_{edge|glow}.png) to local resources.
diff --git a/src/com/android/gallery3d/ui/EdgeView.java b/src/com/android/gallery3d/ui/EdgeView.java
index 4aff0494d..051de18fa 100644
--- a/src/com/android/gallery3d/ui/EdgeView.java
+++ b/src/com/android/gallery3d/ui/EdgeView.java
@@ -19,6 +19,8 @@ package com.android.gallery3d.ui;
import android.content.Context;
import android.opengl.Matrix;
+import com.android.gallery3d.glrenderer.GLCanvas;
+
// EdgeView draws EdgeEffect (blue glow) at four sides of the view.
public class EdgeView extends GLView {
@SuppressWarnings("unused")
diff --git a/src/com/android/gallery3d/ui/ExtTexture.java b/src/com/android/gallery3d/ui/ExtTexture.java
deleted file mode 100644
index eac504fe5..000000000
--- a/src/com/android/gallery3d/ui/ExtTexture.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2012 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.gallery3d.ui;
-
-import javax.microedition.khronos.opengles.GL11;
-import javax.microedition.khronos.opengles.GL11Ext;
-
-// ExtTexture is a texture whose content comes from a external texture.
-// Before drawing, setSize() should be called.
-public class ExtTexture extends BasicTexture {
-
- private static int[] sTextureId = new int[1];
- private static float[] sCropRect = new float[4];
- private int mTarget;
-
- public ExtTexture(int target) {
- GLId.glGenTextures(1, sTextureId, 0);
- mId = sTextureId[0];
- mTarget = target;
- }
-
- private void uploadToCanvas(GLCanvas canvas) {
- GL11 gl = canvas.getGLInstance();
-
- int width = getWidth();
- int height = getHeight();
- // Define a vertically flipped crop rectangle for OES_draw_texture.
- // The four values in sCropRect are: left, bottom, width, and
- // height. Negative value of width or height means flip.
- sCropRect[0] = 0;
- sCropRect[1] = height;
- sCropRect[2] = width;
- sCropRect[3] = -height;
-
- // Set texture parameters.
- gl.glBindTexture(mTarget, mId);
- gl.glTexParameterfv(mTarget,
- GL11Ext.GL_TEXTURE_CROP_RECT_OES, sCropRect, 0);
- gl.glTexParameteri(mTarget,
- GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP_TO_EDGE);
- gl.glTexParameteri(mTarget,
- GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP_TO_EDGE);
- gl.glTexParameterf(mTarget,
- GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
- gl.glTexParameterf(mTarget,
- GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
-
- setAssociatedCanvas(canvas);
- mState = STATE_LOADED;
- }
-
- @Override
- protected boolean onBind(GLCanvas canvas) {
- if (!isLoaded()) {
- uploadToCanvas(canvas);
- }
-
- return true;
- }
-
- @Override
- public int getTarget() {
- return mTarget;
- }
-
- @Override
- public boolean isOpaque() {
- return true;
- }
-
- @Override
- public void yield() {
- // we cannot free the texture because we have no backup.
- }
-}
diff --git a/src/com/android/gallery3d/ui/FadeInTexture.java b/src/com/android/gallery3d/ui/FadeInTexture.java
deleted file mode 100644
index c6a9811f6..000000000
--- a/src/com/android/gallery3d/ui/FadeInTexture.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2011 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.gallery3d.ui;
-
-// FadeInTexture is a texture which begins with a color, then gradually animates
-// into a given texture.
-public class FadeInTexture extends FadeTexture implements Texture {
- @SuppressWarnings("unused")
- private static final String TAG = "FadeInTexture";
-
- private final int mColor;
- private final TiledTexture mTexture;
-
- public FadeInTexture(int color, TiledTexture texture) {
- super(texture.getWidth(), texture.getHeight(), texture.isOpaque());
- mColor = color;
- mTexture = texture;
- }
-
- @Override
- public void draw(GLCanvas canvas, int x, int y, int w, int h) {
- if (isAnimating()) {
- mTexture.drawMixed(canvas, mColor, getRatio(), x, y, w, h);
- } else {
- mTexture.draw(canvas, x, y, w, h);
- }
- }
-}
diff --git a/src/com/android/gallery3d/ui/FadeOutTexture.java b/src/com/android/gallery3d/ui/FadeOutTexture.java
deleted file mode 100644
index 7050e535e..000000000
--- a/src/com/android/gallery3d/ui/FadeOutTexture.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2011 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.gallery3d.ui;
-
-// FadeOutTexture is a texture which begins with a given texture, then gradually animates
-// into fading out totally.
-public class FadeOutTexture extends FadeTexture {
- @SuppressWarnings("unused")
- private static final String TAG = "FadeOutTexture";
-
- private final BasicTexture mTexture;
-
- public FadeOutTexture(BasicTexture texture) {
- super(texture.getWidth(), texture.getHeight(), texture.isOpaque());
- mTexture = texture;
- }
-
- @Override
- public void draw(GLCanvas canvas, int x, int y, int w, int h) {
- if (isAnimating()) {
- canvas.save(GLCanvas.SAVE_FLAG_ALPHA);
- canvas.setAlpha(getRatio());
- mTexture.draw(canvas, x, y, w, h);
- canvas.restore();
- }
- }
-}
diff --git a/src/com/android/gallery3d/ui/FadeTexture.java b/src/com/android/gallery3d/ui/FadeTexture.java
deleted file mode 100644
index 5236d3639..000000000
--- a/src/com/android/gallery3d/ui/FadeTexture.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2011 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.gallery3d.ui;
-
-import com.android.gallery3d.common.Utils;
-
-// FadeTexture is a texture which fades the given texture along the time.
-public abstract class FadeTexture implements Texture {
- @SuppressWarnings("unused")
- private static final String TAG = "FadeTexture";
-
- // The duration of the fading animation in milliseconds
- public static final int DURATION = 180;
-
- private final long mStartTime;
- private final int mWidth;
- private final int mHeight;
- private final boolean mIsOpaque;
- private boolean mIsAnimating;
-
- public FadeTexture(int width, int height, boolean opaque) {
- mWidth = width;
- mHeight = height;
- mIsOpaque = opaque;
- mStartTime = now();
- mIsAnimating = true;
- }
-
- @Override
- public void draw(GLCanvas canvas, int x, int y) {
- draw(canvas, x, y, mWidth, mHeight);
- }
-
- @Override
- public boolean isOpaque() {
- return mIsOpaque;
- }
-
- @Override
- public int getWidth() {
- return mWidth;
- }
-
- @Override
- public int getHeight() {
- return mHeight;
- }
-
- public boolean isAnimating() {
- if (mIsAnimating) {
- if (now() - mStartTime >= DURATION) {
- mIsAnimating = false;
- }
- }
- return mIsAnimating;
- }
-
- protected float getRatio() {
- float r = (float)(now() - mStartTime) / DURATION;
- return Utils.clamp(1.0f - r, 0.0f, 1.0f);
- }
-
- private long now() {
- return AnimationTime.get();
- }
-}
diff --git a/src/com/android/gallery3d/ui/GLCanvas.java b/src/com/android/gallery3d/ui/GLCanvas.java
deleted file mode 100644
index 6f8baef7e..000000000
--- a/src/com/android/gallery3d/ui/GLCanvas.java
+++ /dev/null
@@ -1,132 +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.gallery3d.ui;
-
-import android.graphics.RectF;
-
-import javax.microedition.khronos.opengles.GL11;
-
-//
-// GLCanvas gives a convenient interface to draw using OpenGL.
-//
-// When a rectangle is specified in this interface, it means the region
-// [x, x+width) * [y, y+height)
-//
-public interface GLCanvas {
- // Tells GLCanvas the size of the underlying GL surface. This should be
- // called before first drawing and when the size of GL surface is changed.
- // This is called by GLRoot and should not be called by the clients
- // who only want to draw on the GLCanvas. Both width and height must be
- // nonnegative.
- public void setSize(int width, int height);
-
- // Clear the drawing buffers. This should only be used by GLRoot.
- public void clearBuffer();
- public void clearBuffer(float[] argb);
-
- // Sets and gets the current alpha, alpha must be in [0, 1].
- public void setAlpha(float alpha);
- public float getAlpha();
-
- // (current alpha) = (current alpha) * alpha
- public void multiplyAlpha(float alpha);
-
- // Change the current transform matrix.
- public void translate(float x, float y, float z);
- public void translate(float x, float y);
- public void scale(float sx, float sy, float sz);
- public void rotate(float angle, float x, float y, float z);
- public void multiplyMatrix(float[] mMatrix, int offset);
-
- // Pushes the configuration state (matrix, and alpha) onto
- // a private stack.
- public void save();
-
- // Same as save(), but only save those specified in saveFlags.
- public void save(int saveFlags);
-
- public static final int SAVE_FLAG_ALL = 0xFFFFFFFF;
- public static final int SAVE_FLAG_ALPHA = 0x01;
- public static final int SAVE_FLAG_MATRIX = 0x02;
-
- // Pops from the top of the stack as current configuration state (matrix,
- // alpha, and clip). This call balances a previous call to save(), and is
- // used to remove all modifications to the configuration state since the
- // last save call.
- public void restore();
-
- // Draws a line using the specified paint from (x1, y1) to (x2, y2).
- // (Both end points are included).
- public void drawLine(float x1, float y1, float x2, float y2, GLPaint paint);
-
- // Draws a rectangle using the specified paint from (x1, y1) to (x2, y2).
- // (Both end points are included).
- public void drawRect(float x1, float y1, float x2, float y2, GLPaint paint);
-
- // Fills the specified rectangle with the specified color.
- public void fillRect(float x, float y, float width, float height, int color);
-
- // Draws a texture to the specified rectangle.
- public void drawTexture(
- BasicTexture texture, int x, int y, int width, int height);
- public void drawMesh(BasicTexture tex, int x, int y, int xyBuffer,
- int uvBuffer, int indexBuffer, int indexCount);
-
- // Draws the source rectangle part of the texture to the target rectangle.
- public void drawTexture(BasicTexture texture, RectF source, RectF target);
-
- // Draw a texture with a specified texture transform.
- public void drawTexture(BasicTexture texture, float[] mTextureTransform,
- int x, int y, int w, int h);
-
- // Draw two textures to the specified rectangle. The actual texture used is
- // from * (1 - ratio) + to * ratio
- // The two textures must have the same size.
- public void drawMixed(BasicTexture from, int toColor,
- float ratio, int x, int y, int w, int h);
-
- // Draw a region of a texture and a specified color to the specified
- // rectangle. The actual color used is from * (1 - ratio) + to * ratio.
- // The region of the texture is defined by parameter "src". The target
- // rectangle is specified by parameter "target".
- public void drawMixed(BasicTexture from, int toColor,
- float ratio, RectF src, RectF target);
-
- // Gets the underlying GL instance. This is used only when direct access to
- // GL is needed.
- public GL11 getGLInstance();
-
- // Unloads the specified texture from the canvas. The resource allocated
- // to draw the texture will be released. The specified texture will return
- // to the unloaded state. This function should be called only from
- // BasicTexture or its descendant
- public boolean unloadTexture(BasicTexture texture);
-
- // Delete the specified buffer object, similar to unloadTexture.
- public void deleteBuffer(int bufferId);
-
- // Delete the textures and buffers in GL side. This function should only be
- // called in the GL thread.
- public void deleteRecycledResources();
-
- // Dump statistics information and clear the counters. For debug only.
- public void dumpStatisticsAndClear();
-
- public void beginRenderTarget(RawTexture texture);
-
- public void endRenderTarget();
-}
diff --git a/src/com/android/gallery3d/ui/GLCanvasImpl.java b/src/com/android/gallery3d/ui/GLCanvasImpl.java
deleted file mode 100644
index 45903b3cd..000000000
--- a/src/com/android/gallery3d/ui/GLCanvasImpl.java
+++ /dev/null
@@ -1,920 +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.gallery3d.ui;
-
-import android.graphics.RectF;
-import android.opengl.GLU;
-import android.opengl.Matrix;
-
-import com.android.gallery3d.common.Utils;
-import com.android.gallery3d.util.IntArray;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
-import java.util.ArrayList;
-
-import javax.microedition.khronos.opengles.GL10;
-import javax.microedition.khronos.opengles.GL11;
-import javax.microedition.khronos.opengles.GL11Ext;
-import javax.microedition.khronos.opengles.GL11ExtensionPack;
-
-public class GLCanvasImpl implements GLCanvas {
- @SuppressWarnings("unused")
- private static final String TAG = "GLCanvasImp";
-
- private static final float OPAQUE_ALPHA = 0.95f;
-
- private static final int OFFSET_FILL_RECT = 0;
- private static final int OFFSET_DRAW_LINE = 4;
- private static final int OFFSET_DRAW_RECT = 6;
- private static final float[] BOX_COORDINATES = {
- 0, 0, 1, 0, 0, 1, 1, 1, // used for filling a rectangle
- 0, 0, 1, 1, // used for drawing a line
- 0, 0, 0, 1, 1, 1, 1, 0}; // used for drawing the outline of a rectangle
-
- private final GL11 mGL;
-
- private final float mMatrixValues[] = new float[16];
- private final float mTextureMatrixValues[] = new float[16];
-
- // The results of mapPoints are stored in this buffer, and the order is
- // x1, y1, x2, y2.
- private final float mMapPointsBuffer[] = new float[4];
-
- private final float mTextureColor[] = new float[4];
-
- private int mBoxCoords;
-
- private final GLState mGLState;
- private final ArrayList<RawTexture> mTargetStack = new ArrayList<RawTexture>();
-
- private float mAlpha;
- private final ArrayList<ConfigState> mRestoreStack = new ArrayList<ConfigState>();
- private ConfigState mRecycledRestoreAction;
-
- private final RectF mDrawTextureSourceRect = new RectF();
- private final RectF mDrawTextureTargetRect = new RectF();
- private final float[] mTempMatrix = new float[32];
- private final IntArray mUnboundTextures = new IntArray();
- private final IntArray mDeleteBuffers = new IntArray();
- private int mScreenWidth;
- private int mScreenHeight;
- private boolean mBlendEnabled = true;
- private int mFrameBuffer[] = new int[1];
-
- private RawTexture mTargetTexture;
-
- // Drawing statistics
- int mCountDrawLine;
- int mCountFillRect;
- int mCountDrawMesh;
- int mCountTextureRect;
- int mCountTextureOES;
-
- GLCanvasImpl(GL11 gl) {
- mGL = gl;
- mGLState = new GLState(gl);
- initialize();
- }
-
- @Override
- public void setSize(int width, int height) {
- Utils.assertTrue(width >= 0 && height >= 0);
-
- if (mTargetTexture == null) {
- mScreenWidth = width;
- mScreenHeight = height;
- }
- mAlpha = 1.0f;
-
- GL11 gl = mGL;
- gl.glViewport(0, 0, width, height);
- gl.glMatrixMode(GL11.GL_PROJECTION);
- gl.glLoadIdentity();
- GLU.gluOrtho2D(gl, 0, width, 0, height);
-
- gl.glMatrixMode(GL11.GL_MODELVIEW);
- gl.glLoadIdentity();
-
- float matrix[] = mMatrixValues;
- Matrix.setIdentityM(matrix, 0);
- // to match the graphic coordinate system in android, we flip it vertically.
- if (mTargetTexture == null) {
- Matrix.translateM(matrix, 0, 0, height, 0);
- Matrix.scaleM(matrix, 0, 1, -1, 1);
- }
- }
-
- @Override
- public void setAlpha(float alpha) {
- Utils.assertTrue(alpha >= 0 && alpha <= 1);
- mAlpha = alpha;
- }
-
- @Override
- public float getAlpha() {
- return mAlpha;
- }
-
- @Override
- public void multiplyAlpha(float alpha) {
- Utils.assertTrue(alpha >= 0 && alpha <= 1);
- mAlpha *= alpha;
- }
-
- private static ByteBuffer allocateDirectNativeOrderBuffer(int size) {
- return ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder());
- }
-
- private void initialize() {
- GL11 gl = mGL;
-
- // First create an nio buffer, then create a VBO from it.
- int size = BOX_COORDINATES.length * Float.SIZE / Byte.SIZE;
- FloatBuffer xyBuffer = allocateDirectNativeOrderBuffer(size).asFloatBuffer();
- xyBuffer.put(BOX_COORDINATES, 0, BOX_COORDINATES.length).position(0);
-
- int[] name = new int[1];
- GLId.glGenBuffers(1, name, 0);
- mBoxCoords = name[0];
-
- gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, mBoxCoords);
- gl.glBufferData(GL11.GL_ARRAY_BUFFER,
- xyBuffer.capacity() * (Float.SIZE / Byte.SIZE),
- xyBuffer, GL11.GL_STATIC_DRAW);
-
- gl.glVertexPointer(2, GL11.GL_FLOAT, 0, 0);
- gl.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0);
-
- // Enable the texture coordinate array for Texture 1
- gl.glClientActiveTexture(GL11.GL_TEXTURE1);
- gl.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0);
- gl.glClientActiveTexture(GL11.GL_TEXTURE0);
- gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
-
- // mMatrixValues and mAlpha will be initialized in setSize()
- }
-
- @Override
- public void drawRect(float x, float y, float width, float height, GLPaint paint) {
- GL11 gl = mGL;
-
- mGLState.setColorMode(paint.getColor(), mAlpha);
- mGLState.setLineWidth(paint.getLineWidth());
-
- saveTransform();
- translate(x, y);
- scale(width, height, 1);
-
- gl.glLoadMatrixf(mMatrixValues, 0);
- gl.glDrawArrays(GL11.GL_LINE_LOOP, OFFSET_DRAW_RECT, 4);
-
- restoreTransform();
- mCountDrawLine++;
- }
-
- @Override
- public void drawLine(float x1, float y1, float x2, float y2, GLPaint paint) {
- GL11 gl = mGL;
-
- mGLState.setColorMode(paint.getColor(), mAlpha);
- mGLState.setLineWidth(paint.getLineWidth());
-
- saveTransform();
- translate(x1, y1);
- scale(x2 - x1, y2 - y1, 1);
-
- gl.glLoadMatrixf(mMatrixValues, 0);
- gl.glDrawArrays(GL11.GL_LINE_STRIP, OFFSET_DRAW_LINE, 2);
-
- restoreTransform();
- mCountDrawLine++;
- }
-
- @Override
- public void fillRect(float x, float y, float width, float height, int color) {
- mGLState.setColorMode(color, mAlpha);
- GL11 gl = mGL;
-
- saveTransform();
- translate(x, y);
- scale(width, height, 1);
-
- gl.glLoadMatrixf(mMatrixValues, 0);
- gl.glDrawArrays(GL11.GL_TRIANGLE_STRIP, OFFSET_FILL_RECT, 4);
-
- restoreTransform();
- mCountFillRect++;
- }
-
- @Override
- public void translate(float x, float y, float z) {
- Matrix.translateM(mMatrixValues, 0, x, y, z);
- }
-
- // This is a faster version of translate(x, y, z) because
- // (1) we knows z = 0, (2) we inline the Matrix.translateM call,
- // (3) we unroll the loop
- @Override
- public void translate(float x, float y) {
- float[] m = mMatrixValues;
- m[12] += m[0] * x + m[4] * y;
- m[13] += m[1] * x + m[5] * y;
- m[14] += m[2] * x + m[6] * y;
- m[15] += m[3] * x + m[7] * y;
- }
-
- @Override
- public void scale(float sx, float sy, float sz) {
- Matrix.scaleM(mMatrixValues, 0, sx, sy, sz);
- }
-
- @Override
- public void rotate(float angle, float x, float y, float z) {
- if (angle == 0) return;
- float[] temp = mTempMatrix;
- Matrix.setRotateM(temp, 0, angle, x, y, z);
- Matrix.multiplyMM(temp, 16, mMatrixValues, 0, temp, 0);
- System.arraycopy(temp, 16, mMatrixValues, 0, 16);
- }
-
- @Override
- public void multiplyMatrix(float matrix[], int offset) {
- float[] temp = mTempMatrix;
- Matrix.multiplyMM(temp, 0, mMatrixValues, 0, matrix, offset);
- System.arraycopy(temp, 0, mMatrixValues, 0, 16);
- }
-
- private void textureRect(float x, float y, float width, float height) {
- GL11 gl = mGL;
-
- saveTransform();
- translate(x, y);
- scale(width, height, 1);
-
- gl.glLoadMatrixf(mMatrixValues, 0);
- gl.glDrawArrays(GL11.GL_TRIANGLE_STRIP, OFFSET_FILL_RECT, 4);
-
- restoreTransform();
- mCountTextureRect++;
- }
-
- @Override
- public void drawMesh(BasicTexture tex, int x, int y, int xyBuffer,
- int uvBuffer, int indexBuffer, int indexCount) {
- float alpha = mAlpha;
- if (!bindTexture(tex)) return;
-
- mGLState.setBlendEnabled(mBlendEnabled
- && (!tex.isOpaque() || alpha < OPAQUE_ALPHA));
- mGLState.setTextureAlpha(alpha);
-
- // Reset the texture matrix. We will set our own texture coordinates
- // below.
- setTextureCoords(0, 0, 1, 1);
-
- saveTransform();
- translate(x, y);
-
- mGL.glLoadMatrixf(mMatrixValues, 0);
-
- mGL.glBindBuffer(GL11.GL_ARRAY_BUFFER, xyBuffer);
- mGL.glVertexPointer(2, GL11.GL_FLOAT, 0, 0);
-
- mGL.glBindBuffer(GL11.GL_ARRAY_BUFFER, uvBuffer);
- mGL.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0);
-
- mGL.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
- mGL.glDrawElements(GL11.GL_TRIANGLE_STRIP,
- indexCount, GL11.GL_UNSIGNED_BYTE, 0);
-
- mGL.glBindBuffer(GL11.GL_ARRAY_BUFFER, mBoxCoords);
- mGL.glVertexPointer(2, GL11.GL_FLOAT, 0, 0);
- mGL.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0);
-
- restoreTransform();
- mCountDrawMesh++;
- }
-
- // Transforms two points by the given matrix m. The result
- // {x1', y1', x2', y2'} are stored in mMapPointsBuffer and also returned.
- private float[] mapPoints(float m[], int x1, int y1, int x2, int y2) {
- float[] r = mMapPointsBuffer;
-
- // Multiply m and (x1 y1 0 1) to produce (x3 y3 z3 w3). z3 is unused.
- float x3 = m[0] * x1 + m[4] * y1 + m[12];
- float y3 = m[1] * x1 + m[5] * y1 + m[13];
- float w3 = m[3] * x1 + m[7] * y1 + m[15];
- r[0] = x3 / w3;
- r[1] = y3 / w3;
-
- // Same for x2 y2.
- float x4 = m[0] * x2 + m[4] * y2 + m[12];
- float y4 = m[1] * x2 + m[5] * y2 + m[13];
- float w4 = m[3] * x2 + m[7] * y2 + m[15];
- r[2] = x4 / w4;
- r[3] = y4 / w4;
-
- return r;
- }
-
- private void drawBoundTexture(
- BasicTexture texture, int x, int y, int width, int height) {
- // Test whether it has been rotated or flipped, if so, glDrawTexiOES
- // won't work
- if (isMatrixRotatedOrFlipped(mMatrixValues)) {
- if (texture.hasBorder()) {
- setTextureCoords(
- 1.0f / texture.getTextureWidth(),
- 1.0f / texture.getTextureHeight(),
- (texture.getWidth() - 1.0f) / texture.getTextureWidth(),
- (texture.getHeight() - 1.0f) / texture.getTextureHeight());
- } else {
- setTextureCoords(0, 0,
- (float) texture.getWidth() / texture.getTextureWidth(),
- (float) texture.getHeight() / texture.getTextureHeight());
- }
- textureRect(x, y, width, height);
- } else {
- // draw the rect from bottom-left to top-right
- float points[] = mapPoints(
- mMatrixValues, x, y + height, x + width, y);
- x = (int) (points[0] + 0.5f);
- y = (int) (points[1] + 0.5f);
- width = (int) (points[2] + 0.5f) - x;
- height = (int) (points[3] + 0.5f) - y;
- if (width > 0 && height > 0) {
- ((GL11Ext) mGL).glDrawTexiOES(x, y, 0, width, height);
- mCountTextureOES++;
- }
- }
- }
-
- @Override
- public void drawTexture(
- BasicTexture texture, int x, int y, int width, int height) {
- drawTexture(texture, x, y, width, height, mAlpha);
- }
-
- private void drawTexture(BasicTexture texture,
- int x, int y, int width, int height, float alpha) {
- if (width <= 0 || height <= 0) return;
-
- mGLState.setBlendEnabled(mBlendEnabled
- && (!texture.isOpaque() || alpha < OPAQUE_ALPHA));
- if (!bindTexture(texture)) return;
- mGLState.setTextureAlpha(alpha);
- drawBoundTexture(texture, x, y, width, height);
- }
-
- @Override
- public void drawTexture(BasicTexture texture, RectF source, RectF target) {
- if (target.width() <= 0 || target.height() <= 0) return;
-
- // Copy the input to avoid changing it.
- mDrawTextureSourceRect.set(source);
- mDrawTextureTargetRect.set(target);
- source = mDrawTextureSourceRect;
- target = mDrawTextureTargetRect;
-
- mGLState.setBlendEnabled(mBlendEnabled
- && (!texture.isOpaque() || mAlpha < OPAQUE_ALPHA));
- if (!bindTexture(texture)) return;
- convertCoordinate(source, target, texture);
- setTextureCoords(source);
- mGLState.setTextureAlpha(mAlpha);
- textureRect(target.left, target.top, target.width(), target.height());
- }
-
- @Override
- public void drawTexture(BasicTexture texture, float[] mTextureTransform,
- int x, int y, int w, int h) {
- mGLState.setBlendEnabled(mBlendEnabled
- && (!texture.isOpaque() || mAlpha < OPAQUE_ALPHA));
- if (!bindTexture(texture)) return;
- setTextureCoords(mTextureTransform);
- mGLState.setTextureAlpha(mAlpha);
- textureRect(x, y, w, h);
- }
-
- // This function changes the source coordinate to the texture coordinates.
- // It also clips the source and target coordinates if it is beyond the
- // bound of the texture.
- private static void convertCoordinate(RectF source, RectF target,
- BasicTexture texture) {
-
- int width = texture.getWidth();
- int height = texture.getHeight();
- int texWidth = texture.getTextureWidth();
- int texHeight = texture.getTextureHeight();
- // Convert to texture coordinates
- source.left /= texWidth;
- source.right /= texWidth;
- source.top /= texHeight;
- source.bottom /= texHeight;
-
- // Clip if the rendering range is beyond the bound of the texture.
- float xBound = (float) width / texWidth;
- if (source.right > xBound) {
- target.right = target.left + target.width() *
- (xBound - source.left) / source.width();
- source.right = xBound;
- }
- float yBound = (float) height / texHeight;
- if (source.bottom > yBound) {
- target.bottom = target.top + target.height() *
- (yBound - source.top) / source.height();
- source.bottom = yBound;
- }
- }
-
- @Override
- public void drawMixed(BasicTexture from,
- int toColor, float ratio, int x, int y, int w, int h) {
- drawMixed(from, toColor, ratio, x, y, w, h, mAlpha);
- }
-
- private boolean bindTexture(BasicTexture texture) {
- if (!texture.onBind(this)) return false;
- int target = texture.getTarget();
- mGLState.setTextureTarget(target);
- mGL.glBindTexture(target, texture.getId());
- return true;
- }
-
- private void setTextureColor(float r, float g, float b, float alpha) {
- float[] color = mTextureColor;
- color[0] = r;
- color[1] = g;
- color[2] = b;
- color[3] = alpha;
- }
-
- private void setMixedColor(int toColor, float ratio, float alpha) {
- //
- // The formula we want:
- // alpha * ((1 - ratio) * from + ratio * to)
- //
- // The formula that GL supports is in the form of:
- // combo * from + (1 - combo) * to * scale
- //
- // So, we have combo = alpha * (1 - ratio)
- // and scale = alpha * ratio / (1 - combo)
- //
- float combo = alpha * (1 - ratio);
- float scale = alpha * ratio / (1 - combo);
-
- // Specify the interpolation factor via the alpha component of
- // GL_TEXTURE_ENV_COLORs.
- // RGB component are get from toColor and will used as SRC1
- float colorScale = scale * (toColor >>> 24) / (0xff * 0xff);
- setTextureColor(((toColor >>> 16) & 0xff) * colorScale,
- ((toColor >>> 8) & 0xff) * colorScale,
- (toColor & 0xff) * colorScale, combo);
- GL11 gl = mGL;
- gl.glTexEnvfv(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_COLOR, mTextureColor, 0);
-
- gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_COMBINE_RGB, GL11.GL_INTERPOLATE);
- gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_COMBINE_ALPHA, GL11.GL_INTERPOLATE);
- gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC1_RGB, GL11.GL_CONSTANT);
- gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND1_RGB, GL11.GL_SRC_COLOR);
- gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC1_ALPHA, GL11.GL_CONSTANT);
- gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND1_ALPHA, GL11.GL_SRC_ALPHA);
-
- // Wire up the interpolation factor for RGB.
- gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC2_RGB, GL11.GL_CONSTANT);
- gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND2_RGB, GL11.GL_SRC_ALPHA);
-
- // Wire up the interpolation factor for alpha.
- gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC2_ALPHA, GL11.GL_CONSTANT);
- gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND2_ALPHA, GL11.GL_SRC_ALPHA);
-
- }
-
- @Override
- public void drawMixed(BasicTexture from, int toColor, float ratio,
- RectF source, RectF target) {
- if (target.width() <= 0 || target.height() <= 0) return;
-
- if (ratio <= 0.01f) {
- drawTexture(from, source, target);
- return;
- } else if (ratio >= 1) {
- fillRect(target.left, target.top, target.width(), target.height(), toColor);
- return;
- }
-
- float alpha = mAlpha;
-
- // Copy the input to avoid changing it.
- mDrawTextureSourceRect.set(source);
- mDrawTextureTargetRect.set(target);
- source = mDrawTextureSourceRect;
- target = mDrawTextureTargetRect;
-
- mGLState.setBlendEnabled(mBlendEnabled && (!from.isOpaque()
- || !Utils.isOpaque(toColor) || alpha < OPAQUE_ALPHA));
-
- if (!bindTexture(from)) return;
-
- // Interpolate the RGB and alpha values between both textures.
- mGLState.setTexEnvMode(GL11.GL_COMBINE);
- setMixedColor(toColor, ratio, alpha);
- convertCoordinate(source, target, from);
- setTextureCoords(source);
- textureRect(target.left, target.top, target.width(), target.height());
- mGLState.setTexEnvMode(GL11.GL_REPLACE);
- }
-
- private void drawMixed(BasicTexture from, int toColor,
- float ratio, int x, int y, int width, int height, float alpha) {
- // change from 0 to 0.01f to prevent getting divided by zero below
- if (ratio <= 0.01f) {
- drawTexture(from, x, y, width, height, alpha);
- return;
- } else if (ratio >= 1) {
- fillRect(x, y, width, height, toColor);
- return;
- }
-
- mGLState.setBlendEnabled(mBlendEnabled && (!from.isOpaque()
- || !Utils.isOpaque(toColor) || alpha < OPAQUE_ALPHA));
-
- final GL11 gl = mGL;
- if (!bindTexture(from)) return;
-
- // Interpolate the RGB and alpha values between both textures.
- mGLState.setTexEnvMode(GL11.GL_COMBINE);
- setMixedColor(toColor, ratio, alpha);
-
- drawBoundTexture(from, x, y, width, height);
- mGLState.setTexEnvMode(GL11.GL_REPLACE);
- }
-
- // TODO: the code only work for 2D should get fixed for 3D or removed
- private static final int MSKEW_X = 4;
- private static final int MSKEW_Y = 1;
- private static final int MSCALE_X = 0;
- private static final int MSCALE_Y = 5;
-
- private static boolean isMatrixRotatedOrFlipped(float matrix[]) {
- final float eps = 1e-5f;
- return Math.abs(matrix[MSKEW_X]) > eps
- || Math.abs(matrix[MSKEW_Y]) > eps
- || matrix[MSCALE_X] < -eps
- || matrix[MSCALE_Y] > eps;
- }
-
- private static class GLState {
-
- private final GL11 mGL;
-
- private int mTexEnvMode = GL11.GL_REPLACE;
- private float mTextureAlpha = 1.0f;
- private int mTextureTarget = GL11.GL_TEXTURE_2D;
- private boolean mBlendEnabled = true;
- private float mLineWidth = 1.0f;
- private boolean mLineSmooth = false;
-
- public GLState(GL11 gl) {
- mGL = gl;
-
- // Disable unused state
- gl.glDisable(GL11.GL_LIGHTING);
-
- // Enable used features
- gl.glEnable(GL11.GL_DITHER);
-
- gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
- gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
- gl.glEnable(GL11.GL_TEXTURE_2D);
-
- gl.glTexEnvf(GL11.GL_TEXTURE_ENV,
- GL11.GL_TEXTURE_ENV_MODE, GL11.GL_REPLACE);
-
- // Set the background color
- gl.glClearColor(0f, 0f, 0f, 0f);
- gl.glClearStencil(0);
-
- gl.glEnable(GL11.GL_BLEND);
- gl.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
-
- // We use 565 or 8888 format, so set the alignment to 2 bytes/pixel.
- gl.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 2);
- }
-
- public void setTexEnvMode(int mode) {
- if (mTexEnvMode == mode) return;
- mTexEnvMode = mode;
- mGL.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, mode);
- }
-
- public void setLineWidth(float width) {
- if (mLineWidth == width) return;
- mLineWidth = width;
- mGL.glLineWidth(width);
- }
-
- public void setTextureAlpha(float alpha) {
- if (mTextureAlpha == alpha) return;
- mTextureAlpha = alpha;
- if (alpha >= OPAQUE_ALPHA) {
- // The alpha is need for those texture without alpha channel
- mGL.glColor4f(1, 1, 1, 1);
- setTexEnvMode(GL11.GL_REPLACE);
- } else {
- mGL.glColor4f(alpha, alpha, alpha, alpha);
- setTexEnvMode(GL11.GL_MODULATE);
- }
- }
-
- public void setColorMode(int color, float alpha) {
- setBlendEnabled(!Utils.isOpaque(color) || alpha < OPAQUE_ALPHA);
-
- // Set mTextureAlpha to an invalid value, so that it will reset
- // again in setTextureAlpha(float) later.
- mTextureAlpha = -1.0f;
-
- setTextureTarget(0);
-
- float prealpha = (color >>> 24) * alpha * 65535f / 255f / 255f;
- mGL.glColor4x(
- Math.round(((color >> 16) & 0xFF) * prealpha),
- Math.round(((color >> 8) & 0xFF) * prealpha),
- Math.round((color & 0xFF) * prealpha),
- Math.round(255 * prealpha));
- }
-
- // target is a value like GL_TEXTURE_2D. If target = 0, texturing is disabled.
- public void setTextureTarget(int target) {
- if (mTextureTarget == target) return;
- if (mTextureTarget != 0) {
- mGL.glDisable(mTextureTarget);
- }
- mTextureTarget = target;
- if (mTextureTarget != 0) {
- mGL.glEnable(mTextureTarget);
- }
- }
-
- public void setBlendEnabled(boolean enabled) {
- if (mBlendEnabled == enabled) return;
- mBlendEnabled = enabled;
- if (enabled) {
- mGL.glEnable(GL11.GL_BLEND);
- } else {
- mGL.glDisable(GL11.GL_BLEND);
- }
- }
- }
-
- @Override
- public GL11 getGLInstance() {
- return mGL;
- }
-
- @Override
- public void clearBuffer(float[] argb) {
- if(argb != null && argb.length == 4) {
- mGL.glClearColor(argb[1], argb[2], argb[3], argb[0]);
- } else {
- mGL.glClearColor(0, 0, 0, 1);
- }
- mGL.glClear(GL10.GL_COLOR_BUFFER_BIT);
- }
-
- @Override
- public void clearBuffer() {
- clearBuffer(null);
- }
-
- private void setTextureCoords(RectF source) {
- setTextureCoords(source.left, source.top, source.right, source.bottom);
- }
-
- private void setTextureCoords(float left, float top,
- float right, float bottom) {
- mGL.glMatrixMode(GL11.GL_TEXTURE);
- mTextureMatrixValues[0] = right - left;
- mTextureMatrixValues[5] = bottom - top;
- mTextureMatrixValues[10] = 1;
- mTextureMatrixValues[12] = left;
- mTextureMatrixValues[13] = top;
- mTextureMatrixValues[15] = 1;
- mGL.glLoadMatrixf(mTextureMatrixValues, 0);
- mGL.glMatrixMode(GL11.GL_MODELVIEW);
- }
-
- private void setTextureCoords(float[] mTextureTransform) {
- mGL.glMatrixMode(GL11.GL_TEXTURE);
- mGL.glLoadMatrixf(mTextureTransform, 0);
- mGL.glMatrixMode(GL11.GL_MODELVIEW);
- }
-
- // unloadTexture and deleteBuffer can be called from the finalizer thread,
- // so we synchronized on the mUnboundTextures object.
- @Override
- public boolean unloadTexture(BasicTexture t) {
- synchronized (mUnboundTextures) {
- if (!t.isLoaded()) return false;
- mUnboundTextures.add(t.mId);
- return true;
- }
- }
-
- @Override
- public void deleteBuffer(int bufferId) {
- synchronized (mUnboundTextures) {
- mDeleteBuffers.add(bufferId);
- }
- }
-
- @Override
- public void deleteRecycledResources() {
- synchronized (mUnboundTextures) {
- IntArray ids = mUnboundTextures;
- if (ids.size() > 0) {
- GLId.glDeleteTextures(mGL, ids.size(), ids.getInternalArray(), 0);
- ids.clear();
- }
-
- ids = mDeleteBuffers;
- if (ids.size() > 0) {
- GLId.glDeleteBuffers(mGL, ids.size(), ids.getInternalArray(), 0);
- ids.clear();
- }
- }
- }
-
- @Override
- public void save() {
- save(SAVE_FLAG_ALL);
- }
-
- @Override
- public void save(int saveFlags) {
- ConfigState config = obtainRestoreConfig();
-
- if ((saveFlags & SAVE_FLAG_ALPHA) != 0) {
- config.mAlpha = mAlpha;
- } else {
- config.mAlpha = -1;
- }
-
-
- if ((saveFlags & SAVE_FLAG_MATRIX) != 0) {
- System.arraycopy(mMatrixValues, 0, config.mMatrix, 0, 16);
- } else {
- config.mMatrix[0] = Float.NEGATIVE_INFINITY;
- }
-
- mRestoreStack.add(config);
- }
-
- @Override
- public void restore() {
- if (mRestoreStack.isEmpty()) throw new IllegalStateException();
- ConfigState config = mRestoreStack.remove(mRestoreStack.size() - 1);
- config.restore(this);
- freeRestoreConfig(config);
- }
-
- private void freeRestoreConfig(ConfigState action) {
- action.mNextFree = mRecycledRestoreAction;
- mRecycledRestoreAction = action;
- }
-
- private ConfigState obtainRestoreConfig() {
- if (mRecycledRestoreAction != null) {
- ConfigState result = mRecycledRestoreAction;
- mRecycledRestoreAction = result.mNextFree;
- return result;
- }
- return new ConfigState();
- }
-
- private static class ConfigState {
- float mAlpha;
- float mMatrix[] = new float[16];
- ConfigState mNextFree;
-
- public void restore(GLCanvasImpl canvas) {
- if (mAlpha >= 0) canvas.setAlpha(mAlpha);
- if (mMatrix[0] != Float.NEGATIVE_INFINITY) {
- System.arraycopy(mMatrix, 0, canvas.mMatrixValues, 0, 16);
- }
- }
- }
-
- @Override
- public void dumpStatisticsAndClear() {
- String line = String.format(
- "MESH:%d, TEX_OES:%d, TEX_RECT:%d, FILL_RECT:%d, LINE:%d",
- mCountDrawMesh, mCountTextureRect, mCountTextureOES,
- mCountFillRect, mCountDrawLine);
- mCountDrawMesh = 0;
- mCountTextureRect = 0;
- mCountTextureOES = 0;
- mCountFillRect = 0;
- mCountDrawLine = 0;
- Log.d(TAG, line);
- }
-
- private void saveTransform() {
- System.arraycopy(mMatrixValues, 0, mTempMatrix, 0, 16);
- }
-
- private void restoreTransform() {
- System.arraycopy(mTempMatrix, 0, mMatrixValues, 0, 16);
- }
-
- private void setRenderTarget(RawTexture texture) {
- GL11ExtensionPack gl11ep = (GL11ExtensionPack) mGL;
-
- if (mTargetTexture == null && texture != null) {
- GLId.glGenBuffers(1, mFrameBuffer, 0);
- gl11ep.glBindFramebufferOES(
- GL11ExtensionPack.GL_FRAMEBUFFER_OES, mFrameBuffer[0]);
- }
- if (mTargetTexture != null && texture == null) {
- gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, 0);
- gl11ep.glDeleteFramebuffersOES(1, mFrameBuffer, 0);
- }
-
- mTargetTexture = texture;
- if (texture == null) {
- setSize(mScreenWidth, mScreenHeight);
- } else {
- setSize(texture.getWidth(), texture.getHeight());
-
- if (!texture.isLoaded()) texture.prepare(this);
-
- gl11ep.glFramebufferTexture2DOES(
- GL11ExtensionPack.GL_FRAMEBUFFER_OES,
- GL11ExtensionPack.GL_COLOR_ATTACHMENT0_OES,
- GL11.GL_TEXTURE_2D, texture.getId(), 0);
-
- checkFramebufferStatus(gl11ep);
- }
- }
-
- @Override
- public void endRenderTarget() {
- RawTexture texture = mTargetStack.remove(mTargetStack.size() - 1);
- setRenderTarget(texture);
- restore(); // restore matrix and alpha
- }
-
- @Override
- public void beginRenderTarget(RawTexture texture) {
- save(); // save matrix and alpha
- mTargetStack.add(mTargetTexture);
- setRenderTarget(texture);
- }
-
- private static void checkFramebufferStatus(GL11ExtensionPack gl11ep) {
- int status = gl11ep.glCheckFramebufferStatusOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES);
- if (status != GL11ExtensionPack.GL_FRAMEBUFFER_COMPLETE_OES) {
- String msg = "";
- switch (status) {
- case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES:
- msg = "FRAMEBUFFER_FORMATS";
- break;
- case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES:
- msg = "FRAMEBUFFER_ATTACHMENT";
- break;
- case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES:
- msg = "FRAMEBUFFER_MISSING_ATTACHMENT";
- break;
- case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES:
- msg = "FRAMEBUFFER_DRAW_BUFFER";
- break;
- case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES:
- msg = "FRAMEBUFFER_READ_BUFFER";
- break;
- case GL11ExtensionPack.GL_FRAMEBUFFER_UNSUPPORTED_OES:
- msg = "FRAMEBUFFER_UNSUPPORTED";
- break;
- case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES:
- msg = "FRAMEBUFFER_INCOMPLETE_DIMENSIONS";
- break;
- }
- throw new RuntimeException(msg + ":" + Integer.toHexString(status));
- }
- }
-}
diff --git a/src/com/android/gallery3d/ui/GLId.java b/src/com/android/gallery3d/ui/GLId.java
deleted file mode 100644
index 689cf192e..000000000
--- a/src/com/android/gallery3d/ui/GLId.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2012 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.gallery3d.ui;
-
-import javax.microedition.khronos.opengles.GL11;
-import javax.microedition.khronos.opengles.GL11ExtensionPack;
-
-// This mimics corresponding GL functions.
-public class GLId {
- static int sNextId = 1;
-
- public synchronized static void glGenTextures(int n, int[] textures, int offset) {
- while (n-- > 0) {
- textures[offset + n] = sNextId++;
- }
- }
-
- public synchronized static void glGenBuffers(int n, int[] buffers, int offset) {
- while (n-- > 0) {
- buffers[offset + n] = sNextId++;
- }
- }
-
- public synchronized static void glDeleteTextures(GL11 gl, int n, int[] textures, int offset) {
- gl.glDeleteTextures(n, textures, offset);
- }
-
- public synchronized static void glDeleteBuffers(GL11 gl, int n, int[] buffers, int offset) {
- gl.glDeleteBuffers(n, buffers, offset);
- }
-
- public synchronized static void glDeleteFramebuffers(
- GL11ExtensionPack gl11ep, int n, int[] buffers, int offset) {
- gl11ep.glDeleteFramebuffersOES(n, buffers, offset);
- }
-}
diff --git a/src/com/android/gallery3d/ui/GLPaint.java b/src/com/android/gallery3d/ui/GLPaint.java
deleted file mode 100644
index eb75cc51e..000000000
--- a/src/com/android/gallery3d/ui/GLPaint.java
+++ /dev/null
@@ -1,42 +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.gallery3d.ui;
-
-import com.android.gallery3d.common.Utils;
-
-
-public class GLPaint {
- private float mLineWidth = 1f;
- private int mColor = 0;
-
- public void setColor(int color) {
- mColor = color;
- }
-
- public int getColor() {
- return mColor;
- }
-
- public void setLineWidth(float width) {
- Utils.assertTrue(width >= 0);
- mLineWidth = width;
- }
-
- public float getLineWidth() {
- return mLineWidth;
- }
-}
diff --git a/src/com/android/gallery3d/ui/GLRoot.java b/src/com/android/gallery3d/ui/GLRoot.java
index e406b6703..33a82eaf7 100644
--- a/src/com/android/gallery3d/ui/GLRoot.java
+++ b/src/com/android/gallery3d/ui/GLRoot.java
@@ -20,6 +20,7 @@ import android.content.Context;
import android.graphics.Matrix;
import com.android.gallery3d.anim.CanvasAnimation;
+import com.android.gallery3d.glrenderer.GLCanvas;
public interface GLRoot {
diff --git a/src/com/android/gallery3d/ui/GLRootView.java b/src/com/android/gallery3d/ui/GLRootView.java
index b7c48bf2e..755e10733 100644
--- a/src/com/android/gallery3d/ui/GLRootView.java
+++ b/src/com/android/gallery3d/ui/GLRootView.java
@@ -33,6 +33,9 @@ import com.android.gallery3d.R;
import com.android.gallery3d.anim.CanvasAnimation;
import com.android.gallery3d.common.ApiHelper;
import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.glrenderer.BasicTexture;
+import com.android.gallery3d.glrenderer.GLCanvas;
+import com.android.gallery3d.glrenderer.UploadedTexture;
import com.android.gallery3d.util.GalleryUtils;
import com.android.gallery3d.util.MotionEventHelper;
import com.android.gallery3d.util.Profile;
@@ -117,6 +120,7 @@ public class GLRootView extends GLSurfaceView
super(context, attrs);
mFlags |= FLAG_INITIALIZED;
setBackgroundDrawable(null);
+ setEGLContextClientVersion(GLCanvas.getEGLContextClientVersion());
setEGLConfigChooser(mEglConfigChooser);
setRenderer(this);
if (ApiHelper.USE_888_PIXEL_FORMAT) {
@@ -283,7 +287,8 @@ public class GLRootView extends GLSurfaceView
mRenderLock.lock();
try {
mGL = gl;
- mCanvas = new GLCanvasImpl(gl);
+ mCanvas = GLCanvas.getInstance();
+ mCanvas.initialize(gl);
BasicTexture.invalidateAllTextures();
} finally {
mRenderLock.unlock();
diff --git a/src/com/android/gallery3d/ui/GLView.java b/src/com/android/gallery3d/ui/GLView.java
index 664012c5a..83de19fe4 100644
--- a/src/com/android/gallery3d/ui/GLView.java
+++ b/src/com/android/gallery3d/ui/GLView.java
@@ -23,6 +23,7 @@ import android.view.MotionEvent;
import com.android.gallery3d.anim.CanvasAnimation;
import com.android.gallery3d.anim.StateTransitionAnimation;
import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.glrenderer.GLCanvas;
import java.util.ArrayList;
diff --git a/src/com/android/gallery3d/ui/GalleryEGLConfigChooser.java b/src/com/android/gallery3d/ui/GalleryEGLConfigChooser.java
index deeb3b76d..4cf3edb34 100644
--- a/src/com/android/gallery3d/ui/GalleryEGLConfigChooser.java
+++ b/src/com/android/gallery3d/ui/GalleryEGLConfigChooser.java
@@ -18,6 +18,7 @@ package com.android.gallery3d.ui;
import android.opengl.GLSurfaceView.EGLConfigChooser;
import com.android.gallery3d.common.ApiHelper;
+import com.android.gallery3d.glrenderer.GLCanvas;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
@@ -49,12 +50,35 @@ class GalleryEGLConfigChooser implements EGLConfigChooser {
EGL10.EGL_NONE
};
+ private final int mConfig2Spec565[] = new int[] {
+ EGL10.EGL_RED_SIZE, 5,
+ EGL10.EGL_GREEN_SIZE, 6,
+ EGL10.EGL_BLUE_SIZE, 5,
+ EGL10.EGL_ALPHA_SIZE, 0,
+ EGL10.EGL_RENDERABLE_TYPE, 4, /* EGL_OPENGL_ES2_BIT */
+ EGL10.EGL_NONE
+ };
+
+ private final int mConfig2Spec888[] = new int[] {
+ EGL10.EGL_RED_SIZE, 8,
+ EGL10.EGL_GREEN_SIZE, 8,
+ EGL10.EGL_BLUE_SIZE, 8,
+ EGL10.EGL_ALPHA_SIZE, 0,
+ EGL10.EGL_RENDERABLE_TYPE, 4, /* EGL_OPENGL_ES2_BIT */
+ EGL10.EGL_NONE
+ };
+
@Override
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
int[] numConfig = new int[1];
- int mConfigSpec[] = ApiHelper.USE_888_PIXEL_FORMAT
- ? mConfigSpec888 : mConfigSpec565;
- if (!egl.eglChooseConfig(display, mConfigSpec, null, 0, numConfig)) {
+
+ int configSpec[];
+ if (GLCanvas.getEGLContextClientVersion() == 2) {
+ configSpec = ApiHelper.USE_888_PIXEL_FORMAT ? mConfig2Spec888 : mConfig2Spec565;
+ } else {
+ configSpec = ApiHelper.USE_888_PIXEL_FORMAT ? mConfigSpec888 : mConfigSpec565;
+ }
+ if (!egl.eglChooseConfig(display, configSpec, null, 0, numConfig)) {
throw new RuntimeException("eglChooseConfig failed");
}
@@ -64,7 +88,7 @@ class GalleryEGLConfigChooser implements EGLConfigChooser {
EGLConfig[] configs = new EGLConfig[numConfig[0]];
if (!egl.eglChooseConfig(display,
- mConfigSpec, configs, configs.length, numConfig)) {
+ configSpec, configs, configs.length, numConfig)) {
throw new RuntimeException();
}
diff --git a/src/com/android/gallery3d/ui/GestureRecognizer.java b/src/com/android/gallery3d/ui/GestureRecognizer.java
index e4e0c49f5..1e5250b9b 100644
--- a/src/com/android/gallery3d/ui/GestureRecognizer.java
+++ b/src/com/android/gallery3d/ui/GestureRecognizer.java
@@ -32,7 +32,7 @@ public class GestureRecognizer {
boolean onSingleTapUp(float x, float y);
boolean onDoubleTap(float x, float y);
boolean onScroll(float dx, float dy, float totalX, float totalY);
- boolean onFling(float velocityX, float velocityY);
+ boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY);
boolean onScaleBegin(float focusX, float focusY);
boolean onScale(float focusX, float focusY, float scale);
void onScaleEnd();
@@ -94,7 +94,7 @@ public class GestureRecognizer {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
- return mListener.onFling(velocityX, velocityY);
+ return mListener.onFling(e1, e2, velocityX, velocityY);
}
}
diff --git a/src/com/android/gallery3d/ui/Log.java b/src/com/android/gallery3d/ui/Log.java
index 32adc98eb..5570763bb 100644
--- a/src/com/android/gallery3d/ui/Log.java
+++ b/src/com/android/gallery3d/ui/Log.java
@@ -16,6 +16,7 @@
package com.android.gallery3d.ui;
+// TODO: Delete this
public class Log {
public static int v(String tag, String msg) {
return android.util.Log.v(tag, msg);
diff --git a/src/com/android/gallery3d/ui/ManageCacheDrawer.java b/src/com/android/gallery3d/ui/ManageCacheDrawer.java
index e989af27d..d210bd1f1 100644
--- a/src/com/android/gallery3d/ui/ManageCacheDrawer.java
+++ b/src/com/android/gallery3d/ui/ManageCacheDrawer.java
@@ -23,6 +23,9 @@ import com.android.gallery3d.app.AbstractGalleryActivity;
import com.android.gallery3d.data.DataSourceType;
import com.android.gallery3d.data.MediaSet;
import com.android.gallery3d.data.Path;
+import com.android.gallery3d.glrenderer.GLCanvas;
+import com.android.gallery3d.glrenderer.ResourceTexture;
+import com.android.gallery3d.glrenderer.StringTexture;
import com.android.gallery3d.ui.AlbumSetSlidingWindow.AlbumSetEntry;
public class ManageCacheDrawer extends AlbumSetSlotRenderer {
diff --git a/src/com/android/gallery3d/ui/MenuExecutor.java b/src/com/android/gallery3d/ui/MenuExecutor.java
index f432333ce..46e400483 100644
--- a/src/com/android/gallery3d/ui/MenuExecutor.java
+++ b/src/com/android/gallery3d/ui/MenuExecutor.java
@@ -31,7 +31,6 @@ import android.view.MenuItem;
import com.android.gallery3d.R;
import com.android.gallery3d.app.AbstractGalleryActivity;
-import com.android.gallery3d.app.CropImage;
import com.android.gallery3d.common.Utils;
import com.android.gallery3d.data.DataManager;
import com.android.gallery3d.data.MediaItem;
@@ -62,6 +61,7 @@ public class MenuExecutor {
private Future<?> mTask;
// wait the operation to finish when we want to stop it.
private boolean mWaitOnStop;
+ private boolean mPaused;
private final AbstractGalleryActivity mActivity;
private final SelectionManager mSelectionManager;
@@ -113,7 +113,7 @@ public class MenuExecutor {
break;
}
case MSG_TASK_UPDATE: {
- if (mDialog != null) mDialog.setProgress(message.arg1);
+ if (mDialog != null && !mPaused) mDialog.setProgress(message.arg1);
if (message.obj != null) {
ProgressListener listener = (ProgressListener) message.obj;
listener.onProgressUpdate(message.arg1);
@@ -133,13 +133,23 @@ public class MenuExecutor {
if (mTask != null) {
if (!mWaitOnStop) mTask.cancel();
mTask.waitDone();
- mDialog.dismiss();
+ if (mDialog != null && mDialog.isShowing()) mDialog.dismiss();
mDialog = null;
mTask = null;
}
}
+ public void resume() {
+ mPaused = false;
+ if (mDialog != null) mDialog.show();
+ }
+
public void pause() {
+ mPaused = true;
+ if (mDialog != null && mDialog.isShowing()) mDialog.hide();
+ }
+
+ public void destroy() {
stopTaskAndDismissDialog();
}
@@ -161,6 +171,7 @@ public class MenuExecutor {
boolean supportRotate = (supported & MediaObject.SUPPORT_ROTATE) != 0;
boolean supportCrop = (supported & MediaObject.SUPPORT_CROP) != 0;
boolean supportTrim = (supported & MediaObject.SUPPORT_TRIM) != 0;
+ boolean supportMute = (supported & MediaObject.SUPPORT_MUTE) != 0;
boolean supportShare = (supported & MediaObject.SUPPORT_SHARE) != 0;
boolean supportSetAs = (supported & MediaObject.SUPPORT_SETAS) != 0;
boolean supportShowOnMap = (supported & MediaObject.SUPPORT_SHOW_ON_MAP) != 0;
@@ -174,6 +185,7 @@ public class MenuExecutor {
setMenuItemVisible(menu, R.id.action_rotate_cw, supportRotate);
setMenuItemVisible(menu, R.id.action_crop, supportCrop);
setMenuItemVisible(menu, R.id.action_trim, supportTrim);
+ setMenuItemVisible(menu, R.id.action_mute, supportMute);
// Hide panorama until call to updateMenuForPanorama corrects it
setMenuItemVisible(menu, R.id.action_share_panorama, false);
setMenuItemVisible(menu, R.id.action_share, supportShare);
@@ -332,7 +344,7 @@ public class MenuExecutor {
mDialog.show();
}
MediaOperation operation = new MediaOperation(action, ids, listener);
- mTask = mActivity.getThreadPool().submit(operation, null);
+ mTask = mActivity.getBatchServiceThreadPoolIfAvailable().submit(operation, null);
mWaitOnStop = waitOnStop;
}
diff --git a/src/com/android/gallery3d/ui/MultiLineTexture.java b/src/com/android/gallery3d/ui/MultiLineTexture.java
deleted file mode 100644
index b0c3c2bbf..000000000
--- a/src/com/android/gallery3d/ui/MultiLineTexture.java
+++ /dev/null
@@ -1,51 +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.gallery3d.ui;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.text.Layout;
-import android.text.StaticLayout;
-import android.text.TextPaint;
-
-// MultiLineTexture is a texture shows the content of a specified String.
-//
-// To create a MultiLineTexture, use the newInstance() method and specify
-// the String, the font size, and the color.
-class MultiLineTexture extends CanvasTexture {
- private final Layout mLayout;
-
- private MultiLineTexture(Layout layout) {
- super(layout.getWidth(), layout.getHeight());
- mLayout = layout;
- }
-
- public static MultiLineTexture newInstance(
- String text, int maxWidth, float textSize, int color,
- Layout.Alignment alignment) {
- TextPaint paint = StringTexture.getDefaultPaint(textSize, color);
- Layout layout = new StaticLayout(text, 0, text.length(), paint,
- maxWidth, alignment, 1, 0, true, null, 0);
-
- return new MultiLineTexture(layout);
- }
-
- @Override
- protected void onDraw(Canvas canvas, Bitmap backing) {
- mLayout.draw(canvas);
- }
-}
diff --git a/src/com/android/gallery3d/ui/NinePatchChunk.java b/src/com/android/gallery3d/ui/NinePatchChunk.java
deleted file mode 100644
index 61bf22c33..000000000
--- a/src/com/android/gallery3d/ui/NinePatchChunk.java
+++ /dev/null
@@ -1,82 +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.gallery3d.ui;
-
-import android.graphics.Rect;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-// See "frameworks/base/include/utils/ResourceTypes.h" for the format of
-// NinePatch chunk.
-class NinePatchChunk {
-
- public static final int NO_COLOR = 0x00000001;
- public static final int TRANSPARENT_COLOR = 0x00000000;
-
- public Rect mPaddings = new Rect();
-
- public int mDivX[];
- public int mDivY[];
- public int mColor[];
-
- private static void readIntArray(int[] data, ByteBuffer buffer) {
- for (int i = 0, n = data.length; i < n; ++i) {
- data[i] = buffer.getInt();
- }
- }
-
- private static void checkDivCount(int length) {
- if (length == 0 || (length & 0x01) != 0) {
- throw new RuntimeException("invalid nine-patch: " + length);
- }
- }
-
- public static NinePatchChunk deserialize(byte[] data) {
- ByteBuffer byteBuffer =
- ByteBuffer.wrap(data).order(ByteOrder.nativeOrder());
-
- byte wasSerialized = byteBuffer.get();
- if (wasSerialized == 0) return null;
-
- NinePatchChunk chunk = new NinePatchChunk();
- chunk.mDivX = new int[byteBuffer.get()];
- chunk.mDivY = new int[byteBuffer.get()];
- chunk.mColor = new int[byteBuffer.get()];
-
- checkDivCount(chunk.mDivX.length);
- checkDivCount(chunk.mDivY.length);
-
- // skip 8 bytes
- byteBuffer.getInt();
- byteBuffer.getInt();
-
- chunk.mPaddings.left = byteBuffer.getInt();
- chunk.mPaddings.right = byteBuffer.getInt();
- chunk.mPaddings.top = byteBuffer.getInt();
- chunk.mPaddings.bottom = byteBuffer.getInt();
-
- // skip 4 bytes
- byteBuffer.getInt();
-
- readIntArray(chunk.mDivX, byteBuffer);
- readIntArray(chunk.mDivY, byteBuffer);
- readIntArray(chunk.mColor, byteBuffer);
-
- return chunk;
- }
-} \ No newline at end of file
diff --git a/src/com/android/gallery3d/ui/NinePatchTexture.java b/src/com/android/gallery3d/ui/NinePatchTexture.java
deleted file mode 100644
index fa0e9cdc3..000000000
--- a/src/com/android/gallery3d/ui/NinePatchTexture.java
+++ /dev/null
@@ -1,440 +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.gallery3d.ui;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Rect;
-
-import com.android.gallery3d.common.Utils;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
-
-import javax.microedition.khronos.opengles.GL11;
-
-// NinePatchTexture is a texture backed by a NinePatch resource.
-//
-// getPaddings() returns paddings specified in the NinePatch.
-// getNinePatchChunk() returns the layout data specified in the NinePatch.
-//
-public class NinePatchTexture extends ResourceTexture {
- @SuppressWarnings("unused")
- private static final String TAG = "NinePatchTexture";
- private NinePatchChunk mChunk;
- private SmallCache<NinePatchInstance> mInstanceCache
- = new SmallCache<NinePatchInstance>();
-
- public NinePatchTexture(Context context, int resId) {
- super(context, resId);
- }
-
- @Override
- protected Bitmap onGetBitmap() {
- if (mBitmap != null) return mBitmap;
-
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inPreferredConfig = Bitmap.Config.ARGB_8888;
- Bitmap bitmap = BitmapFactory.decodeResource(
- mContext.getResources(), mResId, options);
- mBitmap = bitmap;
- setSize(bitmap.getWidth(), bitmap.getHeight());
- byte[] chunkData = bitmap.getNinePatchChunk();
- mChunk = chunkData == null
- ? null
- : NinePatchChunk.deserialize(bitmap.getNinePatchChunk());
- if (mChunk == null) {
- throw new RuntimeException("invalid nine-patch image: " + mResId);
- }
- return bitmap;
- }
-
- public Rect getPaddings() {
- // get the paddings from nine patch
- if (mChunk == null) onGetBitmap();
- return mChunk.mPaddings;
- }
-
- public NinePatchChunk getNinePatchChunk() {
- if (mChunk == null) onGetBitmap();
- return mChunk;
- }
-
- // This is a simple cache for a small number of things. Linear search
- // is used because the cache is small. It also tries to remove less used
- // item when the cache is full by moving the often-used items to the front.
- private static class SmallCache<V> {
- private static final int CACHE_SIZE = 16;
- private static final int CACHE_SIZE_START_MOVE = CACHE_SIZE / 2;
- private int[] mKey = new int[CACHE_SIZE];
- private V[] mValue = (V[]) new Object[CACHE_SIZE];
- private int mCount; // number of items in this cache
-
- // Puts a value into the cache. If the cache is full, also returns
- // a less used item, otherwise returns null.
- public V put(int key, V value) {
- if (mCount == CACHE_SIZE) {
- V old = mValue[CACHE_SIZE - 1]; // remove the last item
- mKey[CACHE_SIZE - 1] = key;
- mValue[CACHE_SIZE - 1] = value;
- return old;
- } else {
- mKey[mCount] = key;
- mValue[mCount] = value;
- mCount++;
- return null;
- }
- }
-
- public V get(int key) {
- for (int i = 0; i < mCount; i++) {
- if (mKey[i] == key) {
- // Move the accessed item one position to the front, so it
- // will less likely to be removed when cache is full. Only
- // do this if the cache is starting to get full.
- if (mCount > CACHE_SIZE_START_MOVE && i > 0) {
- int tmpKey = mKey[i];
- mKey[i] = mKey[i - 1];
- mKey[i - 1] = tmpKey;
-
- V tmpValue = mValue[i];
- mValue[i] = mValue[i - 1];
- mValue[i - 1] = tmpValue;
- }
- return mValue[i];
- }
- }
- return null;
- }
-
- public void clear() {
- for (int i = 0; i < mCount; i++) {
- mValue[i] = null; // make sure it's can be garbage-collected.
- }
- mCount = 0;
- }
-
- public int size() {
- return mCount;
- }
-
- public V valueAt(int i) {
- return mValue[i];
- }
- }
-
- private NinePatchInstance findInstance(GLCanvas canvas, int w, int h) {
- int key = w;
- key = (key << 16) | h;
- NinePatchInstance instance = mInstanceCache.get(key);
-
- if (instance == null) {
- instance = new NinePatchInstance(this, w, h);
- NinePatchInstance removed = mInstanceCache.put(key, instance);
- if (removed != null) {
- removed.recycle(canvas);
- }
- }
-
- return instance;
- }
-
- @Override
- public void draw(GLCanvas canvas, int x, int y, int w, int h) {
- if (!isLoaded()) {
- mInstanceCache.clear();
- }
-
- if (w != 0 && h != 0) {
- findInstance(canvas, w, h).draw(canvas, this, x, y);
- }
- }
-
- @Override
- public void recycle() {
- super.recycle();
- GLCanvas canvas = mCanvasRef;
- if (canvas == null) return;
- int n = mInstanceCache.size();
- for (int i = 0; i < n; i++) {
- NinePatchInstance instance = mInstanceCache.valueAt(i);
- instance.recycle(canvas);
- }
- mInstanceCache.clear();
- }
-}
-
-// This keeps data for a specialization of NinePatchTexture with the size
-// (width, height). We pre-compute the coordinates for efficiency.
-class NinePatchInstance {
-
- @SuppressWarnings("unused")
- private static final String TAG = "NinePatchInstance";
-
- // We need 16 vertices for a normal nine-patch image (the 4x4 vertices)
- private static final int VERTEX_BUFFER_SIZE = 16 * 2;
-
- // We need 22 indices for a normal nine-patch image, plus 2 for each
- // transparent region. Current there are at most 1 transparent region.
- private static final int INDEX_BUFFER_SIZE = 22 + 2;
-
- private FloatBuffer mXyBuffer;
- private FloatBuffer mUvBuffer;
- private ByteBuffer mIndexBuffer;
-
- // Names for buffer names: xy, uv, index.
- private int[] mBufferNames;
-
- private int mIdxCount;
-
- public NinePatchInstance(NinePatchTexture tex, int width, int height) {
- NinePatchChunk chunk = tex.getNinePatchChunk();
-
- if (width <= 0 || height <= 0) {
- throw new RuntimeException("invalid dimension");
- }
-
- // The code should be easily extended to handle the general cases by
- // allocating more space for buffers. But let's just handle the only
- // use case.
- if (chunk.mDivX.length != 2 || chunk.mDivY.length != 2) {
- throw new RuntimeException("unsupported nine patch");
- }
-
- float divX[] = new float[4];
- float divY[] = new float[4];
- float divU[] = new float[4];
- float divV[] = new float[4];
-
- int nx = stretch(divX, divU, chunk.mDivX, tex.getWidth(), width);
- int ny = stretch(divY, divV, chunk.mDivY, tex.getHeight(), height);
-
- prepareVertexData(divX, divY, divU, divV, nx, ny, chunk.mColor);
- }
-
- /**
- * Stretches the texture according to the nine-patch rules. It will
- * linearly distribute the strechy parts defined in the nine-patch chunk to
- * the target area.
- *
- * <pre>
- * source
- * /--------------^---------------\
- * u0 u1 u2 u3 u4 u5
- * div ---> |fffff|ssssssss|fff|ssssss|ffff| ---> u
- * | div0 div1 div2 div3 |
- * | | / / / /
- * | | / / / /
- * | | / / / /
- * |fffff|ssss|fff|sss|ffff| ---> x
- * x0 x1 x2 x3 x4 x5
- * \----------v------------/
- * target
- *
- * f: fixed segment
- * s: stretchy segment
- * </pre>
- *
- * @param div the stretch parts defined in nine-patch chunk
- * @param source the length of the texture
- * @param target the length on the drawing plan
- * @param u output, the positions of these dividers in the texture
- * coordinate
- * @param x output, the corresponding position of these dividers on the
- * drawing plan
- * @return the number of these dividers.
- */
- private static int stretch(
- float x[], float u[], int div[], int source, int target) {
- int textureSize = Utils.nextPowerOf2(source);
- float textureBound = (float) source / textureSize;
-
- float stretch = 0;
- for (int i = 0, n = div.length; i < n; i += 2) {
- stretch += div[i + 1] - div[i];
- }
-
- float remaining = target - source + stretch;
-
- float lastX = 0;
- float lastU = 0;
-
- x[0] = 0;
- u[0] = 0;
- for (int i = 0, n = div.length; i < n; i += 2) {
- // Make the stretchy segment a little smaller to prevent sampling
- // on neighboring fixed segments.
- // fixed segment
- x[i + 1] = lastX + (div[i] - lastU) + 0.5f;
- u[i + 1] = Math.min((div[i] + 0.5f) / textureSize, textureBound);
-
- // stretchy segment
- float partU = div[i + 1] - div[i];
- float partX = remaining * partU / stretch;
- remaining -= partX;
- stretch -= partU;
-
- lastX = x[i + 1] + partX;
- lastU = div[i + 1];
- x[i + 2] = lastX - 0.5f;
- u[i + 2] = Math.min((lastU - 0.5f)/ textureSize, textureBound);
- }
- // the last fixed segment
- x[div.length + 1] = target;
- u[div.length + 1] = textureBound;
-
- // remove segments with length 0.
- int last = 0;
- for (int i = 1, n = div.length + 2; i < n; ++i) {
- if ((x[i] - x[last]) < 1f) continue;
- x[++last] = x[i];
- u[last] = u[i];
- }
- return last + 1;
- }
-
- private void prepareVertexData(float x[], float y[], float u[], float v[],
- int nx, int ny, int[] color) {
- /*
- * Given a 3x3 nine-patch image, the vertex order is defined as the
- * following graph:
- *
- * (0) (1) (2) (3)
- * | /| /| /|
- * | / | / | / |
- * (4) (5) (6) (7)
- * | \ | \ | \ |
- * | \| \| \|
- * (8) (9) (A) (B)
- * | /| /| /|
- * | / | / | / |
- * (C) (D) (E) (F)
- *
- * And we draw the triangle strip in the following index order:
- *
- * index: 04152637B6A5948C9DAEBF
- */
- int pntCount = 0;
- float xy[] = new float[VERTEX_BUFFER_SIZE];
- float uv[] = new float[VERTEX_BUFFER_SIZE];
- for (int j = 0; j < ny; ++j) {
- for (int i = 0; i < nx; ++i) {
- int xIndex = (pntCount++) << 1;
- int yIndex = xIndex + 1;
- xy[xIndex] = x[i];
- xy[yIndex] = y[j];
- uv[xIndex] = u[i];
- uv[yIndex] = v[j];
- }
- }
-
- int idxCount = 1;
- boolean isForward = false;
- byte index[] = new byte[INDEX_BUFFER_SIZE];
- for (int row = 0; row < ny - 1; row++) {
- --idxCount;
- isForward = !isForward;
-
- int start, end, inc;
- if (isForward) {
- start = 0;
- end = nx;
- inc = 1;
- } else {
- start = nx - 1;
- end = -1;
- inc = -1;
- }
-
- for (int col = start; col != end; col += inc) {
- int k = row * nx + col;
- if (col != start) {
- int colorIdx = row * (nx - 1) + col;
- if (isForward) colorIdx--;
- if (color[colorIdx] == NinePatchChunk.TRANSPARENT_COLOR) {
- index[idxCount] = index[idxCount - 1];
- ++idxCount;
- index[idxCount++] = (byte) k;
- }
- }
-
- index[idxCount++] = (byte) k;
- index[idxCount++] = (byte) (k + nx);
- }
- }
-
- mIdxCount = idxCount;
-
- int size = (pntCount * 2) * (Float.SIZE / Byte.SIZE);
- mXyBuffer = allocateDirectNativeOrderBuffer(size).asFloatBuffer();
- mUvBuffer = allocateDirectNativeOrderBuffer(size).asFloatBuffer();
- mIndexBuffer = allocateDirectNativeOrderBuffer(mIdxCount);
-
- mXyBuffer.put(xy, 0, pntCount * 2).position(0);
- mUvBuffer.put(uv, 0, pntCount * 2).position(0);
- mIndexBuffer.put(index, 0, idxCount).position(0);
- }
-
- private static ByteBuffer allocateDirectNativeOrderBuffer(int size) {
- return ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder());
- }
-
- private void prepareBuffers(GLCanvas canvas) {
- mBufferNames = new int[3];
- GL11 gl = canvas.getGLInstance();
- GLId.glGenBuffers(3, mBufferNames, 0);
-
- gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, mBufferNames[0]);
- gl.glBufferData(GL11.GL_ARRAY_BUFFER,
- mXyBuffer.capacity() * (Float.SIZE / Byte.SIZE),
- mXyBuffer, GL11.GL_STATIC_DRAW);
-
- gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, mBufferNames[1]);
- gl.glBufferData(GL11.GL_ARRAY_BUFFER,
- mUvBuffer.capacity() * (Float.SIZE / Byte.SIZE),
- mUvBuffer, GL11.GL_STATIC_DRAW);
-
- gl.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, mBufferNames[2]);
- gl.glBufferData(GL11.GL_ELEMENT_ARRAY_BUFFER,
- mIndexBuffer.capacity(),
- mIndexBuffer, GL11.GL_STATIC_DRAW);
-
- // These buffers are never used again.
- mXyBuffer = null;
- mUvBuffer = null;
- mIndexBuffer = null;
- }
-
- public void draw(GLCanvas canvas, NinePatchTexture tex, int x, int y) {
- if (mBufferNames == null) {
- prepareBuffers(canvas);
- }
- canvas.drawMesh(tex, x, y, mBufferNames[0], mBufferNames[1],
- mBufferNames[2], mIdxCount);
- }
-
- public void recycle(GLCanvas canvas) {
- if (mBufferNames != null) {
- canvas.deleteBuffer(mBufferNames[0]);
- canvas.deleteBuffer(mBufferNames[1]);
- canvas.deleteBuffer(mBufferNames[2]);
- mBufferNames = null;
- }
- }
-}
diff --git a/src/com/android/gallery3d/ui/PhotoFallbackEffect.java b/src/com/android/gallery3d/ui/PhotoFallbackEffect.java
index 3ca09ab96..4603285a4 100644
--- a/src/com/android/gallery3d/ui/PhotoFallbackEffect.java
+++ b/src/com/android/gallery3d/ui/PhotoFallbackEffect.java
@@ -23,6 +23,8 @@ import android.view.animation.Interpolator;
import com.android.gallery3d.anim.Animation;
import com.android.gallery3d.data.Path;
+import com.android.gallery3d.glrenderer.GLCanvas;
+import com.android.gallery3d.glrenderer.RawTexture;
import com.android.gallery3d.ui.AlbumSlotRenderer.SlotFilter;
import java.util.ArrayList;
diff --git a/src/com/android/gallery3d/ui/PhotoView.java b/src/com/android/gallery3d/ui/PhotoView.java
index 6dcae4ca4..40e01ab07 100644
--- a/src/com/android/gallery3d/ui/PhotoView.java
+++ b/src/com/android/gallery3d/ui/PhotoView.java
@@ -35,6 +35,11 @@ import com.android.gallery3d.common.Utils;
import com.android.gallery3d.data.MediaItem;
import com.android.gallery3d.data.MediaObject;
import com.android.gallery3d.data.Path;
+import com.android.gallery3d.glrenderer.GLCanvas;
+import com.android.gallery3d.glrenderer.RawTexture;
+import com.android.gallery3d.glrenderer.ResourceTexture;
+import com.android.gallery3d.glrenderer.StringTexture;
+import com.android.gallery3d.glrenderer.Texture;
import com.android.gallery3d.util.GalleryUtils;
import com.android.gallery3d.util.RangeArray;
@@ -52,7 +57,7 @@ public class PhotoView extends GLView {
public int height;
}
- public interface Model extends TileImageView.Model {
+ public interface Model extends TileImageView.TileSource {
public int getCurrentIndex();
public void moveTo(int index);
@@ -174,8 +179,9 @@ public class PhotoView extends GLView {
public static final int SCREEN_NAIL_MAX = 3;
// These are constants for the delete gesture.
- private static final int SWIPE_ESCAPE_VELOCITY = 2500; // dp/sec
- private static final int MAX_DISMISS_VELOCITY = 4000; // dp/sec
+ private static final int SWIPE_ESCAPE_VELOCITY = 500; // dp/sec
+ private static final int MAX_DISMISS_VELOCITY = 2500; // dp/sec
+ private static final int SWIPE_ESCAPE_DISTANCE = 150; // dp
// The picture entries, the valid index is from -SCREEN_NAIL_MAX to
// SCREEN_NAIL_MAX.
@@ -1070,19 +1076,19 @@ public class PhotoView extends GLView {
}
@Override
- public boolean onFling(float velocityX, float velocityY) {
+ public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if (mIgnoreSwipingGesture) return true;
if (mModeChanged) return true;
if (swipeImages(velocityX, velocityY)) {
mIgnoreUpEvent = true;
} else {
- flingImages(velocityX, velocityY);
+ flingImages(velocityX, velocityY, Math.abs(e2.getY() - e1.getY()));
}
mHadFling = true;
return true;
}
- private boolean flingImages(float velocityX, float velocityY) {
+ private boolean flingImages(float velocityX, float velocityY, float dY) {
int vx = (int) (velocityX + 0.5f);
int vy = (int) (velocityY + 0.5f);
if (!mFilmMode) {
@@ -1099,11 +1105,13 @@ public class PhotoView extends GLView {
}
int maxVelocity = GalleryUtils.dpToPixel(MAX_DISMISS_VELOCITY);
int escapeVelocity = GalleryUtils.dpToPixel(SWIPE_ESCAPE_VELOCITY);
+ int escapeDistance = GalleryUtils.dpToPixel(SWIPE_ESCAPE_DISTANCE);
int centerY = mPositionController.getPosition(mTouchBoxIndex)
.centerY();
boolean fastEnough = (Math.abs(vy) > escapeVelocity)
&& (Math.abs(vy) > Math.abs(vx))
- && ((vy > 0) == (centerY > getHeight() / 2));
+ && ((vy > 0) == (centerY > getHeight() / 2))
+ && dY >= escapeDistance;
if (fastEnough) {
vy = Math.min(vy, maxVelocity);
int duration = mPositionController.flingFilmY(mTouchBoxIndex, vy);
@@ -1237,7 +1245,10 @@ public class PhotoView extends GLView {
if (mFilmMode) {
int xi = (int) (x + 0.5f);
int yi = (int) (y + 0.5f);
- mTouchBoxIndex = mPositionController.hitTest(xi, yi);
+ // We only care about being within the x bounds, necessary for
+ // handling very wide images which are otherwise very hard to fling
+ mTouchBoxIndex = mPositionController.hitTest(xi, getHeight() / 2);
+
if (mTouchBoxIndex < mPrevBound || mTouchBoxIndex > mNextBound) {
mTouchBoxIndex = Integer.MAX_VALUE;
} else {
diff --git a/src/com/android/gallery3d/ui/PreparePageFadeoutTexture.java b/src/com/android/gallery3d/ui/PreparePageFadeoutTexture.java
index 36e7f4b82..f52aa5ff2 100644
--- a/src/com/android/gallery3d/ui/PreparePageFadeoutTexture.java
+++ b/src/com/android/gallery3d/ui/PreparePageFadeoutTexture.java
@@ -3,6 +3,8 @@ package com.android.gallery3d.ui;
import android.os.ConditionVariable;
import com.android.gallery3d.app.AbstractGalleryActivity;
+import com.android.gallery3d.glrenderer.GLCanvas;
+import com.android.gallery3d.glrenderer.RawTexture;
import com.android.gallery3d.ui.GLRoot.OnGLIdleListener;
public class PreparePageFadeoutTexture implements OnGLIdleListener {
diff --git a/src/com/android/gallery3d/ui/ProgressSpinner.java b/src/com/android/gallery3d/ui/ProgressSpinner.java
index 4f9381c76..1b31af278 100644
--- a/src/com/android/gallery3d/ui/ProgressSpinner.java
+++ b/src/com/android/gallery3d/ui/ProgressSpinner.java
@@ -19,6 +19,8 @@ package com.android.gallery3d.ui;
import android.content.Context;
import com.android.gallery3d.R;
+import com.android.gallery3d.glrenderer.GLCanvas;
+import com.android.gallery3d.glrenderer.ResourceTexture;
public class ProgressSpinner {
private static float ROTATE_SPEED_OUTER = 1080f / 3500f;
diff --git a/src/com/android/gallery3d/ui/RawTexture.java b/src/com/android/gallery3d/ui/RawTexture.java
deleted file mode 100644
index 4c0d9d365..000000000
--- a/src/com/android/gallery3d/ui/RawTexture.java
+++ /dev/null
@@ -1,91 +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.gallery3d.ui;
-
-import javax.microedition.khronos.opengles.GL11;
-import javax.microedition.khronos.opengles.GL11Ext;
-
-public class RawTexture extends BasicTexture {
- private static final String TAG = "RawTexture";
-
- private final static int[] sTextureId = new int[1];
- private final static float[] sCropRect = new float[4];
-
- private final boolean mOpaque;
-
- public RawTexture(int width, int height, boolean opaque) {
- mOpaque = opaque;
- setSize(width, height);
- }
-
- @Override
- public boolean isOpaque() {
- return mOpaque;
- }
-
- protected void prepare(GLCanvas canvas) {
- GL11 gl = canvas.getGLInstance();
-
- // Define a vertically flipped crop rectangle for
- // OES_draw_texture.
- // The four values in sCropRect are: left, bottom, width, and
- // height. Negative value of width or height means flip.
- sCropRect[0] = 0;
- sCropRect[1] = mHeight;
- sCropRect[2] = mWidth;
- sCropRect[3] = -mHeight;
-
- // Upload the bitmap to a new texture.
- GLId.glGenTextures(1, sTextureId, 0);
- gl.glBindTexture(GL11.GL_TEXTURE_2D, sTextureId[0]);
- gl.glTexParameterfv(GL11.GL_TEXTURE_2D,
- GL11Ext.GL_TEXTURE_CROP_RECT_OES, sCropRect, 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);
-
- gl.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA,
- getTextureWidth(), getTextureHeight(),
- 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, null);
-
- mId = sTextureId[0];
- mState = STATE_LOADED;
- setAssociatedCanvas(canvas);
- }
-
- @Override
- protected boolean onBind(GLCanvas canvas) {
- if (isLoaded()) return true;
- Log.w(TAG, "lost the content due to context change");
- return false;
- }
-
- @Override
- public void yield() {
- // we cannot free the texture because we have no backup.
- }
-
- @Override
- protected int getTarget() {
- return GL11.GL_TEXTURE_2D;
- }
-}
diff --git a/src/com/android/gallery3d/ui/ResourceTexture.java b/src/com/android/gallery3d/ui/ResourceTexture.java
deleted file mode 100644
index 1fa9d7014..000000000
--- a/src/com/android/gallery3d/ui/ResourceTexture.java
+++ /dev/null
@@ -1,52 +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.gallery3d.ui;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-
-import com.android.gallery3d.common.Utils;
-
-// ResourceTexture is a texture whose Bitmap is decoded from a resource.
-// By default ResourceTexture is not opaque.
-public class ResourceTexture extends UploadedTexture {
-
- protected final Context mContext;
- protected final int mResId;
-
- public ResourceTexture(Context context, int resId) {
- mContext = Utils.checkNotNull(context);
- mResId = resId;
- setOpaque(false);
- }
-
- @Override
- protected Bitmap onGetBitmap() {
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inPreferredConfig = Bitmap.Config.ARGB_8888;
- return BitmapFactory.decodeResource(
- mContext.getResources(), mResId, options);
- }
-
- @Override
- protected void onFreeBitmap(Bitmap bitmap) {
- if (!inFinalizer()) {
- bitmap.recycle();
- }
- }
-}
diff --git a/src/com/android/gallery3d/ui/ScreenNail.java b/src/com/android/gallery3d/ui/ScreenNail.java
index 0a16ab850..965bf0b54 100644
--- a/src/com/android/gallery3d/ui/ScreenNail.java
+++ b/src/com/android/gallery3d/ui/ScreenNail.java
@@ -17,6 +17,8 @@ package com.android.gallery3d.ui;
import android.graphics.RectF;
+import com.android.gallery3d.glrenderer.GLCanvas;
+
public interface ScreenNail {
public int getWidth();
public int getHeight();
diff --git a/src/com/android/gallery3d/ui/ScrollBarView.java b/src/com/android/gallery3d/ui/ScrollBarView.java
index 82d4800cc..34fbcef7a 100644
--- a/src/com/android/gallery3d/ui/ScrollBarView.java
+++ b/src/com/android/gallery3d/ui/ScrollBarView.java
@@ -20,6 +20,9 @@ import android.content.Context;
import android.graphics.Rect;
import android.util.TypedValue;
+import com.android.gallery3d.glrenderer.GLCanvas;
+import com.android.gallery3d.glrenderer.NinePatchTexture;
+
public class ScrollBarView extends GLView {
@SuppressWarnings("unused")
private static final String TAG = "ScrollBarView";
diff --git a/src/com/android/gallery3d/ui/SlideshowView.java b/src/com/android/gallery3d/ui/SlideshowView.java
index bb36c47e9..b215c6661 100644
--- a/src/com/android/gallery3d/ui/SlideshowView.java
+++ b/src/com/android/gallery3d/ui/SlideshowView.java
@@ -21,11 +21,12 @@ import android.graphics.PointF;
import com.android.gallery3d.anim.CanvasAnimation;
import com.android.gallery3d.anim.FloatAnimation;
+import com.android.gallery3d.glrenderer.BitmapTexture;
+import com.android.gallery3d.glrenderer.GLCanvas;
+import com.android.gallery3d.glrenderer.GLCanvas.Blending;
import java.util.Random;
-import javax.microedition.khronos.opengles.GL11;
-
public class SlideshowView extends GLView {
@SuppressWarnings("unused")
private static final String TAG = "SlideshowView";
@@ -93,8 +94,8 @@ public class SlideshowView extends GLView {
protected void render(GLCanvas canvas) {
long animTime = AnimationTime.get();
boolean requestRender = mTransitionAnimation.calculate(animTime);
- GL11 gl = canvas.getGLInstance();
- gl.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE);
+ canvas.save(GLCanvas.SAVE_FLAG_BLEND);
+ canvas.setBlending(Blending.Additive);
float alpha = mPrevTexture == null ? 1f : mTransitionAnimation.get();
if (mPrevTexture != null && alpha != 1f) {
@@ -118,7 +119,7 @@ public class SlideshowView extends GLView {
canvas.restore();
}
if (requestRender) invalidate();
- gl.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ canvas.restore();
}
private class SlideshowAnimation extends CanvasAnimation {
diff --git a/src/com/android/gallery3d/ui/SlotView.java b/src/com/android/gallery3d/ui/SlotView.java
index 15a583e5c..bd0ffdc15 100644
--- a/src/com/android/gallery3d/ui/SlotView.java
+++ b/src/com/android/gallery3d/ui/SlotView.java
@@ -25,6 +25,7 @@ import android.view.animation.DecelerateInterpolator;
import com.android.gallery3d.anim.Animation;
import com.android.gallery3d.app.AbstractGalleryActivity;
import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.glrenderer.GLCanvas;
public class SlotView extends GLView {
@SuppressWarnings("unused")
diff --git a/src/com/android/gallery3d/ui/StringTexture.java b/src/com/android/gallery3d/ui/StringTexture.java
deleted file mode 100644
index 97995c8a5..000000000
--- a/src/com/android/gallery3d/ui/StringTexture.java
+++ /dev/null
@@ -1,88 +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.gallery3d.ui;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint.FontMetricsInt;
-import android.graphics.Typeface;
-import android.text.TextPaint;
-import android.text.TextUtils;
-import android.util.FloatMath;
-
-// StringTexture is a texture shows the content of a specified String.
-//
-// To create a StringTexture, use the newInstance() method and specify
-// the String, the font size, and the color.
-class StringTexture extends CanvasTexture {
- private final String mText;
- private final TextPaint mPaint;
- private final FontMetricsInt mMetrics;
-
- private StringTexture(String text, TextPaint paint,
- FontMetricsInt metrics, int width, int height) {
- super(width, height);
- mText = text;
- mPaint = paint;
- mMetrics = metrics;
- }
-
- public static TextPaint getDefaultPaint(float textSize, int color) {
- TextPaint paint = new TextPaint();
- paint.setTextSize(textSize);
- paint.setAntiAlias(true);
- paint.setColor(color);
- paint.setShadowLayer(2f, 0f, 0f, Color.BLACK);
- return paint;
- }
-
- public static StringTexture newInstance(
- String text, float textSize, int color) {
- return newInstance(text, getDefaultPaint(textSize, color));
- }
-
- public static StringTexture newInstance(
- String text, float textSize, int color,
- float lengthLimit, boolean isBold) {
- TextPaint paint = getDefaultPaint(textSize, color);
- if (isBold) {
- paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
- }
- if (lengthLimit > 0) {
- text = TextUtils.ellipsize(
- text, paint, lengthLimit, TextUtils.TruncateAt.END).toString();
- }
- return newInstance(text, paint);
- }
-
- private static StringTexture newInstance(String text, TextPaint paint) {
- FontMetricsInt metrics = paint.getFontMetricsInt();
- int width = (int) FloatMath.ceil(paint.measureText(text));
- int height = metrics.bottom - metrics.top;
- // The texture size needs to be at least 1x1.
- if (width <= 0) width = 1;
- if (height <= 0) height = 1;
- return new StringTexture(text, paint, metrics, width, height);
- }
-
- @Override
- protected void onDraw(Canvas canvas, Bitmap backing) {
- canvas.translate(0, -mMetrics.ascent);
- canvas.drawText(mText, 0, 0, mPaint);
- }
-}
diff --git a/src/com/android/gallery3d/ui/SurfaceTextureScreenNail.java b/src/com/android/gallery3d/ui/SurfaceTextureScreenNail.java
index ceed71abe..ef8959c9d 100644
--- a/src/com/android/gallery3d/ui/SurfaceTextureScreenNail.java
+++ b/src/com/android/gallery3d/ui/SurfaceTextureScreenNail.java
@@ -21,6 +21,8 @@ import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import com.android.gallery3d.common.ApiHelper;
+import com.android.gallery3d.glrenderer.ExtTexture;
+import com.android.gallery3d.glrenderer.GLCanvas;
@TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
public abstract class SurfaceTextureScreenNail implements ScreenNail,
diff --git a/src/com/android/gallery3d/ui/Texture.java b/src/com/android/gallery3d/ui/Texture.java
deleted file mode 100644
index 2c426f994..000000000
--- a/src/com/android/gallery3d/ui/Texture.java
+++ /dev/null
@@ -1,43 +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.gallery3d.ui;
-
-// Texture is a rectangular image which can be drawn on GLCanvas.
-// The isOpaque() function gives a hint about whether the texture is opaque,
-// so the drawing can be done faster.
-//
-// This is the current texture hierarchy:
-//
-// Texture
-// -- ColorTexture
-// -- FadeInTexture
-// -- BasicTexture
-// -- UploadedTexture
-// -- BitmapTexture
-// -- Tile
-// -- ResourceTexture
-// -- NinePatchTexture
-// -- CanvasTexture
-// -- StringTexture
-//
-public interface Texture {
- public int getWidth();
- public int getHeight();
- public void draw(GLCanvas canvas, int x, int y);
- public void draw(GLCanvas canvas, int x, int y, int w, int h);
- public boolean isOpaque();
-}
diff --git a/src/com/android/gallery3d/ui/TextureUploader.java b/src/com/android/gallery3d/ui/TextureUploader.java
deleted file mode 100644
index 9a8c47fc6..000000000
--- a/src/com/android/gallery3d/ui/TextureUploader.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2012 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.gallery3d.ui;
-
-import com.android.gallery3d.ui.GLRoot.OnGLIdleListener;
-
-import java.util.ArrayDeque;
-
-public class TextureUploader implements OnGLIdleListener {
- private static final int INIT_CAPACITY = 64;
- private static final int QUOTA_PER_FRAME = 1;
-
- private final ArrayDeque<UploadedTexture> mFgTextures =
- new ArrayDeque<UploadedTexture>(INIT_CAPACITY);
- private final ArrayDeque<UploadedTexture> mBgTextures =
- new ArrayDeque<UploadedTexture>(INIT_CAPACITY);
- private final GLRoot mGLRoot;
- private volatile boolean mIsQueued = false;
-
- public TextureUploader(GLRoot root) {
- mGLRoot = root;
- }
-
- public synchronized void clear() {
- while (!mFgTextures.isEmpty()) {
- mFgTextures.pop().setIsUploading(false);
- }
- while (!mBgTextures.isEmpty()) {
- mBgTextures.pop().setIsUploading(false);
- }
- }
-
- // caller should hold synchronized on "this"
- private void queueSelfIfNeed() {
- if (mIsQueued) return;
- mIsQueued = true;
- mGLRoot.addOnGLIdleListener(this);
- }
-
- public synchronized void addBgTexture(UploadedTexture t) {
- if (t.isContentValid()) return;
- mBgTextures.addLast(t);
- t.setIsUploading(true);
- queueSelfIfNeed();
- }
-
- public synchronized void addFgTexture(UploadedTexture t) {
- if (t.isContentValid()) return;
- mFgTextures.addLast(t);
- t.setIsUploading(true);
- queueSelfIfNeed();
- }
-
- private int upload(GLCanvas canvas, ArrayDeque<UploadedTexture> deque,
- int uploadQuota, boolean isBackground) {
- while (uploadQuota > 0) {
- UploadedTexture t;
- synchronized (this) {
- if (deque.isEmpty()) break;
- t = deque.removeFirst();
- t.setIsUploading(false);
- if (t.isContentValid()) continue;
-
- // this has to be protected by the synchronized block
- // to prevent the inner bitmap get recycled
- t.updateContent(canvas);
- }
-
- // It will took some more time for a texture to be drawn for
- // the first time.
- // Thus, when scrolling, if a new column appears on screen,
- // it may cause a UI jank even these textures are uploaded.
- if (isBackground) t.draw(canvas, 0, 0);
- --uploadQuota;
- }
- return uploadQuota;
- }
-
- @Override
- public boolean onGLIdle(GLCanvas canvas, boolean renderRequested) {
- int uploadQuota = QUOTA_PER_FRAME;
- uploadQuota = upload(canvas, mFgTextures, uploadQuota, false);
- if (uploadQuota < QUOTA_PER_FRAME) mGLRoot.requestRender();
- upload(canvas, mBgTextures, uploadQuota, true);
- synchronized (this) {
- mIsQueued = !mFgTextures.isEmpty() || !mBgTextures.isEmpty();
- return mIsQueued;
- }
- }
-}
diff --git a/src/com/android/gallery3d/ui/TileImageView.java b/src/com/android/gallery3d/ui/TileImageView.java
index 8f26981fe..f1c31e49d 100644
--- a/src/com/android/gallery3d/ui/TileImageView.java
+++ b/src/com/android/gallery3d/ui/TileImageView.java
@@ -16,20 +16,24 @@
package com.android.gallery3d.ui;
+import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
+import android.support.v4.util.LongSparseArray;
+import android.util.DisplayMetrics;
import android.util.FloatMath;
+import android.view.WindowManager;
import com.android.gallery3d.app.GalleryContext;
import com.android.gallery3d.common.ApiHelper;
-import com.android.gallery3d.common.LongSparseArray;
import com.android.gallery3d.common.Utils;
import com.android.gallery3d.data.BitmapPool;
import com.android.gallery3d.data.DecodeUtils;
+import com.android.gallery3d.glrenderer.GLCanvas;
+import com.android.gallery3d.glrenderer.UploadedTexture;
import com.android.gallery3d.util.Future;
-import com.android.gallery3d.util.GalleryUtils;
import com.android.gallery3d.util.ThreadPool;
import com.android.gallery3d.util.ThreadPool.CancelListener;
import com.android.gallery3d.util.ThreadPool.JobContext;
@@ -41,14 +45,11 @@ public class TileImageView extends GLView {
@SuppressWarnings("unused")
private static final String TAG = "TileImageView";
-
- // TILE_SIZE must be 2^N - 2. We put one pixel border in each side of the
- // texture to avoid seams between tiles.
- private static int TILE_SIZE;
- private static final int TILE_BORDER = 1;
- private static int BITMAP_SIZE;
private static final int UPLOAD_LIMIT = 1;
+ // TILE_SIZE must be 2^N
+ private static int sTileSize;
+
private static BitmapPool sTilePool;
/*
@@ -76,7 +77,7 @@ public class TileImageView extends GLView {
private static final int STATE_RECYCLING = 0x20;
private static final int STATE_RECYCLED = 0x40;
- private Model mModel;
+ private TileSource mModel;
private ScreenNail mScreenNail;
protected int mLevelCount; // cache the value of mScaledBitmaps.length
@@ -125,7 +126,7 @@ public class TileImageView extends GLView {
private final ThreadPool mThreadPool;
private boolean mBackgroundTileUploaded;
- public static interface Model {
+ public static interface TileSource {
public int getLevelCount();
public ScreenNail getScreenNail();
public int getImageWidth();
@@ -133,8 +134,7 @@ public class TileImageView extends GLView {
// The tile returned by this method can be specified this way: Assuming
// the image size is (width, height), first take the intersection of (0,
- // 0) - (width, height) and (x, y) - (x + tileSize, y + tileSize). Then
- // extend this intersection region by borderSize pixels on each side. If
+ // 0) - (width, height) and (x, y) - (x + tileSize, y + tileSize). If
// in extending the region, we found some part of the region are outside
// the image, those pixels are filled with black.
//
@@ -144,27 +144,34 @@ public class TileImageView extends GLView {
//
// The method would be called in another thread.
public Bitmap getTile(int level, int x, int y, int tileSize,
- int borderSize, BitmapPool pool);
+ BitmapPool pool);
+ }
+
+ public static boolean isHighResolution(Context context) {
+ DisplayMetrics metrics = new DisplayMetrics();
+ WindowManager wm = (WindowManager)
+ context.getSystemService(Context.WINDOW_SERVICE);
+ wm.getDefaultDisplay().getMetrics(metrics);
+ return metrics.heightPixels > 2048 || metrics.widthPixels > 2048;
}
public TileImageView(GalleryContext context) {
mThreadPool = context.getThreadPool();
mTileDecoder = mThreadPool.submit(new TileDecoder());
- if (TILE_SIZE == 0) {
- if (GalleryUtils.isHighResolution(context.getAndroidContext())) {
- TILE_SIZE = 510 ;
+ if (sTileSize == 0) {
+ if (isHighResolution(context.getAndroidContext())) {
+ sTileSize = 512 ;
} else {
- TILE_SIZE = 254;
+ sTileSize = 256;
}
- BITMAP_SIZE = TILE_SIZE + TILE_BORDER * 2;
sTilePool =
ApiHelper.HAS_REUSING_BITMAP_IN_BITMAP_REGION_DECODER
- ? new BitmapPool(BITMAP_SIZE, BITMAP_SIZE, 128)
+ ? new BitmapPool(sTileSize, sTileSize, 128)
: null;
}
}
- public void setModel(Model model) {
+ public void setModel(TileSource model) {
mModel = model;
if (model != null) notifyModelInvalidated();
}
@@ -266,7 +273,7 @@ public class TileImageView extends GLView {
}
for (int i = fromLevel; i < endLevel; ++i) {
- int size = TILE_SIZE << i;
+ int size = sTileSize << i;
Rect r = range[i - fromLevel];
for (int y = r.top, bottom = r.bottom; y < bottom; y += size) {
for (int x = r.left, right = r.right; x < right; x += size) {
@@ -320,7 +327,7 @@ public class TileImageView extends GLView {
int bottom = (int) FloatMath.ceil(top + height / scale);
// align the rectangle to tile boundary
- int size = TILE_SIZE << level;
+ int size = sTileSize << level;
left = Math.max(0, size * (left / size));
top = Math.max(0, size * (top / size));
right = Math.min(mImageWidth, right);
@@ -431,7 +438,7 @@ public class TileImageView extends GLView {
mScreenNail.noDraw();
}
- int size = (TILE_SIZE << level);
+ int size = (sTileSize << level);
float length = size * mScale;
Rect r = mTileRange;
@@ -594,7 +601,7 @@ public class TileImageView extends GLView {
RectF source = mSourceRect;
RectF target = mTargetRect;
target.set(x, y, x + length, y + length);
- source.set(0, 0, TILE_SIZE, TILE_SIZE);
+ source.set(0, 0, sTileSize, sTileSize);
Tile tile = getTile(tx, ty, level);
if (tile != null) {
@@ -614,7 +621,7 @@ public class TileImageView extends GLView {
if (drawTile(tile, canvas, source, target)) return;
}
if (mScreenNail != null) {
- int size = TILE_SIZE << level;
+ int size = sTileSize << level;
float scaleX = (float) mScreenNail.getWidth() / mImageWidth;
float scaleY = (float) mScreenNail.getHeight() / mImageHeight;
source.set(tx * scaleX, ty * scaleY, (tx + size) * scaleX,
@@ -627,8 +634,6 @@ public class TileImageView extends GLView {
Tile tile, GLCanvas canvas, RectF source, RectF target) {
while (true) {
if (tile.isContentValid()) {
- // offset source rectangle for the texture border.
- source.offset(TILE_BORDER, TILE_BORDER);
canvas.drawTexture(tile, source, target);
return true;
}
@@ -640,15 +645,15 @@ public class TileImageView extends GLView {
source.left /= 2f;
source.right /= 2f;
} else {
- source.left = (TILE_SIZE + source.left) / 2f;
- source.right = (TILE_SIZE + source.right) / 2f;
+ source.left = (sTileSize + source.left) / 2f;
+ source.right = (sTileSize + source.right) / 2f;
}
if (tile.mY == parent.mY) {
source.top /= 2f;
source.bottom /= 2f;
} else {
- source.top = (TILE_SIZE + source.top) / 2f;
- source.bottom = (TILE_SIZE + source.bottom) / 2f;
+ source.top = (sTileSize + source.top) / 2f;
+ source.bottom = (sTileSize + source.bottom) / 2f;
}
tile = parent;
}
@@ -678,7 +683,7 @@ public class TileImageView extends GLView {
// by (1 << mTilelevel) from a region in the original image.
try {
mDecodedTile = DecodeUtils.ensureGLCompatibleBitmap(mModel.getTile(
- mTileLevel, mX, mY, TILE_SIZE, TILE_BORDER, sTilePool));
+ mTileLevel, mX, mY, sTileSize, sTilePool));
} catch (Throwable t) {
Log.w(TAG, "fail to decode tile", t);
}
@@ -691,9 +696,9 @@ public class TileImageView extends GLView {
// We need to override the width and height, so that we won't
// draw beyond the boundaries.
- int rightEdge = ((mImageWidth - mX) >> mTileLevel) + TILE_BORDER;
- int bottomEdge = ((mImageHeight - mY) >> mTileLevel) + TILE_BORDER;
- setSize(Math.min(BITMAP_SIZE, rightEdge), Math.min(BITMAP_SIZE, bottomEdge));
+ int rightEdge = ((mImageWidth - mX) >> mTileLevel);
+ int bottomEdge = ((mImageHeight - mY) >> mTileLevel);
+ setSize(Math.min(sTileSize, rightEdge), Math.min(sTileSize, bottomEdge));
Bitmap bitmap = mDecodedTile;
mDecodedTile = null;
@@ -707,12 +712,12 @@ public class TileImageView extends GLView {
// boundary).
@Override
public int getTextureWidth() {
- return TILE_SIZE + TILE_BORDER * 2;
+ return sTileSize;
}
@Override
public int getTextureHeight() {
- return TILE_SIZE + TILE_BORDER * 2;
+ return sTileSize;
}
public void update(int x, int y, int level) {
@@ -724,7 +729,7 @@ public class TileImageView extends GLView {
public Tile getParentTile() {
if (mTileLevel + 1 == mLevelCount) return null;
- int size = TILE_SIZE << (mTileLevel + 1);
+ int size = sTileSize << (mTileLevel + 1);
int x = size * (mX / size);
int y = size * (mY / size);
return getTile(x, y, mTileLevel + 1);
@@ -733,7 +738,7 @@ public class TileImageView extends GLView {
@Override
public String toString() {
return String.format("tile(%s, %s, %s / %s)",
- mX / TILE_SIZE, mY / TILE_SIZE, mLevel, mLevelCount);
+ mX / sTileSize, mY / sTileSize, mLevel, mLevelCount);
}
}
diff --git a/src/com/android/gallery3d/ui/TileImageViewAdapter.java b/src/com/android/gallery3d/ui/TileImageViewAdapter.java
index 45e2ce218..0d20b0757 100644
--- a/src/com/android/gallery3d/ui/TileImageViewAdapter.java
+++ b/src/com/android/gallery3d/ui/TileImageViewAdapter.java
@@ -28,7 +28,7 @@ import com.android.gallery3d.common.ApiHelper;
import com.android.gallery3d.common.Utils;
import com.android.gallery3d.data.BitmapPool;
-public class TileImageViewAdapter implements TileImageView.Model {
+public class TileImageViewAdapter implements TileImageView.TileSource {
private static final String TAG = "TileImageViewAdapter";
protected ScreenNail mScreenNail;
protected boolean mOwnScreenNail;
@@ -84,16 +84,14 @@ public class TileImageViewAdapter implements TileImageView.Model {
// (44, 44, 256, 256) from the original photo and down sample it to 106.
@TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
@Override
- public Bitmap getTile(int level, int x, int y, int tileSize,
- int borderSize, BitmapPool pool) {
+ public Bitmap getTile(int level, int x, int y, int tileSize, BitmapPool pool) {
if (!ApiHelper.HAS_REUSING_BITMAP_IN_BITMAP_REGION_DECODER) {
- return getTileWithoutReusingBitmap(level, x, y, tileSize, borderSize);
+ return getTileWithoutReusingBitmap(level, x, y, tileSize);
}
- int b = borderSize << level;
int t = tileSize << level;
- Rect wantRegion = new Rect(x - b, y - b, x + t + b, y + t + b);
+ Rect wantRegion = new Rect(x, y, x + t, y + t);
boolean needClear;
BitmapRegionDecoder regionDecoder = null;
@@ -112,8 +110,7 @@ public class TileImageViewAdapter implements TileImageView.Model {
if (bitmap != null) {
if (needClear) bitmap.eraseColor(0);
} else {
- int s = tileSize + 2 * borderSize;
- bitmap = Bitmap.createBitmap(s, s, Config.ARGB_8888);
+ bitmap = Bitmap.createBitmap(tileSize, tileSize, Config.ARGB_8888);
}
BitmapFactory.Options options = new BitmapFactory.Options();
@@ -141,10 +138,9 @@ public class TileImageViewAdapter implements TileImageView.Model {
}
private Bitmap getTileWithoutReusingBitmap(
- int level, int x, int y, int tileSize, int borderSize) {
- int b = borderSize << level;
+ int level, int x, int y, int tileSize) {
int t = tileSize << level;
- Rect wantRegion = new Rect(x - b, y - b, x + t + b, y + t + b);
+ Rect wantRegion = new Rect(x, y, x + t, y + t);
BitmapRegionDecoder regionDecoder;
Rect overlapRegion;
@@ -173,8 +169,7 @@ public class TileImageViewAdapter implements TileImageView.Model {
if (wantRegion.equals(overlapRegion)) return bitmap;
- int s = tileSize + 2 * borderSize;
- Bitmap result = Bitmap.createBitmap(s, s, Config.ARGB_8888);
+ Bitmap result = Bitmap.createBitmap(tileSize, tileSize, Config.ARGB_8888);
Canvas canvas = new Canvas(result);
canvas.drawBitmap(bitmap,
(overlapRegion.left - wantRegion.left) >> level,
diff --git a/src/com/android/gallery3d/ui/TiledScreenNail.java b/src/com/android/gallery3d/ui/TiledScreenNail.java
index 74665f584..ab24f5b6c 100644
--- a/src/com/android/gallery3d/ui/TiledScreenNail.java
+++ b/src/com/android/gallery3d/ui/TiledScreenNail.java
@@ -22,6 +22,8 @@ import android.graphics.RectF;
import com.android.gallery3d.common.Utils;
import com.android.gallery3d.data.BitmapPool;
import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.glrenderer.GLCanvas;
+import com.android.gallery3d.glrenderer.TiledTexture;
// This is a ScreenNail wraps a Bitmap. There are some extra functions:
//
diff --git a/src/com/android/gallery3d/ui/TiledTexture.java b/src/com/android/gallery3d/ui/TiledTexture.java
deleted file mode 100644
index 02bde9f4f..000000000
--- a/src/com/android/gallery3d/ui/TiledTexture.java
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright (C) 2012 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.gallery3d.ui;
-
-import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.PorterDuffXfermode;
-import android.graphics.RectF;
-import android.os.SystemClock;
-
-import com.android.gallery3d.ui.GLRoot.OnGLIdleListener;
-
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-
-// This class is similar to BitmapTexture, except the bitmap is
-// split into tiles. By doing so, we may increase the time required to
-// upload the whole bitmap but we reduce the time of uploading each tile
-// so it make the animation more smooth and prevents jank.
-public class TiledTexture implements Texture {
- private static final int CONTENT_SIZE = 254;
- private static final int BORDER_SIZE = 1;
- private static final int TILE_SIZE = CONTENT_SIZE + 2 * BORDER_SIZE;
- private static final int INIT_CAPACITY = 8;
-
- // We are targeting at 60fps, so we have 16ms for each frame.
- // In this 16ms, we use about 4~8 ms to upload tiles.
- private static final long UPLOAD_TILE_LIMIT = 4; // ms
-
- private static Tile sFreeTileHead = null;
- private static final Object sFreeTileLock = new Object();
-
- private static Bitmap sUploadBitmap;
- private static Canvas sCanvas;
- private static Paint sBitmapPaint;
- private static Paint sPaint;
-
- private int mUploadIndex = 0;
-
- private final Tile[] mTiles; // Can be modified in different threads.
- // Should be protected by "synchronized."
- private final int mWidth;
- private final int mHeight;
- private final RectF mSrcRect = new RectF();
- private final RectF mDestRect = new RectF();
-
- public static class Uploader implements OnGLIdleListener {
- private final ArrayDeque<TiledTexture> mTextures =
- new ArrayDeque<TiledTexture>(INIT_CAPACITY);
-
- private final GLRoot mGlRoot;
- private boolean mIsQueued = false;
-
- public Uploader(GLRoot glRoot) {
- mGlRoot = glRoot;
- }
-
- public synchronized void clear() {
- mTextures.clear();
- }
-
- public synchronized void addTexture(TiledTexture t) {
- if (t.isReady()) return;
- mTextures.addLast(t);
-
- if (mIsQueued) return;
- mIsQueued = true;
- mGlRoot.addOnGLIdleListener(this);
- }
-
- @Override
- public boolean onGLIdle(GLCanvas canvas, boolean renderRequested) {
- ArrayDeque<TiledTexture> deque = mTextures;
- synchronized (this) {
- long now = SystemClock.uptimeMillis();
- long dueTime = now + UPLOAD_TILE_LIMIT;
- while (now < dueTime && !deque.isEmpty()) {
- TiledTexture t = deque.peekFirst();
- if (t.uploadNextTile(canvas)) {
- deque.removeFirst();
- mGlRoot.requestRender();
- }
- now = SystemClock.uptimeMillis();
- }
- mIsQueued = !mTextures.isEmpty();
-
- // return true to keep this listener in the queue
- return mIsQueued;
- }
- }
- }
-
- private static class Tile extends UploadedTexture {
- public int offsetX;
- public int offsetY;
- public Bitmap bitmap;
- public Tile nextFreeTile;
- public int contentWidth;
- public int contentHeight;
-
- @Override
- public void setSize(int width, int height) {
- contentWidth = width;
- contentHeight = height;
- mWidth = width + 2 * BORDER_SIZE;
- mHeight = height + 2 * BORDER_SIZE;
- mTextureWidth = TILE_SIZE;
- mTextureHeight = TILE_SIZE;
- }
-
- @Override
- protected Bitmap onGetBitmap() {
- int x = BORDER_SIZE - offsetX;
- int y = BORDER_SIZE - offsetY;
- int r = bitmap.getWidth() + x;
- int b = bitmap.getHeight() + y;
- sCanvas.drawBitmap(bitmap, x, y, sBitmapPaint);
- bitmap = null;
-
- // draw borders if need
- if (x > 0) sCanvas.drawLine(x - 1, 0, x - 1, TILE_SIZE, sPaint);
- if (y > 0) sCanvas.drawLine(0, y - 1, TILE_SIZE, y - 1, sPaint);
- if (r < CONTENT_SIZE) sCanvas.drawLine(r, 0, r, TILE_SIZE, sPaint);
- if (b < CONTENT_SIZE) sCanvas.drawLine(0, b, TILE_SIZE, b, sPaint);
-
- return sUploadBitmap;
- }
-
- @Override
- protected void onFreeBitmap(Bitmap bitmap) {
- // do nothing
- }
- }
-
- private static void freeTile(Tile tile) {
- tile.invalidateContent();
- tile.bitmap = null;
- synchronized (sFreeTileLock) {
- tile.nextFreeTile = sFreeTileHead;
- sFreeTileHead = tile;
- }
- }
-
- private static Tile obtainTile() {
- synchronized (sFreeTileLock) {
- Tile result = sFreeTileHead;
- if (result == null) return new Tile();
- sFreeTileHead = result.nextFreeTile;
- result.nextFreeTile = null;
- return result;
- }
- }
-
- private boolean uploadNextTile(GLCanvas canvas) {
- if (mUploadIndex == mTiles.length) return true;
-
- synchronized (mTiles) {
- Tile next = mTiles[mUploadIndex++];
-
- // Make sure tile has not already been recycled by the time
- // this is called (race condition in onGLIdle)
- if (next.bitmap != null) {
- boolean hasBeenLoad = next.isLoaded();
- next.updateContent(canvas);
-
- // It will take some time for a texture to be drawn for the first
- // time. When scrolling, we need to draw several tiles on the screen
- // at the same time. It may cause a UI jank even these textures has
- // been uploaded.
- if (!hasBeenLoad) next.draw(canvas, 0, 0);
- }
- }
- return mUploadIndex == mTiles.length;
- }
-
- public TiledTexture(Bitmap bitmap) {
- mWidth = bitmap.getWidth();
- mHeight = bitmap.getHeight();
- ArrayList<Tile> list = new ArrayList<Tile>();
-
- for (int x = 0, w = mWidth; x < w; x += CONTENT_SIZE) {
- for (int y = 0, h = mHeight; y < h; y += CONTENT_SIZE) {
- Tile tile = obtainTile();
- tile.offsetX = x;
- tile.offsetY = y;
- tile.bitmap = bitmap;
- tile.setSize(
- Math.min(CONTENT_SIZE, mWidth - x),
- Math.min(CONTENT_SIZE, mHeight - y));
- list.add(tile);
- }
- }
- mTiles = list.toArray(new Tile[list.size()]);
- }
-
- public boolean isReady() {
- return mUploadIndex == mTiles.length;
- }
-
- // Can be called in UI thread.
- public void recycle() {
- synchronized (mTiles) {
- for (int i = 0, n = mTiles.length; i < n; ++i) {
- freeTile(mTiles[i]);
- }
- }
- }
-
- public static void freeResources() {
- sUploadBitmap = null;
- sCanvas = null;
- sBitmapPaint = null;
- sPaint = null;
- }
-
- public static void prepareResources() {
- sUploadBitmap = Bitmap.createBitmap(TILE_SIZE, TILE_SIZE, Config.ARGB_8888);
- sCanvas = new Canvas(sUploadBitmap);
- sBitmapPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
- sBitmapPaint.setXfermode(new PorterDuffXfermode(Mode.SRC));
- sPaint = new Paint();
- sPaint.setXfermode(new PorterDuffXfermode(Mode.SRC));
- sPaint.setColor(Color.TRANSPARENT);
- }
-
- // We want to draw the "source" on the "target".
- // This method is to find the "output" rectangle which is
- // the corresponding area of the "src".
- // (x,y) target
- // (x0,y0) source +---------------+
- // +----------+ | |
- // | src | | output |
- // | +--+ | linear map | +----+ |
- // | +--+ | ----------> | | | |
- // | | by (scaleX, scaleY) | +----+ |
- // +----------+ | |
- // Texture +---------------+
- // Canvas
- private static void mapRect(RectF output,
- RectF src, float x0, float y0, float x, float y, float scaleX,
- float scaleY) {
- output.set(x + (src.left - x0) * scaleX,
- y + (src.top - y0) * scaleY,
- x + (src.right - x0) * scaleX,
- y + (src.bottom - y0) * scaleY);
- }
-
- // Draws a mixed color of this texture and a specified color onto the
- // a rectangle. The used color is: from * (1 - ratio) + to * ratio.
- public void drawMixed(GLCanvas canvas, int color, float ratio,
- int x, int y, int width, int height) {
- RectF src = mSrcRect;
- RectF dest = mDestRect;
- float scaleX = (float) width / mWidth;
- float scaleY = (float) height / mHeight;
- synchronized (mTiles) {
- for (int i = 0, n = mTiles.length; i < n; ++i) {
- Tile t = mTiles[i];
- src.set(0, 0, t.contentWidth, t.contentHeight);
- src.offset(t.offsetX, t.offsetY);
- mapRect(dest, src, 0, 0, x, y, scaleX, scaleY);
- src.offset(BORDER_SIZE - t.offsetX, BORDER_SIZE - t.offsetY);
- canvas.drawMixed(t, color, ratio, mSrcRect, mDestRect);
- }
- }
- }
-
- // Draws the texture on to the specified rectangle.
- @Override
- public void draw(GLCanvas canvas, int x, int y, int width, int height) {
- RectF src = mSrcRect;
- RectF dest = mDestRect;
- float scaleX = (float) width / mWidth;
- float scaleY = (float) height / mHeight;
- synchronized (mTiles) {
- for (int i = 0, n = mTiles.length; i < n; ++i) {
- Tile t = mTiles[i];
- src.set(0, 0, t.contentWidth, t.contentHeight);
- src.offset(t.offsetX, t.offsetY);
- mapRect(dest, src, 0, 0, x, y, scaleX, scaleY);
- src.offset(BORDER_SIZE - t.offsetX, BORDER_SIZE - t.offsetY);
- canvas.drawTexture(t, mSrcRect, mDestRect);
- }
- }
- }
-
- // Draws a sub region of this texture on to the specified rectangle.
- public void draw(GLCanvas canvas, RectF source, RectF target) {
- RectF src = mSrcRect;
- RectF dest = mDestRect;
- float x0 = source.left;
- float y0 = source.top;
- float x = target.left;
- float y = target.top;
- float scaleX = target.width() / source.width();
- float scaleY = target.height() / source.height();
-
- synchronized (mTiles) {
- for (int i = 0, n = mTiles.length; i < n; ++i) {
- Tile t = mTiles[i];
- src.set(0, 0, t.contentWidth, t.contentHeight);
- src.offset(t.offsetX, t.offsetY);
- if (!src.intersect(source)) continue;
- mapRect(dest, src, x0, y0, x, y, scaleX, scaleY);
- src.offset(BORDER_SIZE - t.offsetX, BORDER_SIZE - t.offsetY);
- canvas.drawTexture(t, src, dest);
- }
- }
- }
-
- @Override
- public int getWidth() {
- return mWidth;
- }
-
- @Override
- public int getHeight() {
- return mHeight;
- }
-
- @Override
- public void draw(GLCanvas canvas, int x, int y) {
- draw(canvas, x, y, mWidth, mHeight);
- }
-
- @Override
- public boolean isOpaque() {
- return false;
- }
-}
diff --git a/src/com/android/gallery3d/ui/UndoBarView.java b/src/com/android/gallery3d/ui/UndoBarView.java
index 8c9836deb..42f12ae72 100644
--- a/src/com/android/gallery3d/ui/UndoBarView.java
+++ b/src/com/android/gallery3d/ui/UndoBarView.java
@@ -21,6 +21,10 @@ import android.view.MotionEvent;
import com.android.gallery3d.R;
import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.glrenderer.GLCanvas;
+import com.android.gallery3d.glrenderer.NinePatchTexture;
+import com.android.gallery3d.glrenderer.ResourceTexture;
+import com.android.gallery3d.glrenderer.StringTexture;
import com.android.gallery3d.util.GalleryUtils;
public class UndoBarView extends GLView {
diff --git a/src/com/android/gallery3d/ui/UploadedTexture.java b/src/com/android/gallery3d/ui/UploadedTexture.java
deleted file mode 100644
index bb86d05ef..000000000
--- a/src/com/android/gallery3d/ui/UploadedTexture.java
+++ /dev/null
@@ -1,331 +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.gallery3d.ui;
-
-import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
-import android.opengl.GLUtils;
-
-import com.android.gallery3d.common.Utils;
-
-import java.util.HashMap;
-
-import javax.microedition.khronos.opengles.GL11;
-import javax.microedition.khronos.opengles.GL11Ext;
-
-// UploadedTextures use a Bitmap for the content of the texture.
-//
-// Subclasses should implement onGetBitmap() to provide the Bitmap and
-// implement onFreeBitmap(mBitmap) which will be called when the Bitmap
-// is not needed anymore.
-//
-// isContentValid() is meaningful only when the isLoaded() returns true.
-// It means whether the content needs to be updated.
-//
-// The user of this class should call recycle() when the texture is not
-// needed anymore.
-//
-// By default an UploadedTexture is opaque (so it can be drawn faster without
-// blending). The user or subclass can override it using setOpaque().
-abstract class UploadedTexture extends BasicTexture {
-
- // To prevent keeping allocation the borders, we store those used borders here.
- // Since the length will be power of two, it won't use too much memory.
- private static HashMap<BorderKey, Bitmap> sBorderLines =
- new HashMap<BorderKey, Bitmap>();
- private static BorderKey sBorderKey = new BorderKey();
-
- @SuppressWarnings("unused")
- private static final String TAG = "Texture";
- private boolean mContentValid = true;
-
- // indicate this textures is being uploaded in background
- private boolean mIsUploading = false;
- private boolean mOpaque = true;
- private boolean mThrottled = false;
- private static int sUploadedCount;
- private static final int UPLOAD_LIMIT = 100;
-
- protected Bitmap mBitmap;
- private int mBorder;
-
- protected UploadedTexture() {
- this(false);
- }
-
- protected UploadedTexture(boolean hasBorder) {
- super(null, 0, STATE_UNLOADED);
- if (hasBorder) {
- setBorder(true);
- mBorder = 1;
- }
- }
-
- protected void setIsUploading(boolean uploading) {
- mIsUploading = uploading;
- }
-
- public boolean isUploading() {
- return mIsUploading;
- }
-
- private static class BorderKey implements Cloneable {
- public boolean vertical;
- public Config config;
- public int length;
-
- @Override
- public int hashCode() {
- int x = config.hashCode() ^ length;
- return vertical ? x : -x;
- }
-
- @Override
- public boolean equals(Object object) {
- if (!(object instanceof BorderKey)) return false;
- BorderKey o = (BorderKey) object;
- return vertical == o.vertical
- && config == o.config && length == o.length;
- }
-
- @Override
- public BorderKey clone() {
- try {
- return (BorderKey) super.clone();
- } catch (CloneNotSupportedException e) {
- throw new AssertionError(e);
- }
- }
- }
-
- protected void setThrottled(boolean throttled) {
- mThrottled = throttled;
- }
-
- private static Bitmap getBorderLine(
- boolean vertical, Config config, int length) {
- BorderKey key = sBorderKey;
- key.vertical = vertical;
- key.config = config;
- key.length = length;
- Bitmap bitmap = sBorderLines.get(key);
- if (bitmap == null) {
- bitmap = vertical
- ? Bitmap.createBitmap(1, length, config)
- : Bitmap.createBitmap(length, 1, config);
- sBorderLines.put(key.clone(), bitmap);
- }
- return bitmap;
- }
-
- private Bitmap getBitmap() {
- if (mBitmap == null) {
- mBitmap = onGetBitmap();
- int w = mBitmap.getWidth() + mBorder * 2;
- int h = mBitmap.getHeight() + mBorder * 2;
- if (mWidth == UNSPECIFIED) {
- setSize(w, h);
- }
- }
- return mBitmap;
- }
-
- private void freeBitmap() {
- Utils.assertTrue(mBitmap != null);
- onFreeBitmap(mBitmap);
- mBitmap = null;
- }
-
- @Override
- public int getWidth() {
- if (mWidth == UNSPECIFIED) getBitmap();
- return mWidth;
- }
-
- @Override
- public int getHeight() {
- if (mWidth == UNSPECIFIED) getBitmap();
- return mHeight;
- }
-
- protected abstract Bitmap onGetBitmap();
-
- protected abstract void onFreeBitmap(Bitmap bitmap);
-
- protected void invalidateContent() {
- if (mBitmap != null) freeBitmap();
- mContentValid = false;
- mWidth = UNSPECIFIED;
- mHeight = UNSPECIFIED;
- }
-
- /**
- * Whether the content on GPU is valid.
- */
- public boolean isContentValid() {
- return isLoaded() && mContentValid;
- }
-
- /**
- * Updates the content on GPU's memory.
- * @param canvas
- */
- public void updateContent(GLCanvas canvas) {
- if (!isLoaded()) {
- if (mThrottled && ++sUploadedCount > UPLOAD_LIMIT) {
- return;
- }
- uploadToCanvas(canvas);
- } else if (!mContentValid) {
- Bitmap bitmap = getBitmap();
- int format = GLUtils.getInternalFormat(bitmap);
- int type = GLUtils.getType(bitmap);
- canvas.getGLInstance().glBindTexture(GL11.GL_TEXTURE_2D, mId);
- GLUtils.texSubImage2D(GL11.GL_TEXTURE_2D, 0, mBorder, mBorder,
- bitmap, format, type);
- freeBitmap();
- mContentValid = true;
- }
- }
-
- public static void resetUploadLimit() {
- sUploadedCount = 0;
- }
-
- public static boolean uploadLimitReached() {
- return sUploadedCount > UPLOAD_LIMIT;
- }
-
- static int[] sTextureId = new int[1];
- static float[] sCropRect = new float[4];
-
- private void uploadToCanvas(GLCanvas canvas) {
- GL11 gl = canvas.getGLInstance();
-
- Bitmap bitmap = getBitmap();
- if (bitmap != null) {
- try {
- int bWidth = bitmap.getWidth();
- int bHeight = bitmap.getHeight();
- int width = bWidth + mBorder * 2;
- int height = bHeight + mBorder * 2;
- int texWidth = getTextureWidth();
- int texHeight = getTextureHeight();
-
- Utils.assertTrue(bWidth <= texWidth && bHeight <= texHeight);
-
- // Define a vertically flipped crop rectangle for
- // OES_draw_texture.
- // The four values in sCropRect are: left, bottom, width, and
- // height. Negative value of width or height means flip.
- sCropRect[0] = mBorder;
- sCropRect[1] = mBorder + bHeight;
- sCropRect[2] = bWidth;
- sCropRect[3] = -bHeight;
-
- // Upload the bitmap to a new texture.
- GLId.glGenTextures(1, sTextureId, 0);
- gl.glBindTexture(GL11.GL_TEXTURE_2D, sTextureId[0]);
- gl.glTexParameterfv(GL11.GL_TEXTURE_2D,
- GL11Ext.GL_TEXTURE_CROP_RECT_OES, sCropRect, 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);
-
- if (bWidth == texWidth && bHeight == texHeight) {
- GLUtils.texImage2D(GL11.GL_TEXTURE_2D, 0, bitmap, 0);
- } else {
- int format = GLUtils.getInternalFormat(bitmap);
- int type = GLUtils.getType(bitmap);
- Config config = bitmap.getConfig();
-
- gl.glTexImage2D(GL11.GL_TEXTURE_2D, 0, format,
- texWidth, texHeight, 0, format, type, null);
- GLUtils.texSubImage2D(GL11.GL_TEXTURE_2D, 0,
- mBorder, mBorder, bitmap, format, type);
-
- if (mBorder > 0) {
- // Left border
- Bitmap line = getBorderLine(true, config, texHeight);
- GLUtils.texSubImage2D(GL11.GL_TEXTURE_2D, 0,
- 0, 0, line, format, type);
-
- // Top border
- line = getBorderLine(false, config, texWidth);
- GLUtils.texSubImage2D(GL11.GL_TEXTURE_2D, 0,
- 0, 0, line, format, type);
- }
-
- // Right border
- if (mBorder + bWidth < texWidth) {
- Bitmap line = getBorderLine(true, config, texHeight);
- GLUtils.texSubImage2D(GL11.GL_TEXTURE_2D, 0,
- mBorder + bWidth, 0, line, format, type);
- }
-
- // Bottom border
- if (mBorder + bHeight < texHeight) {
- Bitmap line = getBorderLine(false, config, texWidth);
- GLUtils.texSubImage2D(GL11.GL_TEXTURE_2D, 0,
- 0, mBorder + bHeight, line, format, type);
- }
- }
- } finally {
- freeBitmap();
- }
- // Update texture state.
- setAssociatedCanvas(canvas);
- mId = sTextureId[0];
- mState = STATE_LOADED;
- mContentValid = true;
- } else {
- mState = STATE_ERROR;
- throw new RuntimeException("Texture load fail, no bitmap");
- }
- }
-
- @Override
- protected boolean onBind(GLCanvas canvas) {
- updateContent(canvas);
- return isContentValid();
- }
-
- @Override
- protected int getTarget() {
- return GL11.GL_TEXTURE_2D;
- }
-
- public void setOpaque(boolean isOpaque) {
- mOpaque = isOpaque;
- }
-
- @Override
- public boolean isOpaque() {
- return mOpaque;
- }
-
- @Override
- public void recycle() {
- super.recycle();
- if (mBitmap != null) freeBitmap();
- }
-}