Have an actual fallback if the surface is lost

Bug: 17516789

This will force a relayout/reinitialize pass if the Surface
is lost mid-render instead of crashing on the next frame

Change-Id: If08bfa16f740728fa7c05904fa11e26f07b81e2e
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index b499dd0..6c3637d 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -166,6 +166,11 @@
         freePrefetechedLayers();
     }
 
+    if (CC_UNLIKELY(!mNativeWindow.get())) {
+        info.out.canDrawThisFrame = false;
+        return;
+    }
+
     int runningBehind = 0;
     // TODO: This query is moderately expensive, investigate adding some sort
     // of fast-path based off when we last called eglSwapBuffers() as well as
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index e20564b..435244e 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -68,6 +68,8 @@
     bool initialize(ANativeWindow* window);
     void updateSurface(ANativeWindow* window);
     void pauseSurface(ANativeWindow* window);
+    bool hasSurface() { return mNativeWindow.get(); }
+
     void setup(int width, int height, const Vector3& lightCenter, float lightRadius,
             uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
     void setOpaque(bool opaque);
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index dd34e09..97b31a9 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -132,6 +132,12 @@
     mLayers.clear();
     mContext->prepareTree(info);
 
+    // This is after the prepareTree so that any pending operations
+    // (RenderNode tree state, prefetched layers, etc...) will be flushed.
+    if (CC_UNLIKELY(!mContext->hasSurface())) {
+        mSyncResult |= kSync_LostSurfaceRewardIfFound;
+    }
+
     if (info.out.hasAnimations) {
         if (info.out.requiresUiRedraw) {
             mSyncResult |= kSync_UIRedrawRequired;
diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h
index 243cc5d..28f6cb2 100644
--- a/libs/hwui/renderthread/DrawFrameTask.h
+++ b/libs/hwui/renderthread/DrawFrameTask.h
@@ -42,6 +42,7 @@
 enum SyncResult {
     kSync_OK = 0,
     kSync_UIRedrawRequired = 1 << 0,
+    kSync_LostSurfaceRewardIfFound = 1 << 1,
 };
 
 /*