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;");