SurfaceTextureScreenNail.java revision 840ae396bac4ff8ff34e88c8d2a1773cb112a4b6
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 Changimport android.opengl.GLES11Ext;
23b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang
246772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Changimport com.android.gallery3d.common.ApiHelper;
256772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang
26b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Changpublic abstract class SurfaceTextureScreenNail implements ScreenNail,
27b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang        SurfaceTexture.OnFrameAvailableListener {
28b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    private static final String TAG = "SurfaceTextureScreenNail";
296772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang    // This constant is not available in API level before 15, but it was just an
306772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang    // oversight.
316772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang    private static final int GL_TEXTURE_EXTERNAL_OES = 0x8D65;
326772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang
33ffc2a4a77f7164dd435d07c11a3df290c4b64079Angus Kong    protected ExtTexture mExtTexture;
34b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    private SurfaceTexture mSurfaceTexture;
35b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    private int mWidth, mHeight;
36b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    private float[] mTransform = new float[16];
37b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    private boolean mHasTexture = false;
38b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang
39b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    public SurfaceTextureScreenNail() {
40b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    }
41b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang
42b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    public void acquireSurfaceTexture() {
436772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang        mExtTexture = new ExtTexture(GL_TEXTURE_EXTERNAL_OES);
44b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang        mExtTexture.setSize(mWidth, mHeight);
45b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang        mSurfaceTexture = new SurfaceTexture(mExtTexture.getId());
466772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang        setDefaultBufferSize(mSurfaceTexture, mWidth, mHeight);
47b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang        mSurfaceTexture.setOnFrameAvailableListener(this);
48b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang        synchronized (this) {
49b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang            mHasTexture = true;
50b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang        }
51b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    }
52b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang
536772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang    @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
546772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang    private static void setDefaultBufferSize(SurfaceTexture st, int width, int height) {
556772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang        if (ApiHelper.HAS_SET_DEFALT_BUFFER_SIZE) {
566772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang            st.setDefaultBufferSize(width, height);
576772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang        }
586772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang    }
596772173d2a49b87a1d209f42fe52b5f830596f99Chih-Chung Chang
60840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang    @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
61840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang    private static void releaseSurfaceTexture(SurfaceTexture st) {
62840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang        if (ApiHelper.HAS_RELEASE_SURFACE_TEXTURE) {
63840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang            st.release();
64840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang        }
65840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang    }
66840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang
67b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    public SurfaceTexture getSurfaceTexture() {
68b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang        return mSurfaceTexture;
69b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    }
70b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang
71b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    public void releaseSurfaceTexture() {
72b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang        synchronized (this) {
73b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang            mHasTexture = false;
74b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang        }
75b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang        mExtTexture.recycle();
76b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang        mExtTexture = null;
77840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang        releaseSurfaceTexture(mSurfaceTexture);
78b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang        mSurfaceTexture = null;
79b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    }
80b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang
81b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    public void setSize(int width, int height) {
82b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang        mWidth = width;
83b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang        mHeight = height;
84b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    }
85b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang
86b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    @Override
87b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    public int getWidth() {
88b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang        return mWidth;
89b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    }
90b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang
91b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    @Override
92b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    public int getHeight() {
93b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang        return mHeight;
94b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    }
95b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang
96b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    @Override
97b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    public void draw(GLCanvas canvas, int x, int y, int width, int height) {
98b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang        synchronized (this) {
99b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang            if (!mHasTexture) return;
100b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang            mSurfaceTexture.updateTexImage();
101b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang            mSurfaceTexture.getTransformMatrix(mTransform);
102b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang
103b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang            // Flip vertically.
104b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang            canvas.save(GLCanvas.SAVE_FLAG_MATRIX);
105b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang            int cx = x + width / 2;
106b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang            int cy = y + height / 2;
107b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang            canvas.translate(cx, cy);
108b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang            canvas.scale(1, -1, 1);
109b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang            canvas.translate(-cx, -cy);
110b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang            canvas.drawTexture(mExtTexture, mTransform, x, y, width, height);
111b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang            canvas.restore();
112b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang        }
113b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    }
114b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang
115b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    @Override
116b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    public void draw(GLCanvas canvas, RectF source, RectF dest) {
117b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang        throw new UnsupportedOperationException();
118b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    }
119b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang
120b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    @Override
121b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    abstract public void noDraw();
122b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang
123b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    @Override
124b8be1e0ad76b6abc0da7ead39f7a9811195d001eChih-Chung Chang    abstract public void recycle();
125b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang
126b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    @Override
127b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang    abstract public void onFrameAvailable(SurfaceTexture surfaceTexture);
128b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang}
129