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

This commit is contained in:
Romain Guy
2011-02-08 12:23:59 -08:00
committed by Android (Google) Code Review

View File

@@ -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.
*/
@@ -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);
}
@@ -250,6 +278,7 @@ public abstract class HardwareRenderer {
int mFrameCount;
Paint mDebugPaint;
boolean mDirtyRegions;
final int mGlVersion;
final boolean mTranslucent;
@@ -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);
}
/**
@@ -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
@@ -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 "
@@ -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");
}
@@ -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;
}
@@ -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,
@@ -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;
@@ -703,7 +748,8 @@ public abstract class HardwareRenderer {
mAlphaSize = alphaSize;
mDepthSize = depthSize;
mStencilSize = stencilSize;
}
mDirtyRegions = dirtyRegions;
}
@Override
EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, EGLConfig[] configs) {
@@ -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;