From 2a83f001fdb189f945e82e81e717ba204824b112 Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Tue, 18 Jan 2011 18:28:21 -0800 Subject: [PATCH] Recreate the EGL surface when ViewRoot's surface changes. Bug #3306150 Change-Id: Ifbf0ab9deca7a34eff7d844ea7276d12d7284788 --- core/java/android/view/HardwareRenderer.java | 14 ++++++++++++++ core/java/android/view/Surface.java | 9 +++++++++ core/java/android/view/ViewRoot.java | 5 +++++ core/jni/android_view_Surface.cpp | 8 ++++++++ 4 files changed, 36 insertions(+) diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index f9a6c1b58c3fa..addd1b342d5fa 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -84,6 +84,13 @@ public abstract class HardwareRenderer { * @return True if the initialization was successful, false otherwise. */ abstract boolean initialize(SurfaceHolder holder); + + /** + * Updates the hardware renderer for the specified surface. + * + * @param holder The holder for the surface to hardware accelerate. + */ + abstract void updateSurface(SurfaceHolder holder); /** * Setup the hardware renderer for drawing. This is called for every @@ -330,6 +337,13 @@ public abstract class HardwareRenderer { } return false; } + + @Override + void updateSurface(SurfaceHolder holder) { + if (isRequested() && isEnabled()) { + createEglSurface(holder); + } + } abstract GLES20Canvas createCanvas(); diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index e20335506ac45..0326a8f46182a 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -159,6 +159,8 @@ public class Surface implements Parcelable { private Canvas mCanvas; @SuppressWarnings("unused") private int mNativeSurface; + @SuppressWarnings("unused") + private int mSurfaceGenerationId; private String mName; // The display metrics used to provide the pseudo canvas size for applications @@ -308,6 +310,13 @@ public class Surface implements Parcelable { * returns false. */ public native boolean isValid(); + + /** + * @hide + */ + public int getGenerationId() { + return mSurfaceGenerationId; + } /** Free all server-side state associated with this surface and * release this object's reference. {@hide} */ diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java index 96f8cdcce70b5..961b633170d8c 100644 --- a/core/java/android/view/ViewRoot.java +++ b/core/java/android/view/ViewRoot.java @@ -983,6 +983,8 @@ public final class ViewRoot extends Handler implements ViewParent, Log.i(TAG, "host=w:" + host.getMeasuredWidth() + ", h:" + host.getMeasuredHeight() + ", params=" + params); } + + final int surfaceGenerationId = mSurface.getGenerationId(); relayoutResult = relayoutWindow(params, viewVisibility, insetsPending); if (params != null) { @@ -1043,6 +1045,9 @@ public final class ViewRoot extends Handler implements ViewParent, mScroller.abortAnimation(); } disposeResizeBitmap(); + } else if (surfaceGenerationId != mSurface.getGenerationId() && + mSurfaceHolder == null && mAttachInfo.mHardwareRenderer != null) { + mAttachInfo.mHardwareRenderer.updateSurface(mHolder); } } catch (RemoteException e) { } diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index 8c30987be9850..e4af33f1e885f 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -61,6 +61,7 @@ static sso_t sso; struct so_t { jfieldID surfaceControl; + jfieldID surfaceGenerationId; jfieldID surface; jfieldID saveCount; jfieldID canvas; @@ -189,6 +190,12 @@ static void setSurface(JNIEnv* env, jobject clazz, const sp& surface) p->decStrong(clazz); } env->SetIntField(clazz, so.surface, (int)surface.get()); + // This test is conservative and it would be better to compare the ISurfaces + if (p && p != surface.get()) { + jint generationId = env->GetIntField(clazz, so.surfaceGenerationId); + generationId++; + env->SetIntField(clazz, so.surfaceGenerationId, generationId); + } } // ---------------------------------------------------------------------------- @@ -785,6 +792,7 @@ static JNINativeMethod gSurfaceMethods[] = { void nativeClassInit(JNIEnv* env, jclass clazz) { so.surface = env->GetFieldID(clazz, ANDROID_VIEW_SURFACE_JNI_ID, "I"); + so.surfaceGenerationId = env->GetFieldID(clazz, "mSurfaceGenerationId", "I"); so.surfaceControl = env->GetFieldID(clazz, "mSurfaceControl", "I"); so.saveCount = env->GetFieldID(clazz, "mSaveCount", "I"); so.canvas = env->GetFieldID(clazz, "mCanvas", "Landroid/graphics/Canvas;");