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

Commit a9489274 authored by Romain Guy's avatar Romain Guy
Browse files

Add the ability to specify the opacity of a TextureView

TextureView assumes its content is opaque by default.

Change-Id: Iba873423566a5b67c388081838bd910dceba32ba
parent d586ad9c
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -161,10 +161,11 @@ class GLES20Canvas extends HardwareCanvas {
    // Hardware layers
    ///////////////////////////////////////////////////////////////////////////
    
    static native int nCreateTextureLayer(int[] layerInfo);
    static native int nCreateTextureLayer(boolean opaque, int[] layerInfo);
    static native int nCreateLayer(int width, int height, boolean isOpaque, int[] layerInfo);
    static native void nResizeLayer(int layerId, int width, int height, int[] layerInfo);
    static native void nUpdateTextureLayer(int layerId, int width, int height, SurfaceTexture surface);
    static native void nUpdateTextureLayer(int layerId, int width, int height, boolean opaque,
            SurfaceTexture surface);
    static native void nDestroyLayer(int layerId);
    static native void nDestroyLayerDeferred(int layerId);
    static native boolean nCopyLayer(int layerId, int bitmap);
+4 −4
Original line number Diff line number Diff line
@@ -28,9 +28,9 @@ class GLES20TextureLayer extends GLES20Layer {
    private int mTexture;
    private SurfaceTexture mSurface;

    GLES20TextureLayer() {
    GLES20TextureLayer(boolean isOpaque) {
        int[] layerInfo = new int[2];
        mLayer = GLES20Canvas.nCreateTextureLayer(layerInfo);
        mLayer = GLES20Canvas.nCreateTextureLayer(isOpaque, layerInfo);

        if (mLayer != 0) {
            mTexture = layerInfo[0];
@@ -70,7 +70,7 @@ class GLES20TextureLayer extends GLES20Layer {
        return mSurface;
    }

    void update(int width, int height) {
        GLES20Canvas.nUpdateTextureLayer(mLayer, width, height, mSurface);
    void update(int width, int height, boolean isOpaque) {
        GLES20Canvas.nUpdateTextureLayer(mLayer, width, height, isOpaque, mSurface);
    }
}
+9 −6
Original line number Diff line number Diff line
@@ -170,9 +170,11 @@ public abstract class HardwareRenderer {
     * Creates a new hardware layer. A hardware layer built by calling this
     * method will be treated as a texture layer, instead of as a render target.
     * 
     * @param isOpaque Whether the layer should be opaque or not
     * 
     * @return A hardware layer
     */    
    abstract HardwareLayer createHardwareLayer();
    abstract HardwareLayer createHardwareLayer(boolean isOpaque);
    
    /**
     * Creates a new hardware layer.
@@ -202,8 +204,9 @@ public abstract class HardwareRenderer {
     * @param layer The hardware layer to update
     * @param width The layer's width
     * @param height The layer's height
     * @param isOpaque Whether the layer is opaque
     */
    abstract void updateTextureLayer(HardwareLayer layer, int width, int height);
    abstract void updateTextureLayer(HardwareLayer layer, int width, int height, boolean isOpaque);

    /**
     * Copies the content of the specified layer into the specified bitmap.
@@ -803,8 +806,8 @@ public abstract class HardwareRenderer {
        }

        @Override
        HardwareLayer createHardwareLayer() {
            return new GLES20TextureLayer();
        HardwareLayer createHardwareLayer(boolean isOpaque) {
            return new GLES20TextureLayer(isOpaque);
        }

        @Override
@@ -818,8 +821,8 @@ public abstract class HardwareRenderer {
        }

        @Override
        void updateTextureLayer(HardwareLayer layer, int width, int height) {
            ((GLES20TextureLayer) layer).update(width, height);
        void updateTextureLayer(HardwareLayer layer, int width, int height, boolean isOpaque) {
            ((GLES20TextureLayer) layer).update(width, height, isOpaque);
        }

        @Override
+42 −20
Original line number Diff line number Diff line
@@ -96,9 +96,14 @@ public class TextureView extends View {
    private SurfaceTexture mSurface;
    private SurfaceTextureListener mListener;

    private final Object[] mLock = new Object[0];
    private boolean mUpdateLayer;
    private boolean mOpaque = true;

    private final Runnable mUpdateLayerAction = new Runnable() {
        @Override
        public void run() {
            updateLayer();
        }
    };
    private SurfaceTexture.OnFrameAvailableListener mUpdateListener;

    /**
@@ -143,6 +148,28 @@ public class TextureView extends View {
        mLayerPaint = new Paint();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isOpaque() {
        return mOpaque;
    }

    /**
     * Indicates whether the content of this TextureView is opaque. The
     * content is assumed to be opaque by default.
     * 
     * @param opaque True if the content of this TextureView is opaque,
     *               false otherwise
     */
    public void setOpaque(boolean opaque) {
        if (opaque != mOpaque) {
            mOpaque = opaque;
            updateLayer();
        }
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
@@ -212,7 +239,6 @@ public class TextureView extends View {
     */
    @Override
    public final void draw(Canvas canvas) {
        super.draw(canvas);
    }

    /**
@@ -229,8 +255,6 @@ public class TextureView extends View {
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (mSurface != null) {
            // No need to synchronize here, we set update layer to false only on the UI thread
            mUpdateLayer = true;
            nSetDefaultBufferSize(mSurface, getWidth(), getHeight());
            if (mListener != null) {
                mListener.onSurfaceTextureSizeChanged(mSurface, getWidth(), getHeight());
@@ -245,7 +269,7 @@ public class TextureView extends View {
        }

        if (mLayer == null) {
            mLayer = mAttachInfo.mHardwareRenderer.createHardwareLayer();
            mLayer = mAttachInfo.mHardwareRenderer.createHardwareLayer(mOpaque);
            mSurface = mAttachInfo.mHardwareRenderer.createSurfaceTexture(mLayer);
            nSetDefaultBufferSize(mSurface, getWidth(), getHeight());

@@ -254,10 +278,7 @@ public class TextureView extends View {
                public void onFrameAvailable(SurfaceTexture surfaceTexture) {
                    // Per SurfaceTexture's documentation, the callback may be invoked
                    // from an arbitrary thread
                    synchronized (mLock) {
                        mUpdateLayer = true;
                        postInvalidate();
                    }
                    post(mUpdateLayerAction);
                }
            };
            mSurface.setOnFrameAvailableListener(mUpdateListener);
@@ -267,13 +288,6 @@ public class TextureView extends View {
            }
        }

        synchronized (mLock) {
            if (mUpdateLayer) {
                mAttachInfo.mHardwareRenderer.updateTextureLayer(mLayer, getWidth(), getHeight());
                mUpdateLayer = false;
            }
        }

        return mLayer;
    }

@@ -287,15 +301,23 @@ public class TextureView extends View {
            // updates listener
            if (visibility == VISIBLE) {
                mSurface.setOnFrameAvailableListener(mUpdateListener);
                // No need to synchronize here, we set update layer to false only on the UI thread
                mUpdateLayer = true;
                invalidate();
                updateLayer();
            } else {
                mSurface.setOnFrameAvailableListener(null);
            }
        }
    }

    private void updateLayer() {
        if (mAttachInfo == null || mAttachInfo.mHardwareRenderer == null) {
            return;
        }

        mAttachInfo.mHardwareRenderer.updateTextureLayer(mLayer, getWidth(), getHeight(), mOpaque);

        invalidate();
    }

    /**
     * <p>Returns a {@link android.graphics.Bitmap} representation of the content
     * of the associated surface texture. If the surface texture is not available,
+1 −1
Original line number Diff line number Diff line
@@ -9674,10 +9674,10 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
                computeScroll();
                canvas.translate(-mScrollX, -mScrollY);
                mPrivateFlags |= DRAWN | DRAWING_CACHE_VALID;
                mPrivateFlags &= ~DIRTY_MASK;

                // Fast path for layouts with no backgrounds
                if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
                    mPrivateFlags &= ~DIRTY_MASK;
                    dispatchDraw(canvas);
                } else {
                    draw(canvas);
Loading