Home | History | Annotate | Download | only in ui
      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