Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ffc2a4a7 authored by Angus Kong's avatar Angus Kong
Browse files

Add Raw2DTexture.

Raw2DTexture is a wrapper of GL 2D texture. It also support copy other
texture's content into this texture.

bug:5988937

Change-Id: Ib4f6ff7ed2f6ea499517536366b511b7984a9b98
parent 3fb40bd6
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package com.android.gallery3d.ui;

import android.graphics.SurfaceTexture;
import javax.microedition.khronos.opengles.GL11;
import javax.microedition.khronos.opengles.GL11Ext;

+6 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.gallery3d.ui;

import javax.microedition.khronos.opengles.GL11;
import javax.microedition.khronos.opengles.GL11ExtensionPack;

// This mimics corresponding GL functions.
public class GLId {
@@ -41,4 +42,9 @@ public class GLId {
    public synchronized static void glDeleteBuffers(GL11 gl, int n, int[] buffers, int offset) {
        gl.glDeleteBuffers(n, buffers, offset);
    }

    public synchronized static void glDeleteFramebuffers(
            GL11ExtensionPack gl11ep, int n, int[] buffers, int offset) {
        gl11ep.glDeleteFramebuffersOES(n, buffers, offset);
    }
}
+172 −0
Original line number Diff line number Diff line
/*
 * 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.opengl.GLU;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL11;
import javax.microedition.khronos.opengles.GL11Ext;
import javax.microedition.khronos.opengles.GL11ExtensionPack;

/**
 * A wrapper class of GL 2D texture.
 */
public class Raw2DTexture extends BasicTexture {
    private static final int[] sTextureId = new int[1];
    // OpenGL related fields used when copy.
    private static final int[] sBufferName = new int[1];
    private int mFBO;  // Frame buffer object.

    // We need copy from another texture when in camera capture animation.
    // The copy is done through a framebuffer object with an attached
    // destination texture. The source texture is rendered to the framebuffer
    // and the data will be stored in the destination texture.
    public static void copy(GLCanvas canvas, BasicTexture src, Raw2DTexture dst) {
        int[] viewPort = new int[4];
        GL11 gl11 = canvas.getGLInstance();
        GL11ExtensionPack gl11ep = (GL11ExtensionPack) gl11;

        if (!dst.isLoaded(canvas)) {
            dst.prepare(canvas.getGLInstance());
        }

        gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, dst.mFBO);
        gl11ep.glFramebufferTexture2DOES(
                GL11ExtensionPack.GL_FRAMEBUFFER_OES,
                GL11ExtensionPack.GL_COLOR_ATTACHMENT0_OES,
                GL11.GL_TEXTURE_2D,
                dst.getId(), 0);
        checkFramebufferStatus(gl11ep);

        // Draw the source onto our destination.
        // The texture coords and vertex pointer are already set properly. We don't
        // need to set again.
        gl11.glBindTexture(src.getTarget(), src.getId());
        boolean targetEnabled = gl11.glIsEnabled(src.getTarget());
        gl11.glEnable(src.getTarget());
        boolean scissorEnabled = gl11.glIsEnabled(GL11.GL_SCISSOR_TEST);
        gl11.glDisable(GL11.GL_SCISSOR_TEST);

        // Set the texture matrix.
        gl11.glMatrixMode(GL11.GL_TEXTURE);
        gl11.glPushMatrix();
        gl11.glLoadIdentity();

        // Set the view port.
        gl11.glGetIntegerv(GL11.GL_VIEWPORT, viewPort, 0);
        gl11.glViewport(0, 0, dst.getTextureWidth(), dst.getTextureHeight());

        // Set the projection matrix.
        gl11.glMatrixMode(GL11.GL_PROJECTION);
        gl11.glPushMatrix();
        gl11.glLoadIdentity();
        GLU.gluOrtho2D(gl11, 0, 1, 0, 1);

        // Set the modelview matrix.
        gl11.glMatrixMode(GL11.GL_MODELVIEW);
        gl11.glPushMatrix();
        gl11.glLoadIdentity();

        // Draw the texture.
        gl11.glDrawArrays(GL11.GL_TRIANGLE_STRIP, 0, 4);

        // Clear.
        if (!targetEnabled) gl11.glDisable(src.getTarget());
        if (scissorEnabled) gl11.glEnable(GL11.GL_SCISSOR_TEST);
        gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, 0);
        gl11.glBindTexture(src.getTarget(), 0);
        gl11.glViewport(viewPort[0], viewPort[1], viewPort[2], viewPort[3]);
        gl11.glMatrixMode(GL11.GL_TEXTURE);
        gl11.glPopMatrix();
        gl11.glMatrixMode(GL11.GL_PROJECTION);
        gl11.glPopMatrix();
        gl11.glMatrixMode(GL11.GL_MODELVIEW);
        gl11.glPopMatrix();
        GLId.glDeleteFramebuffers(gl11ep, 1, dst.sBufferName, 0);
    }

    public Raw2DTexture(int w, int h) {
        setSize(w, h);
        GLId.glGenTextures(1, sTextureId, 0);
        mId = sTextureId[0];
        GLId.glGenBuffers(1, sBufferName, 0);
        mFBO = sBufferName[0];
    }

    private void prepare(GL11 gl11) {
        gl11.glBindTexture(GL11.GL_TEXTURE_2D, mId);
        gl11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP_TO_EDGE);
        gl11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP_TO_EDGE);
        gl11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
        gl11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
        gl11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA,
                getTextureWidth(), getTextureHeight(),
                0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, null);
        gl11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
        mState = UploadedTexture.STATE_LOADED;
    }

    @Override
    protected boolean onBind(GLCanvas canvas) {
        if (!isLoaded(canvas)) {
            return false;
        }

        return true;
    }

    @Override
    public int getTarget() {
        return GL11.GL_TEXTURE_2D;
    }

    public boolean isOpaque() {
        return true;
    }

    @Override
    public void yield() {
        // we cannot free the texture because we have no backup.
    }

    private static void checkFramebufferStatus(GL11ExtensionPack gl11ep) {
        int status = gl11ep.glCheckFramebufferStatusOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES);
        if (status != GL11ExtensionPack.GL_FRAMEBUFFER_COMPLETE_OES) {
            String msg = "";
            switch (status) {
                case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES:
                    msg = "FRAMEBUFFER_FORMATS"; break;
                case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES:
                    msg = "FRAMEBUFFER_ATTACHMENT"; break;
                case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES:
                    msg = "FRAMEBUFFER_MISSING_ATTACHMENT"; break;
                case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES:
                    msg = "FRAMEBUFFER_DRAW_BUFFER"; break;
                case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES:
                    msg = "FRAMEBUFFER_READ_BUFFER"; break;
                case GL11ExtensionPack.GL_FRAMEBUFFER_UNSUPPORTED_OES:
                    msg = "FRAMEBUFFER_UNSUPPORTED"; break;
                case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES:
                    msg = "FRAMEBUFFER_INCOMPLETE_DIMENSIONS"; break;
            }
            throw new RuntimeException(msg + ":" + Integer.toHexString(status));
        }
    }
}
+1 −6
Original line number Diff line number Diff line
@@ -19,16 +19,11 @@ 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;
    protected ExtTexture mExtTexture;
    private SurfaceTexture mSurfaceTexture;
    private int mWidth, mHeight;
    private float[] mTransform = new float[16];