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

Commit d139a0ca authored by Romain Guy's avatar Romain Guy Committed by Android (Google) Code Review
Browse files

Merge "Better backend for hardware layers." into honeycomb

parents d345505a 6c319ca1
Loading
Loading
Loading
Loading
+56 −2
Original line number Diff line number Diff line
@@ -73,10 +73,22 @@ class GLES20Canvas extends HardwareCanvas {
    // Constructors
    ///////////////////////////////////////////////////////////////////////////

    /**
     * Creates a canvas to render directly on screen.
     */
    GLES20Canvas(boolean translucent) {
        this(false, translucent);
    }

    /**
     * Creates a canvas to render into an FBO.
     */
    GLES20Canvas(int fbo, boolean translucent) {
        mOpaque = !translucent;
        mRenderer = nCreateLayerRenderer(fbo);
        setupFinalizer();
    }
    
    protected GLES20Canvas(boolean record, boolean translucent) {
        mOpaque = !translucent;

@@ -90,6 +102,10 @@ class GLES20Canvas extends HardwareCanvas {
            mRenderer = nCreateRenderer();
        }

        setupFinalizer();
    }

    private void setupFinalizer() {
        if (mRenderer == 0) {
            throw new IllegalStateException("Could not create GLES20Canvas renderer");
        } else {
@@ -97,7 +113,8 @@ class GLES20Canvas extends HardwareCanvas {
        }
    }

    private native int nCreateRenderer();
    private static native int nCreateRenderer();
    private static native int nCreateLayerRenderer(int fbo);
    private static native int nGetDisplayListRenderer(int renderer);
    private static native void nDestroyRenderer(int renderer);

@@ -135,6 +152,15 @@ class GLES20Canvas extends HardwareCanvas {
        }
    }

    ///////////////////////////////////////////////////////////////////////////
    // Hardware layers
    ///////////////////////////////////////////////////////////////////////////
    
    static native int nCreateLayer(int width, int height, int[] layerInfo);
    static native void nResizeLayer(int layerId, int layerTextureId, int width, int height,
            int[] layerInfo);
    static native void nDestroyLayer(int layerId, int layerTextureId);    
    
    ///////////////////////////////////////////////////////////////////////////
    // Canvas management
    ///////////////////////////////////////////////////////////////////////////
@@ -226,6 +252,34 @@ class GLES20Canvas extends HardwareCanvas {

    private native void nDrawDisplayList(int renderer, int displayList);

    ///////////////////////////////////////////////////////////////////////////
    // Hardware layer
    ///////////////////////////////////////////////////////////////////////////
    
    void drawHardwareLayer(float left, float top, float right, float bottom,
            HardwareLayer layer, Paint paint) {
        final GLES20Layer glLayer = (GLES20Layer) layer;
        boolean hasColorFilter = paint != null && setupColorFilter(paint);
        final int nativePaint = paint == null ? 0 : paint.mNativePaint;
        nDrawLayer(mRenderer, left, top, right, bottom, glLayer.mLayerTextureId,
                glLayer.getU(), glLayer.getV(), nativePaint);
        if (hasColorFilter) nResetModifiers(mRenderer);
    }

    private native void nDrawLayer(int renderer, float left, float top, float right, float bottom,
            int layerTexture, float u, float v, int paint);
    
    void interrupt() {
        nInterrupt(mRenderer);
    }
    
    void resume() {
        nResume(mRenderer);
    }

    private native void nInterrupt(int renderer);
    private native void nResume(int renderer);

    ///////////////////////////////////////////////////////////////////////////
    // Clipping
    ///////////////////////////////////////////////////////////////////////////
+5 −1
Original line number Diff line number Diff line
@@ -106,7 +106,11 @@ class GLES20DisplayList extends DisplayList {

        @Override
        protected void finalize() throws Throwable {
            try {
                replaceNativeObject(0);
            } finally {
                super.finalize();
            }
        }
    }
}
+143 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2011 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 android.view;

import android.graphics.Canvas;

/**
 * An OpenGL ES 2.0 implementation of {@link HardwareLayer}.
 */
class GLES20Layer extends HardwareLayer {
    private int mLayerId;
    int mLayerTextureId;

    private int mLayerWidth;
    private int mLayerHeight;

    private final GLES20Canvas mCanvas;

    private float mU;
    private float mV;

    @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
    private final Finalizer mFinalizer;

    GLES20Layer(int width, int height, boolean isOpaque) {
        super(width, height, isOpaque);

        int[] layerInfo = new int[3];
        mLayerId = GLES20Canvas.nCreateLayer(width, height, layerInfo);
        if (mLayerId != 0) {
            mLayerWidth = layerInfo[0];
            mLayerHeight = layerInfo[1];
            mLayerTextureId = layerInfo[2];

            mCanvas = new GLES20Canvas(mLayerId, !isOpaque);
            mFinalizer = new Finalizer(mLayerId, mLayerTextureId);
            
            mU = mWidth / (float) mLayerWidth;
            mV = mHeight/ (float) mLayerHeight;
        } else {
            mCanvas = null;
            mFinalizer = null;
        }
    }

    float getU() {
        return mU;
    }

    float getV() {
        return mV;
    }

    @Override
    boolean isValid() {
        return mLayerId != 0 && mLayerWidth > 0 && mLayerHeight > 0;
    }

    @Override
    void resize(int width, int height) {
        if (!isValid() || width <= 0 || height <= 0) return;
        if (width > mLayerWidth || height > mLayerHeight) {
            mWidth = width;
            mHeight = height;

            int[] layerInfo = new int[3];

            GLES20Canvas.nResizeLayer(mLayerId, mLayerTextureId, width, height, layerInfo);

            mLayerWidth = layerInfo[0];
            mLayerHeight = layerInfo[1];

            mU = mWidth / (float) mLayerWidth;
            mV = mHeight/ (float) mLayerHeight;            
        }
    }

    @Override
    HardwareCanvas getCanvas() {
        return mCanvas;
    }

    @Override
    void end(Canvas currentCanvas) {
        if (currentCanvas instanceof GLES20Canvas) {
            ((GLES20Canvas) currentCanvas).resume();
        }
    }

    @Override
    HardwareCanvas start(Canvas currentCanvas) {
        if (currentCanvas instanceof GLES20Canvas) {
            ((GLES20Canvas) currentCanvas).interrupt();
        }
        return getCanvas();
    }

    @Override
    void destroy() {
        mFinalizer.destroy();
        mLayerId = mLayerTextureId = 0;
    }

    private static class Finalizer {
        private int mLayerId;
        private int mLayerTextureId;

        public Finalizer(int layerId, int layerTextureId) {
            mLayerId = layerId;
            mLayerTextureId = layerTextureId;
        }

        @Override
        protected void finalize() throws Throwable {
            try {
                if (mLayerId != 0 || mLayerTextureId != 0) {
                    GLES20Canvas.nDestroyLayer(mLayerId, mLayerTextureId);
                }
            } finally {
                super.finalize();
            }
        }

        void destroy() {
            GLES20Canvas.nDestroyLayer(mLayerId, mLayerTextureId);
            mLayerId = mLayerTextureId = 0;
        }
    }
}
+2 −7
Original line number Diff line number Diff line
@@ -36,7 +36,8 @@ import java.util.HashSet;
class GLES20RecordingCanvas extends GLES20Canvas {
    // These lists ensure that any Bitmaps recorded by a DisplayList are kept alive as long
    // as the DisplayList is alive.
    private HashSet<Bitmap> mBitmaps = new HashSet<Bitmap>();
    @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"})
    private final HashSet<Bitmap> mBitmaps = new HashSet<Bitmap>();

    GLES20RecordingCanvas(boolean translucent) {
        super(true, translucent);
@@ -56,12 +57,6 @@ class GLES20RecordingCanvas extends GLES20Canvas {
        setupRenderer(true);
    }

    @Override
    public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,
            Paint paint) {
        super.drawArc(oval, startAngle, sweepAngle, useCenter, paint);
    }

    @Override
    public void drawPatch(Bitmap bitmap, byte[] chunks, RectF dst, Paint paint) {
        super.drawPatch(bitmap, chunks, dst, paint);
+15 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.view;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;

/**
 * Hardware accelerated canvas. 
@@ -48,5 +49,18 @@ abstract class HardwareCanvas extends Canvas {
     * 
     * @param displayList The display list to replay.
     */
    public abstract void drawDisplayList(DisplayList displayList);
    abstract void drawDisplayList(DisplayList displayList);

    /**
     * Draws the specified layer onto this canvas.
     *
     * @param left The left coordinate of the layer
     * @param top The top coordinate of the layer
     * @param right The right coordinate of the layer
     * @param bottom The bottom coordinate of the layer
     * @param layer The layer to composite on this canvas
     * @param paint The paint used to draw the layer
     */
    abstract void drawHardwareLayer(float left, float top, float right, float bottom,
            HardwareLayer layer, Paint paint); 
}
Loading