1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.gallery3d.ui; 18 19 import android.annotation.TargetApi; 20 import android.graphics.RectF; 21 import android.graphics.SurfaceTexture; 22 23 import com.android.gallery3d.common.ApiHelper; 24 import com.android.gallery3d.glrenderer.ExtTexture; 25 import com.android.gallery3d.glrenderer.GLCanvas; 26 27 @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB) 28 public abstract class SurfaceTextureScreenNail implements ScreenNail, 29 SurfaceTexture.OnFrameAvailableListener { 30 @SuppressWarnings("unused") 31 private static final String TAG = "SurfaceTextureScreenNail"; 32 // This constant is not available in API level before 15, but it was just an 33 // oversight. 34 private static final int GL_TEXTURE_EXTERNAL_OES = 0x8D65; 35 36 protected ExtTexture mExtTexture; 37 private SurfaceTexture mSurfaceTexture; 38 private int mWidth, mHeight; 39 private float[] mTransform = new float[16]; 40 private boolean mHasTexture = false; 41 42 public SurfaceTextureScreenNail() { 43 } 44 45 public void acquireSurfaceTexture(GLCanvas canvas) { 46 mExtTexture = new ExtTexture(canvas, GL_TEXTURE_EXTERNAL_OES); 47 mExtTexture.setSize(mWidth, mHeight); 48 mSurfaceTexture = new SurfaceTexture(mExtTexture.getId()); 49 setDefaultBufferSize(mSurfaceTexture, mWidth, mHeight); 50 mSurfaceTexture.setOnFrameAvailableListener(this); 51 synchronized (this) { 52 mHasTexture = true; 53 } 54 } 55 56 @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) 57 private static void setDefaultBufferSize(SurfaceTexture st, int width, int height) { 58 if (ApiHelper.HAS_SET_DEFALT_BUFFER_SIZE) { 59 st.setDefaultBufferSize(width, height); 60 } 61 } 62 63 @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH) 64 private static void releaseSurfaceTexture(SurfaceTexture st) { 65 st.setOnFrameAvailableListener(null); 66 if (ApiHelper.HAS_RELEASE_SURFACE_TEXTURE) { 67 st.release(); 68 } 69 } 70 71 public SurfaceTexture getSurfaceTexture() { 72 return mSurfaceTexture; 73 } 74 75 public void releaseSurfaceTexture() { 76 synchronized (this) { 77 mHasTexture = false; 78 } 79 mExtTexture.recycle(); 80 mExtTexture = null; 81 releaseSurfaceTexture(mSurfaceTexture); 82 mSurfaceTexture = null; 83 } 84 85 public void setSize(int width, int height) { 86 mWidth = width; 87 mHeight = height; 88 } 89 90 public void resizeTexture() { 91 if (mExtTexture != null) { 92 mExtTexture.setSize(mWidth, mHeight); 93 setDefaultBufferSize(mSurfaceTexture, mWidth, mHeight); 94 } 95 } 96 97 @Override 98 public int getWidth() { 99 return mWidth; 100 } 101 102 @Override 103 public int getHeight() { 104 return mHeight; 105 } 106 107 @Override 108 public void draw(GLCanvas canvas, int x, int y, int width, int height) { 109 synchronized (this) { 110 if (!mHasTexture) return; 111 mSurfaceTexture.updateTexImage(); 112 mSurfaceTexture.getTransformMatrix(mTransform); 113 114 // Flip vertically. 115 canvas.save(GLCanvas.SAVE_FLAG_MATRIX); 116 int cx = x + width / 2; 117 int cy = y + height / 2; 118 canvas.translate(cx, cy); 119 canvas.scale(1, -1, 1); 120 canvas.translate(-cx, -cy); 121 updateTransformMatrix(mTransform); 122 canvas.drawTexture(mExtTexture, mTransform, x, y, width, height); 123 canvas.restore(); 124 } 125 } 126 127 @Override 128 public void draw(GLCanvas canvas, RectF source, RectF dest) { 129 throw new UnsupportedOperationException(); 130 } 131 132 protected void updateTransformMatrix(float[] matrix) {} 133 134 @Override 135 abstract public void noDraw(); 136 137 @Override 138 abstract public void recycle(); 139 140 @Override 141 abstract public void onFrameAvailable(SurfaceTexture surfaceTexture); 142 } 143