Loading core/java/android/view/HardwareRenderer.java +64 −18 Original line number Diff line number Diff line Loading @@ -42,9 +42,22 @@ public abstract class HardwareRenderer { /** * 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; /** * 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. */ Loading Loading @@ -113,8 +126,23 @@ public abstract class HardwareRenderer { */ abstract void setup(int width, int height); /** * Interface used to receive callbacks whenever a view is drawn by * a hardware renderer instance. */ 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); /** * Invoked after a view is drawn by a hardware renderer. * * @param canvas The Canvas used to render the view. */ void onHardwarePostDraw(Canvas canvas); } Loading Loading @@ -250,6 +278,7 @@ public abstract class HardwareRenderer { int mFrameCount; Paint mDebugPaint; boolean mDirtyRegions; final int mGlVersion; final boolean mTranslucent; Loading @@ -259,6 +288,9 @@ public abstract class HardwareRenderer { GlRenderer(int glVersion, boolean translucent) { mGlVersion = glVersion; mTranslucent = translucent; final String dirtyProperty = System.getProperty(RENDER_DIRTY_REGIONS_PROPERTY, "true"); //noinspection PointlessBooleanExpression,ConstantConditions mDirtyRegions = RENDER_DIRTY_REGIONS && "true".equalsIgnoreCase(dirtyProperty); } /** Loading Loading @@ -388,10 +420,24 @@ public abstract class HardwareRenderer { // We can now initialize EGL for that display int[] version = new int[2]; if (!sEgl.eglInitialize(sEglDisplay, version)) { throw new RuntimeException("eglInitialize failed " + getEGLErrorString(sEgl.eglGetError())); throw new RuntimeException("eglInitialize failed " + getEGLErrorString(sEgl.eglGetError())); } 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 Loading @@ -409,7 +455,7 @@ public abstract class HardwareRenderer { throw new RuntimeException("eglDisplay not initialized"); } if (sEglConfig == null) { throw new RuntimeException("mEglConfig not initialized"); throw new RuntimeException("eglConfig not initialized"); } if (Thread.currentThread() != sEglThread) { throw new IllegalStateException("HardwareRenderer cannot be used " Loading Loading @@ -452,7 +498,7 @@ public abstract class HardwareRenderer { + getEGLErrorString(sEgl.eglGetError())); } if (RENDER_DIRTY_REGIONS) { if (mDirtyRegions) { if (!GLES20Canvas.preserveBackBuffer()) { Log.w(LOG_TAG, "Backbuffer cannot be preserved"); } Loading Loading @@ -518,15 +564,14 @@ public abstract class HardwareRenderer { * @return An {@link android.view.HardwareRenderer.GlRenderer.EglConfigChooser}. */ 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 void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks, Rect dirty) { if (canDraw()) { //noinspection PointlessBooleanExpression,ConstantConditions if (!HardwareRenderer.RENDER_DIRTY_REGIONS) { if (!mDirtyRegions) { dirty = null; } Loading Loading @@ -676,16 +721,16 @@ public abstract class HardwareRenderer { static class ComponentSizeChooser extends EglConfigChooser { private int[] mValue; private int mRedSize; private int mGreenSize; private int mBlueSize; private int mAlphaSize; private int mDepthSize; private int mStencilSize; private final int mRedSize; private final int mGreenSize; private final int mBlueSize; private final int mAlphaSize; private final int mDepthSize; private final int mStencilSize; private final boolean mDirtyRegions; ComponentSizeChooser(int glVersion, int redSize, int greenSize, int blueSize, int alphaSize, int depthSize, int stencilSize) { //noinspection PointlessBitwiseExpression int alphaSize, int depthSize, int stencilSize, boolean dirtyRegions) { super(glVersion, new int[] { EGL10.EGL_RED_SIZE, redSize, EGL10.EGL_GREEN_SIZE, greenSize, Loading @@ -694,7 +739,7 @@ public abstract class HardwareRenderer { EGL10.EGL_DEPTH_SIZE, depthSize, EGL10.EGL_STENCIL_SIZE, stencilSize, 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 }); mValue = new int[1]; mRedSize = redSize; Loading @@ -703,6 +748,7 @@ public abstract class HardwareRenderer { mAlphaSize = alphaSize; mDepthSize = depthSize; mStencilSize = stencilSize; mDirtyRegions = dirtyRegions; } @Override Loading @@ -716,7 +762,7 @@ public abstract class HardwareRenderer { int b = findConfigAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE, 0); int a = findConfigAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE, 0); boolean backBuffer; if (RENDER_DIRTY_REGIONS) { if (mDirtyRegions) { int surfaceType = findConfigAttrib(egl, display, config, EGL_SURFACE_TYPE, 0); backBuffer = (surfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) != 0; Loading Loading
core/java/android/view/HardwareRenderer.java +64 −18 Original line number Diff line number Diff line Loading @@ -42,9 +42,22 @@ public abstract class HardwareRenderer { /** * 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; /** * 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. */ Loading Loading @@ -113,8 +126,23 @@ public abstract class HardwareRenderer { */ abstract void setup(int width, int height); /** * Interface used to receive callbacks whenever a view is drawn by * a hardware renderer instance. */ 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); /** * Invoked after a view is drawn by a hardware renderer. * * @param canvas The Canvas used to render the view. */ void onHardwarePostDraw(Canvas canvas); } Loading Loading @@ -250,6 +278,7 @@ public abstract class HardwareRenderer { int mFrameCount; Paint mDebugPaint; boolean mDirtyRegions; final int mGlVersion; final boolean mTranslucent; Loading @@ -259,6 +288,9 @@ public abstract class HardwareRenderer { GlRenderer(int glVersion, boolean translucent) { mGlVersion = glVersion; mTranslucent = translucent; final String dirtyProperty = System.getProperty(RENDER_DIRTY_REGIONS_PROPERTY, "true"); //noinspection PointlessBooleanExpression,ConstantConditions mDirtyRegions = RENDER_DIRTY_REGIONS && "true".equalsIgnoreCase(dirtyProperty); } /** Loading Loading @@ -388,10 +420,24 @@ public abstract class HardwareRenderer { // We can now initialize EGL for that display int[] version = new int[2]; if (!sEgl.eglInitialize(sEglDisplay, version)) { throw new RuntimeException("eglInitialize failed " + getEGLErrorString(sEgl.eglGetError())); throw new RuntimeException("eglInitialize failed " + getEGLErrorString(sEgl.eglGetError())); } 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 Loading @@ -409,7 +455,7 @@ public abstract class HardwareRenderer { throw new RuntimeException("eglDisplay not initialized"); } if (sEglConfig == null) { throw new RuntimeException("mEglConfig not initialized"); throw new RuntimeException("eglConfig not initialized"); } if (Thread.currentThread() != sEglThread) { throw new IllegalStateException("HardwareRenderer cannot be used " Loading Loading @@ -452,7 +498,7 @@ public abstract class HardwareRenderer { + getEGLErrorString(sEgl.eglGetError())); } if (RENDER_DIRTY_REGIONS) { if (mDirtyRegions) { if (!GLES20Canvas.preserveBackBuffer()) { Log.w(LOG_TAG, "Backbuffer cannot be preserved"); } Loading Loading @@ -518,15 +564,14 @@ public abstract class HardwareRenderer { * @return An {@link android.view.HardwareRenderer.GlRenderer.EglConfigChooser}. */ 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 void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks, Rect dirty) { if (canDraw()) { //noinspection PointlessBooleanExpression,ConstantConditions if (!HardwareRenderer.RENDER_DIRTY_REGIONS) { if (!mDirtyRegions) { dirty = null; } Loading Loading @@ -676,16 +721,16 @@ public abstract class HardwareRenderer { static class ComponentSizeChooser extends EglConfigChooser { private int[] mValue; private int mRedSize; private int mGreenSize; private int mBlueSize; private int mAlphaSize; private int mDepthSize; private int mStencilSize; private final int mRedSize; private final int mGreenSize; private final int mBlueSize; private final int mAlphaSize; private final int mDepthSize; private final int mStencilSize; private final boolean mDirtyRegions; ComponentSizeChooser(int glVersion, int redSize, int greenSize, int blueSize, int alphaSize, int depthSize, int stencilSize) { //noinspection PointlessBitwiseExpression int alphaSize, int depthSize, int stencilSize, boolean dirtyRegions) { super(glVersion, new int[] { EGL10.EGL_RED_SIZE, redSize, EGL10.EGL_GREEN_SIZE, greenSize, Loading @@ -694,7 +739,7 @@ public abstract class HardwareRenderer { EGL10.EGL_DEPTH_SIZE, depthSize, EGL10.EGL_STENCIL_SIZE, stencilSize, 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 }); mValue = new int[1]; mRedSize = redSize; Loading @@ -703,6 +748,7 @@ public abstract class HardwareRenderer { mAlphaSize = alphaSize; mDepthSize = depthSize; mStencilSize = stencilSize; mDirtyRegions = dirtyRegions; } @Override Loading @@ -716,7 +762,7 @@ public abstract class HardwareRenderer { int b = findConfigAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE, 0); int a = findConfigAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE, 0); boolean backBuffer; if (RENDER_DIRTY_REGIONS) { if (mDirtyRegions) { int surfaceType = findConfigAttrib(egl, display, config, EGL_SURFACE_TYPE, 0); backBuffer = (surfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) != 0; Loading