summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChih-Chung Chang <chihchung@google.com>2012-03-22 17:42:33 +0800
committerChih-Chung Chang <chihchung@google.com>2012-04-02 11:24:23 +0800
commit037e06c5e11ca4a4e40b0741f2d6604b2fd9337a (patch)
tree047235a4ce31aa2c013db38d99056a7196b491e1
parentb10f96d2141fae10073ec48f25d7b824647f8f31 (diff)
downloadandroid_packages_apps_Snap-037e06c5e11ca4a4e40b0741f2d6604b2fd9337a.tar.gz
android_packages_apps_Snap-037e06c5e11ca4a4e40b0741f2d6604b2fd9337a.tar.bz2
android_packages_apps_Snap-037e06c5e11ca4a4e40b0741f2d6604b2fd9337a.zip
Use SurfaceTexture to show Camera preview.
Change-Id: I8bf63dfc5b969ecce51841378b093a650b6f91d8
-rw-r--r--src/com/android/gallery3d/app/AlbumPage.java6
-rw-r--r--src/com/android/gallery3d/app/CameraScreenNail.java225
-rw-r--r--src/com/android/gallery3d/app/CameraView.java117
-rw-r--r--src/com/android/gallery3d/app/PhotoDataAdapter.java2
-rw-r--r--src/com/android/gallery3d/app/PhotoPage.java72
-rw-r--r--src/com/android/gallery3d/app/ScreenNailBridge.java122
-rw-r--r--src/com/android/gallery3d/data/SnailSource.java15
-rw-r--r--src/com/android/gallery3d/ui/BasicTexture.java3
-rw-r--r--src/com/android/gallery3d/ui/BitmapScreenNail.java10
-rw-r--r--src/com/android/gallery3d/ui/BitmapTileProvider.java2
-rw-r--r--src/com/android/gallery3d/ui/ExtTexture.java89
-rw-r--r--src/com/android/gallery3d/ui/GLCanvas.java6
-rw-r--r--src/com/android/gallery3d/ui/GLCanvasImpl.java47
-rw-r--r--src/com/android/gallery3d/ui/GLId.java40
-rw-r--r--src/com/android/gallery3d/ui/NinePatchTexture.java2
-rw-r--r--src/com/android/gallery3d/ui/PhotoView.java29
-rw-r--r--src/com/android/gallery3d/ui/ScreenNail.java6
-rw-r--r--src/com/android/gallery3d/ui/ScreenNailHolder.java31
-rw-r--r--src/com/android/gallery3d/ui/SurfaceTextureScreenNail.java116
-rw-r--r--src/com/android/gallery3d/ui/TileImageView.java12
-rw-r--r--src/com/android/gallery3d/ui/UploadedTexture.java7
-rw-r--r--tests/src/com/android/gallery3d/ui/GLCanvasStub.java2
-rw-r--r--tests/src/com/android/gallery3d/ui/TextureTest.java10
23 files changed, 643 insertions, 328 deletions
diff --git a/src/com/android/gallery3d/app/AlbumPage.java b/src/com/android/gallery3d/app/AlbumPage.java
index 8bd2badf8..37ddb184c 100644
--- a/src/com/android/gallery3d/app/AlbumPage.java
+++ b/src/com/android/gallery3d/app/AlbumPage.java
@@ -51,6 +51,7 @@ import com.android.gallery3d.ui.HighlightDrawer;
import com.android.gallery3d.ui.PositionProvider;
import com.android.gallery3d.ui.PositionRepository;
import com.android.gallery3d.ui.PositionRepository.Position;
+import com.android.gallery3d.ui.ScreenNailHolder;
import com.android.gallery3d.ui.SelectionManager;
import com.android.gallery3d.ui.SlotView;
import com.android.gallery3d.util.Future;
@@ -77,6 +78,7 @@ public class AlbumPage extends ActivityState implements GalleryActionBar.Cluster
private static final int BIT_LOADING_SYNC = 2;
private static final float USER_DISTANCE_METER = 0.3f;
+ private static final boolean TEST_CAMERA_PREVIEW = false;
private boolean mIsActive = false;
private AlbumView mAlbumView;
@@ -196,6 +198,10 @@ public class AlbumPage extends ActivityState implements GalleryActionBar.Cluster
mMediaSetPath.toString());
data.putString(PhotoPage.KEY_MEDIA_ITEM_PATH,
item.getPath().toString());
+ if (TEST_CAMERA_PREVIEW) {
+ ScreenNailHolder holder = new CameraScreenNailHolder(mActivity);
+ data.putParcelable(PhotoPage.KEY_SCREENNAIL_HOLDER, holder);
+ }
mActivity.getStateManager().startStateForResult(
PhotoPage.class, REQUEST_PHOTO, data);
}
diff --git a/src/com/android/gallery3d/app/CameraScreenNail.java b/src/com/android/gallery3d/app/CameraScreenNail.java
new file mode 100644
index 000000000..f68ab72f8
--- /dev/null
+++ b/src/com/android/gallery3d/app/CameraScreenNail.java
@@ -0,0 +1,225 @@
+/*
+ * 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.app;
+
+import android.app.Activity;
+import android.graphics.SurfaceTexture;
+import android.hardware.Camera;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Message;
+import android.util.Log;
+import android.view.Surface;
+
+import com.android.gallery3d.ui.GLCanvas;
+import com.android.gallery3d.ui.ScreenNail;
+import com.android.gallery3d.ui.ScreenNailHolder;
+import com.android.gallery3d.ui.SurfaceTextureScreenNail;
+
+// This is a ScreenNail which displays camera preview. This demos the usage of
+// SurfaceTextureScreenNail. It is not intended for production use.
+class CameraScreenNail extends SurfaceTextureScreenNail {
+ private static final String TAG = "CameraScreenNail";
+ private static final int CAMERA_ID = 0;
+ private static final int PREVIEW_WIDTH = 960;
+ private static final int PREVIEW_HEIGHT = 720;
+ private static final int MSG_START_CAMERA = 1;
+ private static final int MSG_STOP_CAMERA = 2;
+
+ public interface Listener {
+ void requestRender();
+ }
+
+ private Activity mActivity;
+ private Listener mListener;
+ private int mOrientation;
+ private Camera mCamera;
+
+ private HandlerThread mHandlerThread;
+ private Handler mHandler;
+ private volatile boolean mVisible;
+ private volatile boolean mHasFrame;
+
+ public CameraScreenNail(Activity activity, Listener listener) {
+ mActivity = activity;
+ mListener = listener;
+
+ mOrientation = getCameraDisplayOrientation(mActivity, CAMERA_ID);
+ if (mOrientation % 180 == 0) {
+ setSize(PREVIEW_WIDTH, PREVIEW_HEIGHT);
+ } else {
+ setSize(PREVIEW_HEIGHT, PREVIEW_WIDTH);
+ }
+
+ mHandlerThread = new HandlerThread("Camera");
+ mHandlerThread.start();
+ mHandler = new Handler(mHandlerThread.getLooper()) {
+ public void handleMessage(Message message) {
+ if (message.what == MSG_START_CAMERA && mCamera == null) {
+ startCamera();
+ } else if (message.what == MSG_STOP_CAMERA && mCamera != null) {
+ stopCamera();
+ }
+ }
+ };
+ mHandler.sendEmptyMessage(MSG_START_CAMERA);
+ }
+
+ private void startCamera() {
+ try {
+ acquireSurfaceTexture();
+ Camera camera = Camera.open(CAMERA_ID);
+ Camera.Parameters param = camera.getParameters();
+ param.setPreviewSize(PREVIEW_WIDTH, PREVIEW_HEIGHT);
+ camera.setParameters(param);
+ camera.setDisplayOrientation(mOrientation);
+ camera.setPreviewTexture(getSurfaceTexture());
+ camera.startPreview();
+ synchronized (this) {
+ mCamera = camera;
+ }
+ } catch (Throwable th) {
+ Log.e(TAG, "cannot open camera", th);
+ }
+ }
+
+ private void stopCamera() {
+ releaseSurfaceTexture();
+ mCamera.stopPreview();
+ mCamera.release();
+ synchronized (this) {
+ mCamera = null;
+ notifyAll();
+ }
+ mHasFrame = false;
+ }
+
+ @Override
+ public void draw(GLCanvas canvas, int x, int y, int width, int height) {
+ if (!mVisible) {
+ mVisible = true;
+ // Only send one message when mVisible makes transition from
+ // false to true.
+ mHandler.sendEmptyMessage(MSG_START_CAMERA);
+ }
+
+ if (mVisible && mHasFrame) {
+ super.draw(canvas, x, y, width, height);
+ }
+ }
+
+ @Override
+ public void noDraw() {
+ mVisible = false;
+ }
+
+ @Override
+ public void pauseDraw() {
+ mVisible = false;
+ }
+
+ @Override
+ public void onFrameAvailable(SurfaceTexture surfaceTexture) {
+ mHasFrame = true;
+ if (mVisible) {
+ // We need to ask for re-render if the SurfaceTexture receives a new
+ // frame (and we are visible).
+ mListener.requestRender();
+ }
+ }
+
+ public void destroy() {
+ synchronized (this) {
+ mHandler.sendEmptyMessage(MSG_STOP_CAMERA);
+
+ // Wait until camera is closed.
+ while (mCamera != null) {
+ try {
+ wait();
+ } catch (Exception ex) {
+ // ignore.
+ }
+ }
+ }
+ mHandlerThread.quit();
+ }
+
+ // The three methods below are copied from Camera.java
+ private static int getCameraDisplayOrientation(
+ Activity activity, int cameraId) {
+ int displayRotation = getDisplayRotation(activity);
+ int displayOrientation = getDisplayOrientation(
+ displayRotation, cameraId);
+ return displayOrientation;
+ }
+
+ private static int getDisplayRotation(Activity activity) {
+ int rotation = activity.getWindowManager().getDefaultDisplay()
+ .getRotation();
+ switch (rotation) {
+ case Surface.ROTATION_0: return 0;
+ case Surface.ROTATION_90: return 90;
+ case Surface.ROTATION_180: return 180;
+ case Surface.ROTATION_270: return 270;
+ }
+ return 0;
+ }
+
+ private static int getDisplayOrientation(int degrees, int cameraId) {
+ // See android.hardware.Camera.setDisplayOrientation for
+ // documentation.
+ Camera.CameraInfo info = new Camera.CameraInfo();
+ Camera.getCameraInfo(cameraId, info);
+ int result;
+ if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
+ result = (info.orientation + degrees) % 360;
+ result = (360 - result) % 360; // compensate the mirror
+ } else { // back-facing
+ result = (info.orientation - degrees + 360) % 360;
+ }
+ return result;
+ }
+}
+
+// This holds a CameraScreenNail, so we can pass it to a PhotoPage.
+class CameraScreenNailHolder extends ScreenNailHolder
+ implements CameraScreenNail.Listener {
+ private static final String TAG = "CameraScreenNailHolder";
+ private GalleryActivity mActivity;
+ private CameraScreenNail mCameraScreenNail;
+
+ public CameraScreenNailHolder(GalleryActivity activity) {
+ mActivity = activity;
+ }
+
+ @Override
+ public void requestRender() {
+ mActivity.getGLRoot().requestRender();
+ }
+
+ @Override
+ public ScreenNail attach() {
+ mCameraScreenNail = new CameraScreenNail((Activity) mActivity, this);
+ return mCameraScreenNail;
+ }
+
+ @Override
+ public void detach() {
+ mCameraScreenNail.destroy();
+ mCameraScreenNail = null;
+ }
+}
diff --git a/src/com/android/gallery3d/app/CameraView.java b/src/com/android/gallery3d/app/CameraView.java
deleted file mode 100644
index a6c233291..000000000
--- a/src/com/android/gallery3d/app/CameraView.java
+++ /dev/null
@@ -1,117 +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.app;
-
-import android.content.Context;
-import android.graphics.SurfaceTexture;
-import android.hardware.Camera;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.TextureView;
-import android.view.View;
-
-import java.io.IOException;
-
-// This is a sample View which demos the usage of ScreenNailBridge. It
-// is not intended for production use.
-public class CameraView extends TextureView implements
- TextureView.SurfaceTextureListener, ScreenNailBridge.Listener {
- private static final String TAG = "CameraView";
- private static final int PREVIEW_WIDTH = 960;
- private static final int PREVIEW_HEIGHT = 720;
- private Camera mCamera;
- private ScreenNailBridge mScreenNailBridge;
-
- public CameraView(Context context) {
- super(context);
- init();
- }
-
- public CameraView(Context context, AttributeSet attrs) {
- super(context, attrs);
- init();
- }
-
- private void init() {
- setVisibility(View.INVISIBLE);
- setSurfaceTextureListener(this);
- }
-
- public void setScreenNailBridge(ScreenNailBridge s) {
- mScreenNailBridge = s;
- }
-
- @Override
- public void onMeasure(int widthSpec, int heightSpec) {
- int width = getDefaultSize(PREVIEW_WIDTH, widthSpec);
- int height = getDefaultSize(PREVIEW_HEIGHT, heightSpec);
- // Keep aspect ratio
- if (width * PREVIEW_HEIGHT > PREVIEW_WIDTH * height) {
- width = PREVIEW_WIDTH * height / PREVIEW_HEIGHT;
- } else {
- height = PREVIEW_HEIGHT * width / PREVIEW_WIDTH;
- }
- setMeasuredDimension(width, height);
- }
-
- @Override
- public void onSizeChanged(int w, int h, int oldw, int oldh) {
- mScreenNailBridge.setSize(w, h);
- }
-
- @Override
- public void updateView(boolean visible, int x, int y, int w, int h) {
- if (!visible) {
- setVisibility(View.INVISIBLE);
- } else {
- setVisibility(View.VISIBLE);
- setTranslationX(x);
- setTranslationY(y);
- }
- }
-
- @Override
- public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
- try {
- mCamera = Camera.open();
-
- Camera.Parameters param = mCamera.getParameters();
- param.setPreviewSize(PREVIEW_WIDTH, PREVIEW_HEIGHT);
- mCamera.setParameters(param);
-
- mCamera.setPreviewTexture(surface);
- mCamera.startPreview();
- } catch (Throwable ex) {
- Log.e(TAG, "failed to open camera", ex);
- }
- }
-
- @Override
- public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
- mCamera.stopPreview();
- mCamera.release();
- return true;
- }
-
- @Override
- public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
- }
-
- @Override
- public void onSurfaceTextureUpdated(SurfaceTexture surface) {
- }
-}
diff --git a/src/com/android/gallery3d/app/PhotoDataAdapter.java b/src/com/android/gallery3d/app/PhotoDataAdapter.java
index a4fd411af..109323c1c 100644
--- a/src/com/android/gallery3d/app/PhotoDataAdapter.java
+++ b/src/com/android/gallery3d/app/PhotoDataAdapter.java
@@ -221,7 +221,7 @@ public class PhotoDataAdapter implements PhotoPage.Model {
ScreenNail screenNail = future.get();
if (entry == null || entry.screenNailTask != future) {
- if (screenNail != null) screenNail.recycle();
+ if (screenNail != null) screenNail.pauseDraw();
return;
}
diff --git a/src/com/android/gallery3d/app/PhotoPage.java b/src/com/android/gallery3d/app/PhotoPage.java
index 3a18dd2e4..9a1992e54 100644
--- a/src/com/android/gallery3d/app/PhotoPage.java
+++ b/src/com/android/gallery3d/app/PhotoPage.java
@@ -55,6 +55,8 @@ import com.android.gallery3d.ui.GLCanvas;
import com.android.gallery3d.ui.GLView;
import com.android.gallery3d.ui.ImportCompleteListener;
import com.android.gallery3d.ui.MenuExecutor;
+import com.android.gallery3d.ui.ScreenNail;
+import com.android.gallery3d.ui.ScreenNailHolder;
import com.android.gallery3d.ui.PhotoView;
import com.android.gallery3d.ui.PositionRepository;
import com.android.gallery3d.ui.PositionRepository.Position;
@@ -80,6 +82,7 @@ public class PhotoPage extends ActivityState
public static final String KEY_MEDIA_ITEM_PATH = "media-item-path";
public static final String KEY_INDEX_HINT = "index-hint";
public static final String KEY_OPEN_ANIMATION_RECT = "open-animation-rect";
+ public static final String KEY_SCREENNAIL_HOLDER = "screennail-holder";
private GalleryApp mApplication;
private SelectionManager mSelectionManager;
@@ -109,11 +112,8 @@ public class PhotoPage extends ActivityState
private boolean mIsActive;
private ShareActionProvider mShareActionProvider;
private String mSetPathString;
-
- // This is for testing only. It should be removed once we have the real
- // Camera view.
- private CameraView mCameraView;
- private ScreenNailBridge mScreenNail;
+ private ScreenNailHolder mScreenNailHolder;
+ private ScreenNail mScreenNail;
public static interface Model extends PhotoView.Model {
public void resume();
@@ -190,14 +190,24 @@ public class PhotoPage extends ActivityState
Path itemPath = Path.fromString(data.getString(KEY_MEDIA_ITEM_PATH));
if (mSetPathString != null) {
- // Uncomment the block below to test camera screennail.
- /*
- Path cameraScreenNailSetPath = addCameraScreenNail();
-
- // Combine the original MediaSet with the one for camera ScreenNail.
- mSetPathString = "/combo/item/{" + cameraScreenNailSetPath + "," +
- mSetPathString + "}";
- */
+ mScreenNailHolder =
+ (ScreenNailHolder) data.getParcelable(KEY_SCREENNAIL_HOLDER);
+ if (mScreenNailHolder != null) {
+ mScreenNail = mScreenNailHolder.attach();
+
+ // Get the ScreenNail from ScreenNailHolder and register it.
+ int id = SnailSource.registerScreenNail(mScreenNail);
+ Path screenNailSetPath = SnailSource.getSetPath(id);
+ Path screenNailItemPath = SnailSource.getItemPath(id);
+
+ // Combine the original MediaSet with the one for CameraScreenNail.
+ mSetPathString = "/combo/item/{" + screenNailSetPath +
+ "," + mSetPathString + "}";
+
+ // Start from the screen nail.
+ itemPath = screenNailItemPath;
+ }
+
mMediaSet = mActivity.getDataManager().getMediaSet(mSetPathString);
mCurrentIndex = data.getInt(KEY_INDEX_HINT, 0);
mMediaSet = (MediaSet)
@@ -279,34 +289,6 @@ public class PhotoPage extends ActivityState
}
}
- // We create a Camera View and a ScreenNail. The two work together
- // to present the view together with other pictures. Returns the
- // Path of the MediaItem hosting the ScreenNail.
- private Path addCameraScreenNail() {
- // Create a camera view and add it to the root.
- Activity activity = (Activity) mActivity;
- mCameraView = new CameraView(activity);
- ViewGroup galleryRoot = (ViewGroup) activity.findViewById(R.id.gallery_root);
- galleryRoot.addView(mCameraView);
-
- // Create a ScreenNail and register it.
- mScreenNail = new ScreenNailBridge(mCameraView);
- mCameraView.setScreenNailBridge(mScreenNail);
- return SnailSource.registerScreenNail(mScreenNail);
- }
-
- private void removeCameraScreenNail() {
- if (mCameraView == null) return;
-
- // Remove the camera view.
- ((ViewGroup) mCameraView.getParent()).removeView(mCameraView);
- mCameraView = null;
-
- // Unregister the ScreenNail.
- SnailSource.unregisterScreenNail(mScreenNail);
- mScreenNail = null;
- }
-
private void updateShareURI(Path path) {
if (mShareActionProvider != null) {
DataManager manager = mActivity.getDataManager();
@@ -690,7 +672,13 @@ public class PhotoPage extends ActivityState
@Override
protected void onDestroy() {
- removeCameraScreenNail();
+ if (mScreenNailHolder != null) {
+ // Unregister the ScreenNail and notify mScreenNailHolder.
+ SnailSource.unregisterScreenNail(mScreenNail);
+ mScreenNailHolder.detach();
+ mScreenNailHolder = null;
+ mScreenNail = null;
+ }
super.onDestroy();
}
diff --git a/src/com/android/gallery3d/app/ScreenNailBridge.java b/src/com/android/gallery3d/app/ScreenNailBridge.java
deleted file mode 100644
index 9da197dca..000000000
--- a/src/com/android/gallery3d/app/ScreenNailBridge.java
+++ /dev/null
@@ -1,122 +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.app;
-
-import android.graphics.RectF;
-import android.os.Handler;
-import android.util.Log;
-
-import com.android.gallery3d.ui.GLCanvas;
-import com.android.gallery3d.ui.ScreenNail;
-
-// This is a ScreenNail whose actually display is done by an foreign component.
-// The foreign component tells the ScreenNail its size by setSize(). The
-// ScreenNail tells the foreign component the position to display by
-// updateView().
-class ScreenNailBridge implements ScreenNail {
- private static final String TAG = "ScreenNailBridge";
- private int mWidth, mHeight;
- private boolean mVisible = false;
- private int mDrawX, mDrawY, mDrawWidth, mDrawHeight;
- private Listener mListener;
- private Handler mMainHandler;
-
- public interface Listener {
- // This is called from the main thread.
- void updateView(boolean visible, int x, int y, int width, int height);
- };
-
- // The constructor should be called from the main thread.
- public ScreenNailBridge(Listener listener) {
- mListener = listener;
- mMainHandler = new Handler();
- }
-
- // This can be called from any thread. (We expect it to be called from the
- // main thread).
- public synchronized void setSize(int w, int h) {
- mWidth = w;
- mHeight = h;
- }
-
- // This can be called from any thread. (We expect it to be called from GL
- // thread)
- @Override
- public synchronized int getWidth() {
- return mWidth;
- }
-
- // This can be called from any thread. (We expect it to be called from GL
- // thread)
- @Override
- public synchronized int getHeight() {
- return mHeight;
- }
-
- @Override
- public int getRotation() {
- return 0;
- }
-
- // This is run in the main thread.
- private Runnable mUpdateViewRunnable = new Runnable() {
- public void run() {
- boolean v;
- int x, y, width, height;
- synchronized (ScreenNailBridge.this) {
- v = mVisible;
- x = mDrawX;
- y = mDrawY;
- width = mDrawWidth;
- height = mDrawHeight;
- }
- mListener.updateView(v, x, y, width, height);
- }
- };
-
- @Override
- public synchronized void draw(GLCanvas canvas, int x, int y, int width, int height) {
- if (mVisible && mDrawX == x && mDrawY == y && mDrawWidth == width &&
- mDrawHeight == height) {
- return;
- }
- mVisible = true;
- mDrawX = x;
- mDrawY = y;
- mDrawWidth = width;
- mDrawHeight = height;
- mMainHandler.post(mUpdateViewRunnable);
- }
-
- @Override
- public synchronized void disableDraw() {
- if (!mVisible) return;
- mVisible = false;
- mMainHandler.post(mUpdateViewRunnable);
- }
-
- @Override
- public void recycle() {
- // Make sure we will not draw anymore.
- disableDraw();
- }
-
- @Override
- public void draw(GLCanvas canvas, RectF source, RectF dest) {
- throw new UnsupportedOperationException();
- }
-}
diff --git a/src/com/android/gallery3d/data/SnailSource.java b/src/com/android/gallery3d/data/SnailSource.java
index 17b899dba..e74a8bb94 100644
--- a/src/com/android/gallery3d/data/SnailSource.java
+++ b/src/com/android/gallery3d/data/SnailSource.java
@@ -55,14 +55,23 @@ public class SnailSource extends MediaSource {
return null;
}
- // Register a ScreenNail. Returns the Path of the MediaSet
- // containing the MediaItem associated with the ScreenNail.
- public static synchronized Path registerScreenNail(ScreenNail s) {
+ // Registers a ScreenNail and returns the id of it. You can obtain the Path
+ // of the MediaItem associated with the ScreenNail by getItemPath(), and the
+ // Path of the MediaSet containing that MediaItem by getSetPath().
+ public static synchronized int registerScreenNail(ScreenNail s) {
int id = sNextId++;
sRegistry.put(id, s);
+ return id;
+ }
+
+ public static Path getSetPath(int id) {
return Path.fromString("/snail/set").getChild(id);
}
+ public static Path getItemPath(int id) {
+ return Path.fromString("/snail/item").getChild(id);
+ }
+
public static synchronized void unregisterScreenNail(ScreenNail s) {
int index = sRegistry.indexOfValue(s);
sRegistry.removeAt(index);
diff --git a/src/com/android/gallery3d/ui/BasicTexture.java b/src/com/android/gallery3d/ui/BasicTexture.java
index d3dfd745c..6a9a17d92 100644
--- a/src/com/android/gallery3d/ui/BasicTexture.java
+++ b/src/com/android/gallery3d/ui/BasicTexture.java
@@ -130,6 +130,9 @@ abstract class BasicTexture implements 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(GLCanvas canvas) {
return mState == STATE_LOADED;
}
diff --git a/src/com/android/gallery3d/ui/BitmapScreenNail.java b/src/com/android/gallery3d/ui/BitmapScreenNail.java
index 117a9ac30..5a1006845 100644
--- a/src/com/android/gallery3d/ui/BitmapScreenNail.java
+++ b/src/com/android/gallery3d/ui/BitmapScreenNail.java
@@ -56,7 +56,11 @@ public class BitmapScreenNail implements ScreenNail {
}
@Override
- public void recycle() {
+ public void noDraw() {
+ }
+
+ @Override
+ public void pauseDraw() {
if (mTexture != null) {
mTexture.recycle();
}
@@ -71,10 +75,6 @@ public class BitmapScreenNail implements ScreenNail {
}
@Override
- public void disableDraw() {
- }
-
- @Override
public void draw(GLCanvas canvas, RectF source, RectF dest) {
if (mTexture == null) {
mTexture = new BitmapTexture(mBitmap);
diff --git a/src/com/android/gallery3d/ui/BitmapTileProvider.java b/src/com/android/gallery3d/ui/BitmapTileProvider.java
index 99b64d42e..1e78cfd33 100644
--- a/src/com/android/gallery3d/ui/BitmapTileProvider.java
+++ b/src/com/android/gallery3d/ui/BitmapTileProvider.java
@@ -96,7 +96,7 @@ public class BitmapTileProvider implements TileImageView.Model {
BitmapUtils.recycleSilently(bitmap);
}
if (mScreenNail != null) {
- mScreenNail.recycle();
+ mScreenNail.pauseDraw();
}
}
diff --git a/src/com/android/gallery3d/ui/ExtTexture.java b/src/com/android/gallery3d/ui/ExtTexture.java
new file mode 100644
index 000000000..e39f317a3
--- /dev/null
+++ b/src/com/android/gallery3d/ui/ExtTexture.java
@@ -0,0 +1,89 @@
+/*
+ * 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.SurfaceTexture;
+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 = UploadedTexture.STATE_LOADED;
+ }
+
+ @Override
+ protected boolean onBind(GLCanvas canvas) {
+ if (!isLoaded(canvas)) {
+ uploadToCanvas(canvas);
+ }
+
+ return true;
+ }
+
+ @Override
+ public int getTarget() {
+ return mTarget;
+ }
+
+ 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/GLCanvas.java b/src/com/android/gallery3d/ui/GLCanvas.java
index 1359115f8..9b8053ffc 100644
--- a/src/com/android/gallery3d/ui/GLCanvas.java
+++ b/src/com/android/gallery3d/ui/GLCanvas.java
@@ -85,9 +85,13 @@ public interface GLCanvas {
public void drawMesh(BasicTexture tex, int x, int y, int xyBuffer,
int uvBuffer, int indexBuffer, int indexCount);
- // Draws a the source rectangle part of the texture to the target rectangle.
+ // 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.
diff --git a/src/com/android/gallery3d/ui/GLCanvasImpl.java b/src/com/android/gallery3d/ui/GLCanvasImpl.java
index 68f5636f7..686e712bd 100644
--- a/src/com/android/gallery3d/ui/GLCanvasImpl.java
+++ b/src/com/android/gallery3d/ui/GLCanvasImpl.java
@@ -136,7 +136,7 @@ public class GLCanvasImpl implements GLCanvas {
xyBuffer.put(BOX_COORDINATES, 0, BOX_COORDINATES.length).position(0);
int[] name = new int[1];
- gl.glGenBuffers(1, name, 0);
+ GLId.glGenBuffers(1, name, 0);
mBoxCoords = name[0];
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, mBoxCoords);
@@ -377,6 +377,16 @@ public class GLCanvasImpl implements GLCanvas {
textureRect(target.left, target.top, target.width(), target.height());
}
+ 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.
@@ -415,8 +425,9 @@ public class GLCanvasImpl implements GLCanvas {
private boolean bindTexture(BasicTexture texture) {
if (!texture.onBind(this)) return false;
- mGLState.setTexture2DEnabled(true);
- mGL.glBindTexture(GL11.GL_TEXTURE_2D, texture.getId());
+ int target = texture.getTarget();
+ mGLState.setTextureTarget(target);
+ mGL.glBindTexture(target, texture.getId());
return true;
}
@@ -513,7 +524,7 @@ public class GLCanvasImpl implements GLCanvas {
private int mTexEnvMode = GL11.GL_REPLACE;
private float mTextureAlpha = 1.0f;
- private boolean mTexture2DEnabled = true;
+ private int mTextureTarget = 0;
private boolean mBlendEnabled = true;
private float mLineWidth = 1.0f;
private boolean mLineSmooth = false;
@@ -578,7 +589,7 @@ public class GLCanvasImpl implements GLCanvas {
// again in setTextureAlpha(float) later.
mTextureAlpha = -1.0f;
- setTexture2DEnabled(false);
+ setTextureTarget(0);
float prealpha = (color >>> 24) * alpha * 65535f / 255f / 255f;
mGL.glColor4x(
@@ -588,13 +599,15 @@ public class GLCanvasImpl implements GLCanvas {
Math.round(255 * prealpha));
}
- public void setTexture2DEnabled(boolean enabled) {
- if (mTexture2DEnabled == enabled) return;
- mTexture2DEnabled = enabled;
- if (enabled) {
- mGL.glEnable(GL11.GL_TEXTURE_2D);
- } else {
- mGL.glDisable(GL11.GL_TEXTURE_2D);
+ // 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);
}
}
@@ -634,6 +647,12 @@ public class GLCanvasImpl implements GLCanvas {
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.
public boolean unloadTexture(BasicTexture t) {
@@ -654,13 +673,13 @@ public class GLCanvasImpl implements GLCanvas {
synchronized (mUnboundTextures) {
IntArray ids = mUnboundTextures;
if (ids.size() > 0) {
- mGL.glDeleteTextures(ids.size(), ids.getInternalArray(), 0);
+ GLId.glDeleteTextures(ids.size(), ids.getInternalArray(), 0);
ids.clear();
}
ids = mDeleteBuffers;
if (ids.size() > 0) {
- mGL.glDeleteBuffers(ids.size(), ids.getInternalArray(), 0);
+ GLId.glDeleteBuffers(ids.size(), ids.getInternalArray(), 0);
ids.clear();
}
}
diff --git a/src/com/android/gallery3d/ui/GLId.java b/src/com/android/gallery3d/ui/GLId.java
new file mode 100644
index 000000000..c228c350d
--- /dev/null
+++ b/src/com/android/gallery3d/ui/GLId.java
@@ -0,0 +1,40 @@
+/*
+ * 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;
+
+// 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(int n, int[] textures, int offset) {
+ }
+
+ public synchronized static void glDeleteBuffers(int n, int[] buffers, int offset) {
+ }
+}
diff --git a/src/com/android/gallery3d/ui/NinePatchTexture.java b/src/com/android/gallery3d/ui/NinePatchTexture.java
index 6a2ba0037..957229eb5 100644
--- a/src/com/android/gallery3d/ui/NinePatchTexture.java
+++ b/src/com/android/gallery3d/ui/NinePatchTexture.java
@@ -398,7 +398,7 @@ class NinePatchInstance {
private void prepareBuffers(GLCanvas canvas) {
mBufferNames = new int[3];
GL11 gl = canvas.getGLInstance();
- gl.glGenBuffers(3, mBufferNames, 0);
+ GLId.glGenBuffers(3, mBufferNames, 0);
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, mBufferNames[0]);
gl.glBufferData(GL11.GL_ARRAY_BUFFER,
diff --git a/src/com/android/gallery3d/ui/PhotoView.java b/src/com/android/gallery3d/ui/PhotoView.java
index 252f3484d..77e3d99e7 100644
--- a/src/com/android/gallery3d/ui/PhotoView.java
+++ b/src/com/android/gallery3d/ui/PhotoView.java
@@ -225,7 +225,7 @@ public class PhotoView extends GLView {
return;
}
ScreenNailEntry entry = mScreenNails[which];
- entry.set(screenNail);
+ entry.updateScreenNail(screenNail);
}
// -1 previous, 0 current, 1 next
@@ -650,10 +650,8 @@ public class PhotoView extends GLView {
ScreenNailEntry prevNail = mScreenNails[ENTRY_PREVIOUS];
ScreenNailEntry nextNail = mScreenNails[ENTRY_NEXT];
mTileView.invalidateTiles();
- if (prevNail.mScreenNail != null) prevNail.mScreenNail.recycle();
- prevNail.set(mTileView.mScreenNail);
- mTileView.updateScreenNail(nextNail.mScreenNail);
- nextNail.set(null);
+ prevNail.updateScreenNail(mTileView.releaseScreenNail());
+ mTileView.updateScreenNail(nextNail.releaseScreenNail());
mModel.next();
}
@@ -662,10 +660,8 @@ public class PhotoView extends GLView {
ScreenNailEntry prevNail = mScreenNails[ENTRY_PREVIOUS];
ScreenNailEntry nextNail = mScreenNails[ENTRY_NEXT];
mTileView.invalidateTiles();
- if (nextNail.mScreenNail != null) nextNail.mScreenNail.recycle();
- nextNail.set(mTileView.mScreenNail);
- mTileView.updateScreenNail(prevNail.mScreenNail);
- nextNail.set(null);
+ nextNail.updateScreenNail(mTileView.releaseScreenNail());
+ mTileView.updateScreenNail(prevNail.releaseScreenNail());
mModel.previous();
}
@@ -715,10 +711,10 @@ public class PhotoView extends GLView {
private ScreenNail mScreenNail;
- public void set(ScreenNail screenNail) {
+ public void updateScreenNail(ScreenNail screenNail) {
mEnabled = (screenNail != null);
if (mScreenNail == screenNail) return;
- if (mScreenNail != null) mScreenNail.recycle();
+ if (mScreenNail != null) mScreenNail.pauseDraw();
mScreenNail = screenNail;
if (mScreenNail != null) {
mRotation = mScreenNail.getRotation();
@@ -726,6 +722,13 @@ public class PhotoView extends GLView {
}
}
+ // Release the ownership of the ScreenNail from this entry.
+ public ScreenNail releaseScreenNail() {
+ ScreenNail s = mScreenNail;
+ mScreenNail = null;
+ return s;
+ }
+
public void layoutRightEdgeAt(int x) {
mVisible = x > 0;
mOffsetX = x - getRotated(
@@ -767,7 +770,7 @@ public class PhotoView extends GLView {
public void draw(GLCanvas canvas, boolean applyFadingAnimation) {
if (mScreenNail == null) return;
if (!mVisible) {
- mScreenNail.disableDraw();
+ mScreenNail.noDraw();
return;
}
@@ -877,7 +880,7 @@ public class PhotoView extends GLView {
mTransitionMode = TRANS_NONE;
mTileView.freeTextures();
for (ScreenNailEntry entry : mScreenNails) {
- entry.set(null);
+ entry.updateScreenNail(null);
}
}
diff --git a/src/com/android/gallery3d/ui/ScreenNail.java b/src/com/android/gallery3d/ui/ScreenNail.java
index a2377fe2a..58ae8c942 100644
--- a/src/com/android/gallery3d/ui/ScreenNail.java
+++ b/src/com/android/gallery3d/ui/ScreenNail.java
@@ -21,11 +21,9 @@ public interface ScreenNail {
public int getWidth();
public int getHeight();
public int getRotation();
- public void recycle();
public void draw(GLCanvas canvas, int x, int y, int width, int height);
-
- // We need this method to tell ScreenNail to stop displaying.
- public void disableDraw();
+ public void noDraw(); // we do not need to draw this ScreenNail in this frame.
+ public void pauseDraw(); // we do not expect to draw this ScreenNail for some time.
// This is only used by TileImageView to back up the tiles not yet loaded.
public void draw(GLCanvas canvas, RectF source, RectF dest);
diff --git a/src/com/android/gallery3d/ui/ScreenNailHolder.java b/src/com/android/gallery3d/ui/ScreenNailHolder.java
new file mode 100644
index 000000000..a7d541767
--- /dev/null
+++ b/src/com/android/gallery3d/ui/ScreenNailHolder.java
@@ -0,0 +1,31 @@
+/*
+ * 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.os.Parcel;
+import android.os.Parcelable;
+
+public abstract class ScreenNailHolder implements Parcelable {
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel dest, int flags) {
+ }
+
+ public abstract ScreenNail attach();
+ public abstract void detach();
+}
diff --git a/src/com/android/gallery3d/ui/SurfaceTextureScreenNail.java b/src/com/android/gallery3d/ui/SurfaceTextureScreenNail.java
new file mode 100644
index 000000000..3a8f2b0a4
--- /dev/null
+++ b/src/com/android/gallery3d/ui/SurfaceTextureScreenNail.java
@@ -0,0 +1,116 @@
+/*
+ * 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.RectF;
+import android.graphics.SurfaceTexture;
+import android.opengl.GLES11Ext;
+import android.util.Log;
+
+import com.android.gallery3d.ui.GLCanvas;
+import com.android.gallery3d.ui.ScreenNail;
+import com.android.gallery3d.ui.ExtTexture;
+
+public abstract class SurfaceTextureScreenNail implements ScreenNail,
+ SurfaceTexture.OnFrameAvailableListener {
+ private static final String TAG = "SurfaceTextureScreenNail";
+ private ExtTexture mExtTexture;
+ private SurfaceTexture mSurfaceTexture;
+ private int mWidth, mHeight;
+ private float[] mTransform = new float[16];
+ private boolean mHasTexture = false;
+
+ public SurfaceTextureScreenNail() {
+ }
+
+ public void acquireSurfaceTexture() {
+ mExtTexture = new ExtTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES);
+ mExtTexture.setSize(mWidth, mHeight);
+ mSurfaceTexture = new SurfaceTexture(mExtTexture.getId());
+ mSurfaceTexture.setOnFrameAvailableListener(this);
+ synchronized (this) {
+ mHasTexture = true;
+ }
+ }
+
+ public SurfaceTexture getSurfaceTexture() {
+ return mSurfaceTexture;
+ }
+
+ public void releaseSurfaceTexture() {
+ synchronized (this) {
+ mHasTexture = false;
+ }
+ mExtTexture.recycle();
+ mExtTexture = null;
+ mSurfaceTexture.release();
+ mSurfaceTexture = null;
+ }
+
+ public void setSize(int width, int height) {
+ mWidth = width;
+ mHeight = height;
+ }
+
+ @Override
+ public int getWidth() {
+ return mWidth;
+ }
+
+ @Override
+ public int getHeight() {
+ return mHeight;
+ }
+
+ @Override
+ public int getRotation() {
+ return 0;
+ }
+
+ @Override
+ public void draw(GLCanvas canvas, int x, int y, int width, int height) {
+ synchronized (this) {
+ if (!mHasTexture) return;
+ mSurfaceTexture.updateTexImage();
+ mSurfaceTexture.getTransformMatrix(mTransform);
+
+ // Flip vertically.
+ canvas.save(GLCanvas.SAVE_FLAG_MATRIX);
+ int cx = x + width / 2;
+ int cy = y + height / 2;
+ canvas.translate(cx, cy);
+ canvas.scale(1, -1, 1);
+ canvas.translate(-cx, -cy);
+ canvas.drawTexture(mExtTexture, mTransform, x, y, width, height);
+ canvas.restore();
+ }
+ }
+
+ @Override
+ public void draw(GLCanvas canvas, RectF source, RectF dest) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ abstract public void noDraw();
+
+ @Override
+ abstract public void pauseDraw();
+
+ @Override
+ abstract public void onFrameAvailable(SurfaceTexture surfaceTexture);
+}
diff --git a/src/com/android/gallery3d/ui/TileImageView.java b/src/com/android/gallery3d/ui/TileImageView.java
index 638a7f94b..d2ce1677a 100644
--- a/src/com/android/gallery3d/ui/TileImageView.java
+++ b/src/com/android/gallery3d/ui/TileImageView.java
@@ -71,7 +71,7 @@ public class TileImageView extends GLView {
private static final int STATE_RECYCLED = 0x40;
private Model mModel;
- protected ScreenNail mScreenNail;
+ private ScreenNail mScreenNail;
protected int mLevelCount; // cache the value of mScaledBitmaps.length
// The mLevel variable indicates which level of bitmap we should use.
@@ -155,10 +155,16 @@ public class TileImageView extends GLView {
public void updateScreenNail(ScreenNail s) {
if (mScreenNail == s) return;
- if (mScreenNail != null) mScreenNail.recycle();
+ if (mScreenNail != null) mScreenNail.pauseDraw();
mScreenNail = s;
}
+ public ScreenNail releaseScreenNail() {
+ ScreenNail s = mScreenNail;
+ mScreenNail = null;
+ return s;
+ }
+
public void notifyModelInvalidated() {
invalidateTiles();
if (mModel == null) {
@@ -421,7 +427,7 @@ public class TileImageView extends GLView {
try {
if (level != mLevelCount) {
if (mScreenNail != null) {
- mScreenNail.disableDraw();
+ mScreenNail.noDraw();
}
int size = (TILE_SIZE << level);
diff --git a/src/com/android/gallery3d/ui/UploadedTexture.java b/src/com/android/gallery3d/ui/UploadedTexture.java
index c4d8d82f8..85aa1c4b2 100644
--- a/src/com/android/gallery3d/ui/UploadedTexture.java
+++ b/src/com/android/gallery3d/ui/UploadedTexture.java
@@ -228,7 +228,7 @@ abstract class UploadedTexture extends BasicTexture {
sCropRect[3] = -bHeight;
// Upload the bitmap to a new texture.
- gl.glGenTextures(1, sTextureId, 0);
+ 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);
@@ -299,6 +299,11 @@ abstract class UploadedTexture extends BasicTexture {
return isContentValid(canvas);
}
+ @Override
+ protected int getTarget() {
+ return GL11.GL_TEXTURE_2D;
+ }
+
public void setOpaque(boolean isOpaque) {
mOpaque = isOpaque;
}
diff --git a/tests/src/com/android/gallery3d/ui/GLCanvasStub.java b/tests/src/com/android/gallery3d/ui/GLCanvasStub.java
index 70fef1a1c..ee43cb943 100644
--- a/tests/src/com/android/gallery3d/ui/GLCanvasStub.java
+++ b/tests/src/com/android/gallery3d/ui/GLCanvasStub.java
@@ -57,6 +57,8 @@ public class GLCanvasStub implements GLCanvas {
public void drawTexture(BasicTexture texture,
int x, int y, int width, int height, float alpha) {}
public void drawTexture(BasicTexture texture, RectF source, RectF target) {}
+ public void drawTexture(BasicTexture texture, float[] mTextureTransform,
+ int x, int y, int w, int h) {}
public void drawMixed(BasicTexture from, BasicTexture to,
float ratio, int x, int y, int w, int h) {}
public void drawMixed(BasicTexture from, int to,
diff --git a/tests/src/com/android/gallery3d/ui/TextureTest.java b/tests/src/com/android/gallery3d/ui/TextureTest.java
index 821d49bb1..be2356c8e 100644
--- a/tests/src/com/android/gallery3d/ui/TextureTest.java
+++ b/tests/src/com/android/gallery3d/ui/TextureTest.java
@@ -43,6 +43,11 @@ public class TextureTest extends TestCase {
return true;
}
+ @Override
+ protected int getTarget() {
+ return GL11.GL_TEXTURE_2D;
+ }
+
public boolean isOpaque() {
mOpaqueCalled++;
return true;
@@ -171,6 +176,11 @@ public class TextureTest extends TestCase {
return true;
}
+ @Override
+ protected int getTarget() {
+ return GL11.GL_TEXTURE_2D;
+ }
+
public boolean isOpaque() {
return true;
}