1b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang/* 2b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang * Copyright (C) 2012 The Android Open Source Project 3b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang * 4b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang * Licensed under the Apache License, Version 2.0 (the "License"); 5b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang * you may not use this file except in compliance with the License. 6b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang * You may obtain a copy of the License at 7b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang * 8b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang * http://www.apache.org/licenses/LICENSE-2.0 9b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang * 10b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang * Unless required by applicable law or agreed to in writing, software 11b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang * distributed under the License is distributed on an "AS IS" BASIS, 12b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang * See the License for the specific language governing permissions and 14b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang * limitations under the License. 15b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang */ 16b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang 17b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Changpackage com.android.gallery3d.ui; 18b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang 196772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Changimport android.annotation.TargetApi; 20b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Changimport android.graphics.RectF; 21b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Changimport android.graphics.SurfaceTexture; 22b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang 236772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Changimport com.android.gallery3d.common.ApiHelper; 24a4eae1abb4f2547dfbda84301ee764ce35464881John Reckimport com.android.gallery3d.glrenderer.ExtTexture; 25a4eae1abb4f2547dfbda84301ee764ce35464881John Reckimport com.android.gallery3d.glrenderer.GLCanvas; 266772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang 27a9fb0f51165bf1ba8287f4abaf5319efaf2cae84Wu-cheng Li@TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB) 28b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Changpublic abstract class SurfaceTextureScreenNail implements ScreenNail, 29b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang SurfaceTexture.OnFrameAvailableListener { 307817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @SuppressWarnings("unused") 31b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang private static final String TAG = "SurfaceTextureScreenNail"; 326772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang // This constant is not available in API level before 15, but it was just an 336772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang // oversight. 346772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang private static final int GL_TEXTURE_EXTERNAL_OES = 0x8D65; 356772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang 36ffc2a4a77f7164dd435d07c11a3df290c4b64079Angus Kong protected ExtTexture mExtTexture; 37b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang private SurfaceTexture mSurfaceTexture; 38b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang private int mWidth, mHeight; 39b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang private float[] mTransform = new float[16]; 40b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang private boolean mHasTexture = false; 41b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang 42b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang public SurfaceTextureScreenNail() { 43b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang } 44b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang 4550b33abe053ccab7be3d1bca2328e792507963d4George Mount public void acquireSurfaceTexture(GLCanvas canvas) { 4650b33abe053ccab7be3d1bca2328e792507963d4George Mount mExtTexture = new ExtTexture(canvas, GL_TEXTURE_EXTERNAL_OES); 47b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang mExtTexture.setSize(mWidth, mHeight); 48b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang mSurfaceTexture = new SurfaceTexture(mExtTexture.getId()); 496772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang setDefaultBufferSize(mSurfaceTexture, mWidth, mHeight); 50b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang mSurfaceTexture.setOnFrameAvailableListener(this); 51b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang synchronized (this) { 52b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang mHasTexture = true; 53b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang } 54b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang } 55b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang 566772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) 576772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang private static void setDefaultBufferSize(SurfaceTexture st, int width, int height) { 586772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang if (ApiHelper.HAS_SET_DEFALT_BUFFER_SIZE) { 596772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang st.setDefaultBufferSize(width, height); 606772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang } 616772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang } 626772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang 63840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH) 64840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang private static void releaseSurfaceTexture(SurfaceTexture st) { 6571ba6e959569cb90f415490e40bd95855f894cc5John Reck st.setOnFrameAvailableListener(null); 66840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang if (ApiHelper.HAS_RELEASE_SURFACE_TEXTURE) { 67840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang st.release(); 68840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang } 69840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang } 70840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang 71b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang public SurfaceTexture getSurfaceTexture() { 72b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang return mSurfaceTexture; 73b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang } 74b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang 75b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang public void releaseSurfaceTexture() { 76b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang synchronized (this) { 77b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang mHasTexture = false; 78b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang } 79b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang mExtTexture.recycle(); 80b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang mExtTexture = null; 81840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang releaseSurfaceTexture(mSurfaceTexture); 82b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang mSurfaceTexture = null; 83b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang } 84b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang 85b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang public void setSize(int width, int height) { 86b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang mWidth = width; 87b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang mHeight = height; 88b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang } 89b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang 90b6d494925ea14a02ef75f58d5d969d7586914ef7George Mount public void resizeTexture() { 91b6d494925ea14a02ef75f58d5d969d7586914ef7George Mount if (mExtTexture != null) { 92b6d494925ea14a02ef75f58d5d969d7586914ef7George Mount mExtTexture.setSize(mWidth, mHeight); 93b6d494925ea14a02ef75f58d5d969d7586914ef7George Mount setDefaultBufferSize(mSurfaceTexture, mWidth, mHeight); 94b6d494925ea14a02ef75f58d5d969d7586914ef7George Mount } 95b6d494925ea14a02ef75f58d5d969d7586914ef7George Mount } 96b6d494925ea14a02ef75f58d5d969d7586914ef7George Mount 97b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang @Override 98b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang public int getWidth() { 99b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang return mWidth; 100b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang } 101b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang 102b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang @Override 103b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang public int getHeight() { 104b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang return mHeight; 105b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang } 106b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang 107b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang @Override 108b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang public void draw(GLCanvas canvas, int x, int y, int width, int height) { 109b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang synchronized (this) { 110b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang if (!mHasTexture) return; 111b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang mSurfaceTexture.updateTexImage(); 112b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang mSurfaceTexture.getTransformMatrix(mTransform); 113b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang 114b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang // Flip vertically. 115b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang canvas.save(GLCanvas.SAVE_FLAG_MATRIX); 116b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang int cx = x + width / 2; 117b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang int cy = y + height / 2; 118b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang canvas.translate(cx, cy); 119b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang canvas.scale(1, -1, 1); 120b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang canvas.translate(-cx, -cy); 1214ce48412b86ac28042bf70e4cbe051ffc3dd489dJohn Reck updateTransformMatrix(mTransform); 122b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang canvas.drawTexture(mExtTexture, mTransform, x, y, width, height); 123b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang canvas.restore(); 124b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang } 125b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang } 126b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang 127b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang @Override 128b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang public void draw(GLCanvas canvas, RectF source, RectF dest) { 129b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang throw new UnsupportedOperationException(); 130b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang } 131b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang 1324ce48412b86ac28042bf70e4cbe051ffc3dd489dJohn Reck protected void updateTransformMatrix(float[] matrix) {} 1334ce48412b86ac28042bf70e4cbe051ffc3dd489dJohn Reck 134b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang @Override 135b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang abstract public void noDraw(); 136b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang 137b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang @Override 138b8be1e0ad76b6abc0da7ead39f7a9811195d001eChih-Chung Chang abstract public void recycle(); 139b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang 140b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang @Override 141b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang abstract public void onFrameAvailable(SurfaceTexture surfaceTexture); 142b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang} 143