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

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

Merge "Better handling of EGL_SWAP_BEHAVIOR_PRESERVED_BIT Bug #3410832 Bug #3410834"

parents 4cf6663e 069ea0e3
Loading
Loading
Loading
Loading
+64 −18
Original line number Original line Diff line number Diff line
@@ -42,9 +42,22 @@ public abstract class HardwareRenderer {


    /**
    /**
     * Turn on to only refresh the parts of the screen that need updating.
     * Turn on to only refresh the parts of the screen that need updating.
     * When turned on the property defined by {@link #RENDER_DIRTY_REGIONS_PROPERTY}
     * must also have the value "true". 
     */
     */
    public static final boolean RENDER_DIRTY_REGIONS = true;
    public static final boolean RENDER_DIRTY_REGIONS = true;


    /**
     * System property used to enable or disable dirty regions invalidation.
     * This property is only queried if {@link #RENDER_DIRTY_REGIONS} is true.
     * The default value of this property is assumed to be true.
     * 
     * Possible values:
     * "true", to enable partial invalidates
     * "false", to disable partial invalidates
     */
    static final String RENDER_DIRTY_REGIONS_PROPERTY = "hwui.render_dirty_regions";

    /**
    /**
     * Turn on to draw dirty regions every other frame.
     * Turn on to draw dirty regions every other frame.
     */
     */
@@ -113,8 +126,23 @@ public abstract class HardwareRenderer {
     */
     */
    abstract void setup(int width, int height);
    abstract void setup(int width, int height);


    /**
     * Interface used to receive callbacks whenever a view is drawn by
     * a hardware renderer instance.
     */
    interface HardwareDrawCallbacks {
    interface HardwareDrawCallbacks {
        /**
         * Invoked before a view is drawn by a hardware renderer.
         * 
         * @param canvas The Canvas used to render the view.
         */
        void onHardwarePreDraw(Canvas canvas);
        void onHardwarePreDraw(Canvas canvas);

        /**
         * Invoked after a view is drawn by a hardware renderer.
         * 
         * @param canvas The Canvas used to render the view.
         */
        void onHardwarePostDraw(Canvas canvas);
        void onHardwarePostDraw(Canvas canvas);
    }
    }


@@ -250,6 +278,7 @@ public abstract class HardwareRenderer {
        int mFrameCount;
        int mFrameCount;
        Paint mDebugPaint;
        Paint mDebugPaint;


        boolean mDirtyRegions;


        final int mGlVersion;
        final int mGlVersion;
        final boolean mTranslucent;
        final boolean mTranslucent;
@@ -259,6 +288,9 @@ public abstract class HardwareRenderer {
        GlRenderer(int glVersion, boolean translucent) {
        GlRenderer(int glVersion, boolean translucent) {
            mGlVersion = glVersion;
            mGlVersion = glVersion;
            mTranslucent = translucent;
            mTranslucent = translucent;
            final String dirtyProperty = System.getProperty(RENDER_DIRTY_REGIONS_PROPERTY, "true");
            //noinspection PointlessBooleanExpression,ConstantConditions
            mDirtyRegions = RENDER_DIRTY_REGIONS && "true".equalsIgnoreCase(dirtyProperty);
        }
        }


        /**
        /**
@@ -388,10 +420,24 @@ public abstract class HardwareRenderer {
            // We can now initialize EGL for that display
            // We can now initialize EGL for that display
            int[] version = new int[2];
            int[] version = new int[2];
            if (!sEgl.eglInitialize(sEglDisplay, version)) {
            if (!sEgl.eglInitialize(sEglDisplay, version)) {
                throw new RuntimeException("eglInitialize failed "
                throw new RuntimeException("eglInitialize failed " +
                        + getEGLErrorString(sEgl.eglGetError()));
                        getEGLErrorString(sEgl.eglGetError()));
            }
            }

            sEglConfig = getConfigChooser(mGlVersion).chooseConfig(sEgl, sEglDisplay);
            sEglConfig = getConfigChooser(mGlVersion).chooseConfig(sEgl, sEglDisplay);
            if (sEglConfig == null) {
                // We tried to use EGL_SWAP_BEHAVIOR_PRESERVED_BIT, try again without
                if (mDirtyRegions) {
                    mDirtyRegions = false;

                    sEglConfig = getConfigChooser(mGlVersion).chooseConfig(sEgl, sEglDisplay);
                    if (sEglConfig == null) {
                        throw new RuntimeException("eglConfig not initialized");
                    }
                } else {
                    throw new RuntimeException("eglConfig not initialized");
                }
            }
            
            
            /*
            /*
            * Create an EGL context. We want to do this as rarely as we can, because an
            * Create an EGL context. We want to do this as rarely as we can, because an
@@ -409,7 +455,7 @@ public abstract class HardwareRenderer {
                throw new RuntimeException("eglDisplay not initialized");
                throw new RuntimeException("eglDisplay not initialized");
            }
            }
            if (sEglConfig == null) {
            if (sEglConfig == null) {
                throw new RuntimeException("mEglConfig not initialized");
                throw new RuntimeException("eglConfig not initialized");
            }
            }
            if (Thread.currentThread() != sEglThread) {
            if (Thread.currentThread() != sEglThread) {
                throw new IllegalStateException("HardwareRenderer cannot be used " 
                throw new IllegalStateException("HardwareRenderer cannot be used " 
@@ -452,7 +498,7 @@ public abstract class HardwareRenderer {
                        + getEGLErrorString(sEgl.eglGetError()));
                        + getEGLErrorString(sEgl.eglGetError()));
            }
            }
            
            
            if (RENDER_DIRTY_REGIONS) {
            if (mDirtyRegions) {
                if (!GLES20Canvas.preserveBackBuffer()) {
                if (!GLES20Canvas.preserveBackBuffer()) {
                    Log.w(LOG_TAG, "Backbuffer cannot be preserved");
                    Log.w(LOG_TAG, "Backbuffer cannot be preserved");
                }
                }
@@ -518,15 +564,14 @@ public abstract class HardwareRenderer {
         * @return An {@link android.view.HardwareRenderer.GlRenderer.EglConfigChooser}.
         * @return An {@link android.view.HardwareRenderer.GlRenderer.EglConfigChooser}.
         */
         */
        EglConfigChooser getConfigChooser(int glVersion) {
        EglConfigChooser getConfigChooser(int glVersion) {
            return new ComponentSizeChooser(glVersion, 8, 8, 8, 8, 0, 0);
            return new ComponentSizeChooser(glVersion, 8, 8, 8, 8, 0, 0, mDirtyRegions);
        }
        }


        @Override
        @Override
        void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks,
        void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks,
                Rect dirty) {
                Rect dirty) {
            if (canDraw()) {
            if (canDraw()) {
                //noinspection PointlessBooleanExpression,ConstantConditions
                if (!mDirtyRegions) {
                if (!HardwareRenderer.RENDER_DIRTY_REGIONS) {
                    dirty = null;
                    dirty = null;
                }
                }


@@ -676,16 +721,16 @@ public abstract class HardwareRenderer {
        static class ComponentSizeChooser extends EglConfigChooser {
        static class ComponentSizeChooser extends EglConfigChooser {
            private int[] mValue;
            private int[] mValue;


            private int mRedSize;
            private final int mRedSize;
            private int mGreenSize;
            private final int mGreenSize;
            private int mBlueSize;
            private final int mBlueSize;
            private int mAlphaSize;
            private final int mAlphaSize;
            private int mDepthSize;
            private final int mDepthSize;
            private int mStencilSize;
            private final int mStencilSize;
            private final boolean mDirtyRegions;


            ComponentSizeChooser(int glVersion, int redSize, int greenSize, int blueSize,
            ComponentSizeChooser(int glVersion, int redSize, int greenSize, int blueSize,
                    int alphaSize, int depthSize, int stencilSize) {
                    int alphaSize, int depthSize, int stencilSize, boolean dirtyRegions) {
                //noinspection PointlessBitwiseExpression
                super(glVersion, new int[] {
                super(glVersion, new int[] {
                        EGL10.EGL_RED_SIZE, redSize,
                        EGL10.EGL_RED_SIZE, redSize,
                        EGL10.EGL_GREEN_SIZE, greenSize,
                        EGL10.EGL_GREEN_SIZE, greenSize,
@@ -694,7 +739,7 @@ public abstract class HardwareRenderer {
                        EGL10.EGL_DEPTH_SIZE, depthSize,
                        EGL10.EGL_DEPTH_SIZE, depthSize,
                        EGL10.EGL_STENCIL_SIZE, stencilSize,
                        EGL10.EGL_STENCIL_SIZE, stencilSize,
                        EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT |
                        EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT |
                                (RENDER_DIRTY_REGIONS ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0),
                                (dirtyRegions ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0),
                        EGL10.EGL_NONE });
                        EGL10.EGL_NONE });
                mValue = new int[1];
                mValue = new int[1];
                mRedSize = redSize;
                mRedSize = redSize;
@@ -703,6 +748,7 @@ public abstract class HardwareRenderer {
                mAlphaSize = alphaSize;
                mAlphaSize = alphaSize;
                mDepthSize = depthSize;
                mDepthSize = depthSize;
                mStencilSize = stencilSize;
                mStencilSize = stencilSize;
                mDirtyRegions = dirtyRegions;
            }
            }


            @Override
            @Override
@@ -716,7 +762,7 @@ public abstract class HardwareRenderer {
                        int b = findConfigAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE, 0);
                        int b = findConfigAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE, 0);
                        int a = findConfigAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE, 0);
                        int a = findConfigAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE, 0);
                        boolean backBuffer;
                        boolean backBuffer;
                        if (RENDER_DIRTY_REGIONS) {
                        if (mDirtyRegions) {
                            int surfaceType = findConfigAttrib(egl, display, config,
                            int surfaceType = findConfigAttrib(egl, display, config,
                                    EGL_SURFACE_TYPE, 0);
                                    EGL_SURFACE_TYPE, 0);
                            backBuffer = (surfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) != 0;
                            backBuffer = (surfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) != 0;