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

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

Cleanup implementation of hardware layers.

The new implementation relies on OpenGLRenderer's existing layer
code instead of duplicating it. The new code is much cleaner, with
simpler and better APIs and allows tracking of drawn regions inside
layers. Region tracking is not yet enabled but this will be done
in a future CL.

Change-Id: Ie826121a2227de8252c77b992a61218defea5143
parent 4f6aff38
Loading
Loading
Loading
Loading
+10 −14
Original line number Diff line number Diff line
@@ -83,9 +83,9 @@ class GLES20Canvas extends HardwareCanvas {
    /**
     * Creates a canvas to render into an FBO.
     */
    GLES20Canvas(int fbo, boolean translucent) {
    GLES20Canvas(int layer, boolean translucent) {
        mOpaque = !translucent;
        mRenderer = nCreateLayerRenderer(fbo);
        mRenderer = nCreateLayerRenderer(layer);
        setupFinalizer();
    }
    
@@ -114,7 +114,7 @@ class GLES20Canvas extends HardwareCanvas {
    }

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

@@ -156,11 +156,10 @@ 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);    
    static native void nDestroyLayerDeferred(int layerId, int layerTextureId);    
    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 nDestroyLayer(int layerId);
    static native void nDestroyLayerDeferred(int layerId);

    ///////////////////////////////////////////////////////////////////////////
    // Canvas management
@@ -257,18 +256,15 @@ class GLES20Canvas extends HardwareCanvas {
    // Hardware layer
    ///////////////////////////////////////////////////////////////////////////
    
    void drawHardwareLayer(float left, float top, float right, float bottom,
            HardwareLayer layer, Paint paint) {
    void drawHardwareLayer(HardwareLayer layer, float x, float y, 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);
        nDrawLayer(mRenderer, glLayer.getLayer(), x, y, 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);
    private native void nDrawLayer(int renderer, int layer, float x, float y, int paint);
    
    void interrupt() {
        nInterrupt(mRenderer);
+22 −34
Original line number Diff line number Diff line
@@ -22,52 +22,45 @@ import android.graphics.Canvas;
 * An OpenGL ES 2.0 implementation of {@link HardwareLayer}.
 */
class GLES20Layer extends HardwareLayer {
    private int mLayerId;
    int mLayerTextureId;
    private int mLayer;

    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) {
        int[] layerInfo = new int[2];
        mLayer = GLES20Canvas.nCreateLayer(width, height, isOpaque, layerInfo);
        if (mLayer != 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;
            mCanvas = new GLES20Canvas(mLayer, !isOpaque);
            mFinalizer = new Finalizer(mLayer);
        } else {
            mCanvas = null;
            mFinalizer = null;
        }
    }

    float getU() {
        return mU;
    }

    float getV() {
        return mV;
    /**
     * Returns the native layer object used to render this layer.
     * 
     * @return A pointer to the native layer object, or 0 if the object is NULL
     */
    public int getLayer() {
        return mLayer;
    }

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

    @Override
@@ -77,15 +70,12 @@ class GLES20Layer extends HardwareLayer {
            mWidth = width;
            mHeight = height;

            int[] layerInfo = new int[3];
            int[] layerInfo = new int[2];

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

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

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

@@ -112,23 +102,21 @@ class GLES20Layer extends HardwareLayer {
    @Override
    void destroy() {
        mFinalizer.destroy();
        mLayerId = mLayerTextureId = 0;
        mLayer = 0;
    }

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

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

        @Override
        protected void finalize() throws Throwable {
            try {
                if (mLayerId != 0 || mLayerTextureId != 0) {
                    GLES20Canvas.nDestroyLayerDeferred(mLayerId, mLayerTextureId);
                if (mLayerId != 0) {
                    GLES20Canvas.nDestroyLayerDeferred(mLayerId);
                }
            } finally {
                super.finalize();
@@ -136,8 +124,8 @@ class GLES20Layer extends HardwareLayer {
        }

        void destroy() {
            GLES20Canvas.nDestroyLayer(mLayerId, mLayerTextureId);
            mLayerId = mLayerTextureId = 0;
            GLES20Canvas.nDestroyLayer(mLayerId);
            mLayerId = 0;
        }
    }
}
+3 −6
Original line number Diff line number Diff line
@@ -54,13 +54,10 @@ abstract class HardwareCanvas extends Canvas {
    /**
     * 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 x The left coordinate of the layer
     * @param y The top coordinate of the layer
     * @param paint The paint used to draw the layer
     */
    abstract void drawHardwareLayer(float left, float top, float right, float bottom,
            HardwareLayer layer, Paint paint); 
    abstract void drawHardwareLayer(HardwareLayer layer, float x, float y, Paint paint); 
}
+1 −2
Original line number Diff line number Diff line
@@ -2391,8 +2391,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
            if (!layerSaved && layerType == LAYER_TYPE_HARDWARE) {
                final HardwareLayer layer = child.getHardwareLayer(canvas);
                if (layer != null && layer.isValid()) {
                    ((HardwareCanvas) canvas).drawHardwareLayer(0, 0, cr - cl, cb - ct,
                            layer, child.mLayerPaint);
                    ((HardwareCanvas) canvas).drawHardwareLayer(layer, 0, 0, child.mLayerPaint);
                    layerRendered = true;
                } else {
                    canvas.saveLayer(sx, sy, sx + cr - cl, sy + cb - ct, child.mLayerPaint,
+29 −40
Original line number Diff line number Diff line
@@ -458,59 +458,49 @@ static void android_view_GLES20Canvas_resume(JNIEnv* env, jobject canvas,
}

static OpenGLRenderer* android_view_GLES20Canvas_createLayerRenderer(JNIEnv* env,
        jobject clazz, jint fbo) {
    return new LayerRenderer(fbo);
        jobject clazz, Layer* layer) {
    if (layer) {
        return new LayerRenderer(layer);
    }
    return NULL;
}

static jint android_view_GLES20Canvas_createLayer(JNIEnv* env,
        jobject clazz, jint width, jint height, jintArray layerInfo) {
    uint32_t layerWidth = 0;
    uint32_t layerHeight = 0;
    GLuint textureId = 0;

    jint layerId = LayerRenderer::createLayer(width, height,
            &layerWidth, &layerHeight, &textureId);
static Layer* android_view_GLES20Canvas_createLayer(JNIEnv* env, jobject clazz,
        jint width, jint height, jboolean isOpaque, jintArray layerInfo) {
    Layer* layer = LayerRenderer::createLayer(width, height, isOpaque);

    if (layerId) {
    if (layer) {
        jint* storage = env->GetIntArrayElements(layerInfo, NULL);
        storage[0] = layerWidth;
        storage[1] = layerHeight;
        storage[2] = textureId;
        storage[0] = layer->width;
        storage[1] = layer->height;
        env->ReleaseIntArrayElements(layerInfo, storage, 0);
    }

    return layerId;
    return layer;
}

static void android_view_GLES20Canvas_resizeLayer(JNIEnv* env,
        jobject clazz, jint layerId, jint layerTextureId, jint width, jint height,
        jintArray layerInfo) {
    uint32_t layerWidth = 0;
    uint32_t layerHeight = 0;

    LayerRenderer::resizeLayer(layerId, layerTextureId, width, height, &layerWidth, &layerHeight);
static void android_view_GLES20Canvas_resizeLayer(JNIEnv* env, jobject clazz,
        Layer* layer, jint width, jint height, jintArray layerInfo) {
    LayerRenderer::resizeLayer(layer, width, height);

    jint* storage = env->GetIntArrayElements(layerInfo, NULL);
    storage[0] = layerWidth;
    storage[1] = layerHeight;
    storage[0] = layer->width;
    storage[1] = layer->height;
    env->ReleaseIntArrayElements(layerInfo, storage, 0);
}

static void android_view_GLES20Canvas_destroyLayer(JNIEnv* env,
        jobject clazz, jint layerId, jint layerTextureId) {
    LayerRenderer::destroyLayer(layerId, layerTextureId);
static void android_view_GLES20Canvas_destroyLayer(JNIEnv* env, jobject clazz, Layer* layer) {
    LayerRenderer::destroyLayer(layer);
}

static void android_view_GLES20Canvas_destroyLayerDeferred(JNIEnv* env,
        jobject clazz, jint layerId, jint layerTextureId) {
    LayerRenderer::destroyLayerDeferred(layerId, layerTextureId);
        jobject clazz, Layer* layer) {
    LayerRenderer::destroyLayerDeferred(layer);
}

static void android_view_GLES20Canvas_drawLayer(JNIEnv* env,
        jobject canvas, OpenGLRenderer* renderer,
        jfloat left, jfloat top, jfloat right, jfloat bottom,
        jint layerTexture, jfloat u, jfloat v, SkPaint* paint) {
    renderer->drawLayer(layerTexture, left, top, right, bottom, u, v, paint);
static void android_view_GLES20Canvas_drawLayer(JNIEnv* env, jobject canvas,
        OpenGLRenderer* renderer, Layer* layer, jfloat x, jfloat y, SkPaint* paint) {
    renderer->drawLayer(layer, x, y, paint);
}

#endif // USE_OPENGL_RENDERER
@@ -602,12 +592,11 @@ static JNINativeMethod gMethods[] = {
    { "nResume",                 "(I)V",       (void*) android_view_GLES20Canvas_resume },

    { "nCreateLayerRenderer",    "(I)I",       (void*) android_view_GLES20Canvas_createLayerRenderer },
    { "nCreateLayer",            "(II[I)I",    (void*) android_view_GLES20Canvas_createLayer },
    { "nResizeLayer",            "(IIII[I)V",  (void*) android_view_GLES20Canvas_resizeLayer },
    { "nDestroyLayer",           "(II)V",      (void*) android_view_GLES20Canvas_destroyLayer },
    { "nDestroyLayerDeferred",   "(II)V",      (void*) android_view_GLES20Canvas_destroyLayerDeferred },
    { "nDrawLayer",              "(IFFFFIFFI)V",
            (void*) android_view_GLES20Canvas_drawLayer },
    { "nCreateLayer",            "(IIZ[I)I",   (void*) android_view_GLES20Canvas_createLayer },
    { "nResizeLayer",            "(III[I)V" ,  (void*) android_view_GLES20Canvas_resizeLayer },
    { "nDestroyLayer",           "(I)V",       (void*) android_view_GLES20Canvas_destroyLayer },
    { "nDestroyLayerDeferred",   "(I)V",       (void*) android_view_GLES20Canvas_destroyLayerDeferred },
    { "nDrawLayer",              "(IIFFI)V",   (void*) android_view_GLES20Canvas_drawLayer },

#endif
};
Loading