Recreate the EGL surface when ViewRoot's surface changes.
Bug #3306150
Change-Id: Ifbf0ab9deca7a34eff7d844ea7276d12d7284788
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index f9a6c1b..addd1b3 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -84,6 +84,13 @@
* @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 @@
}
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 e203355..0326a8f 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -159,6 +159,8 @@
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 @@
* 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 96f8cdc..961b633 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -983,6 +983,8 @@
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 @@
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 8c30987..e4af33f 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -61,6 +61,7 @@
struct so_t {
jfieldID surfaceControl;
+ jfieldID surfaceGenerationId;
jfieldID surface;
jfieldID saveCount;
jfieldID canvas;
@@ -189,6 +190,12 @@
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 @@
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;");