summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2011-07-08 15:49:50 -0700
committerRomain Guy <romainguy@google.com>2011-07-08 15:49:50 -0700
commit7e1160e8664a9c5c79367f4ba3c2266a39bbcef5 (patch)
tree9ff69b74d95baaceebb9e5cd0c3a2d8c11eb82e1
parentb2479153b743df9e54f7e17c7132a5ecd87fa453 (diff)
downloadframeworks_base-7e1160e8664a9c5c79367f4ba3c2266a39bbcef5.zip
frameworks_base-7e1160e8664a9c5c79367f4ba3c2266a39bbcef5.tar.gz
frameworks_base-7e1160e8664a9c5c79367f4ba3c2266a39bbcef5.tar.bz2
Always redraw the UI on orientation change
Bug #4994715 In some cases, on some architectures, the hardware renderer could fail to properly render a window after an orientation change. The fix is to force the GL driver to drop any existing buffer to make sure the next buffer used to draw has the correct geometry. This change also fixes an issue that was preventing partial screen updates from being properly enabled. Change-Id: I874a48590845a8624425130af7db8e20022895dd
-rw-r--r--core/java/android/view/HardwareRenderer.java55
-rw-r--r--core/java/android/view/ViewAncestor.java3
2 files changed, 39 insertions, 19 deletions
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 188970c..1638c74 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -128,8 +128,14 @@ public abstract class HardwareRenderer {
abstract void updateSurface(SurfaceHolder holder) throws Surface.OutOfResourcesException;
/**
- * Setup the hardware renderer for drawing. This is called for every
- * frame to draw.
+ * Invoked whenever the size of the target surface changes. This will
+ * not be invoked when the surface is first created.
+ */
+ abstract void preapareSurfaceForResize();
+
+ /**
+ * Setup the hardware renderer for drawing. This is called whenever the
+ * size of the target surface changes or when the surface is first created.
*
* @param width Width of the drawing surface.
* @param height Height of the drawing surface.
@@ -289,9 +295,9 @@ public abstract class HardwareRenderer {
static abstract class GlRenderer extends HardwareRenderer {
// These values are not exposed in our EGL APIs
static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
- static final int EGL_SURFACE_TYPE = 0x3033;
- static final int EGL_SWAP_BEHAVIOR_PRESERVED_BIT = 0x0400;
static final int EGL_OPENGL_ES2_BIT = 4;
+ static final int EGL_SURFACE_TYPE = 0x3033;
+ static final int EGL_SWAP_BEHAVIOR_PRESERVED_BIT = 0x0400;
private static final int SURFACE_STATE_ERROR = 0;
private static final int SURFACE_STATE_SUCCESS = 1;
@@ -311,8 +317,16 @@ public abstract class HardwareRenderer {
int mFrameCount;
Paint mDebugPaint;
- boolean mDirtyRegions;
- final boolean mDirtyRegionsRequested;
+ static boolean sDirtyRegions;
+ static final boolean sDirtyRegionsRequested;
+ static {
+ String dirtyProperty = SystemProperties.get(RENDER_DIRTY_REGIONS_PROPERTY, "true");
+ //noinspection PointlessBooleanExpression,ConstantConditions
+ sDirtyRegions = RENDER_DIRTY_REGIONS && "true".equalsIgnoreCase(dirtyProperty);
+ sDirtyRegionsRequested = sDirtyRegions;
+ }
+
+ boolean mDirtyRegionsEnabled;
final boolean mVsyncDisabled;
final int mGlVersion;
@@ -326,11 +340,6 @@ public abstract class HardwareRenderer {
mGlVersion = glVersion;
mTranslucent = translucent;
- final String dirtyProperty = SystemProperties.get(RENDER_DIRTY_REGIONS_PROPERTY, "true");
- //noinspection PointlessBooleanExpression,ConstantConditions
- mDirtyRegions = RENDER_DIRTY_REGIONS && "true".equalsIgnoreCase(dirtyProperty);
- mDirtyRegionsRequested = mDirtyRegions;
-
final String vsyncProperty = SystemProperties.get(DISABLE_VSYNC_PROPERTY, "false");
mVsyncDisabled = "true".equalsIgnoreCase(vsyncProperty);
if (mVsyncDisabled) {
@@ -342,7 +351,7 @@ public abstract class HardwareRenderer {
* Indicates whether this renderer instance can track and update dirty regions.
*/
boolean hasDirtyRegions() {
- return mDirtyRegions;
+ return mDirtyRegionsEnabled;
}
/**
@@ -479,8 +488,8 @@ public abstract class HardwareRenderer {
sEglConfig = chooseEglConfig();
if (sEglConfig == null) {
// We tried to use EGL_SWAP_BEHAVIOR_PRESERVED_BIT, try again without
- if (mDirtyRegions) {
- mDirtyRegions = false;
+ if (sDirtyRegions) {
+ sDirtyRegions = false;
sEglConfig = chooseEglConfig();
if (sEglConfig == null) {
throw new RuntimeException("eglConfig not initialized");
@@ -500,7 +509,7 @@ public abstract class HardwareRenderer {
private EGLConfig chooseEglConfig() {
int[] configsCount = new int[1];
EGLConfig[] configs = new EGLConfig[1];
- int[] configSpec = getConfig(mDirtyRegions);
+ int[] configSpec = getConfig(sDirtyRegions);
if (!sEgl.eglChooseConfig(sEglDisplay, configSpec, configs, 1, configsCount)) {
throw new IllegalArgumentException("eglChooseConfig failed " +
getEGLErrorString(sEgl.eglGetError()));
@@ -566,18 +575,18 @@ public abstract class HardwareRenderer {
// If mDirtyRegions is set, this means we have an EGL configuration
// with EGL_SWAP_BEHAVIOR_PRESERVED_BIT set
- if (mDirtyRegions) {
- if (!GLES20Canvas.preserveBackBuffer()) {
+ if (sDirtyRegions) {
+ if (!(mDirtyRegionsEnabled = GLES20Canvas.preserveBackBuffer())) {
Log.w(LOG_TAG, "Backbuffer cannot be preserved");
}
- } else if (mDirtyRegionsRequested) {
+ } else if (sDirtyRegionsRequested) {
// If mDirtyRegions is not set, our EGL configuration does not
// have EGL_SWAP_BEHAVIOR_PRESERVED_BIT; however, the default
// swap behavior might be EGL_BUFFER_PRESERVED, which means we
// want to set mDirtyRegions. We try to do this only if dirty
// regions were initially requested as part of the device
// configuration (see RENDER_DIRTY_REGIONS)
- mDirtyRegions = GLES20Canvas.isBackBufferPreserved();
+ mDirtyRegionsEnabled = GLES20Canvas.isBackBufferPreserved();
}
return sEglContext.getGL();
@@ -620,6 +629,14 @@ public abstract class HardwareRenderer {
}
@Override
+ void preapareSurfaceForResize() {
+ // Cancels any existing buffer to ensure we'll get a buffer
+ // of the right size before we call eglSwapBuffers
+ sEgl.eglMakeCurrent(sEglDisplay, EGL10.EGL_NO_SURFACE,
+ EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
+ }
+
+ @Override
void setup(int width, int height) {
mCanvas.setViewport(width, height);
}
diff --git a/core/java/android/view/ViewAncestor.java b/core/java/android/view/ViewAncestor.java
index d70c798..c0619a5 100644
--- a/core/java/android/view/ViewAncestor.java
+++ b/core/java/android/view/ViewAncestor.java
@@ -1314,6 +1314,9 @@ public final class ViewAncestor extends Handler implements ViewParent,
if (hwInitialized || ((windowShouldResize || params != null) &&
mAttachInfo.mHardwareRenderer != null &&
mAttachInfo.mHardwareRenderer.isEnabled())) {
+ if (!hwInitialized) {
+ mAttachInfo.mHardwareRenderer.preapareSurfaceForResize();
+ }
mAttachInfo.mHardwareRenderer.setup(mWidth, mHeight);
}