Fence on destruction

 Bug: 14052927
 destroyCanvasAndSurface() needs a fence as when it returns the
 underlying BufferQueue is going to be released from under
 the render thread.

Change-Id: I0147a1d5ec5adf0239c761ef22f65cd8c8a137df
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index cbb98e1..1429837 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -67,7 +67,7 @@
     void destroy(boolean full) {
         mInitialized = false;
         updateEnabledState(null);
-        nDestroyCanvas(mNativeProxy);
+        nDestroyCanvasAndSurface(mNativeProxy);
     }
 
     private void updateEnabledState(Surface surface) {
@@ -300,7 +300,7 @@
     private static native void nDrawDisplayList(long nativeProxy, long displayList,
             int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom);
     private static native void nRunWithGlContext(long nativeProxy, Runnable runnable);
-    private static native void nDestroyCanvas(long nativeProxy);
+    private static native void nDestroyCanvasAndSurface(long nativeProxy);
 
     private static native void nInvokeFunctor(long nativeProxy, long functor, boolean waitForCompletion);
 
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 30d3e0c..b5f489d 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -121,10 +121,10 @@
     proxy->drawDisplayList(displayList, dirtyLeft, dirtyTop, dirtyRight, dirtyBottom);
 }
 
-static void android_view_ThreadedRenderer_destroyCanvas(JNIEnv* env, jobject clazz,
+static void android_view_ThreadedRenderer_destroyCanvasAndSurface(JNIEnv* env, jobject clazz,
         jlong proxyPtr) {
     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
-    proxy->destroyCanvas();
+    proxy->destroyCanvasAndSurface();
 }
 
 static void android_view_ThreadedRenderer_invokeFunctor(JNIEnv* env, jobject clazz,
@@ -194,7 +194,7 @@
     { "nPauseSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_pauseSurface },
     { "nSetup", "(JII)V", (void*) android_view_ThreadedRenderer_setup },
     { "nDrawDisplayList", "(JJIIII)V", (void*) android_view_ThreadedRenderer_drawDisplayList },
-    { "nDestroyCanvas", "(J)V", (void*) android_view_ThreadedRenderer_destroyCanvas },
+    { "nDestroyCanvasAndSurface", "(J)V", (void*) android_view_ThreadedRenderer_destroyCanvasAndSurface },
     { "nInvokeFunctor", "(JJZ)V", (void*) android_view_ThreadedRenderer_invokeFunctor },
     { "nRunWithGlContext", "(JLjava/lang/Runnable;)V", (void*) android_view_ThreadedRenderer_runWithGlContext },
     { "nCreateDisplayListLayer", "(JII)J", (void*) android_view_ThreadedRenderer_createDisplayListLayer },
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 3638184..65fed44 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -318,10 +318,10 @@
 }
 
 CanvasContext::~CanvasContext() {
-    destroyCanvas();
+    destroyCanvasAndSurface();
 }
 
-void CanvasContext::destroyCanvas() {
+void CanvasContext::destroyCanvasAndSurface() {
     if (mCanvas) {
         delete mCanvas;
         mCanvas = 0;
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index dcb5957..8d1a00a 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -56,7 +56,7 @@
     void setup(int width, int height);
     void processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters, bool* hasFunctors);
     void drawDisplayList(RenderNode* displayList, Rect* dirty);
-    void destroyCanvas();
+    void destroyCanvasAndSurface();
 
     bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
 
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index b233ae9..ce490f1 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -140,15 +140,18 @@
     mDrawFrameTask.drawFrame(&mRenderThread);
 }
 
-CREATE_BRIDGE1(destroyCanvas, CanvasContext* context) {
-    args->context->destroyCanvas();
+CREATE_BRIDGE1(destroyCanvasAndSurface, CanvasContext* context) {
+    args->context->destroyCanvasAndSurface();
     return NULL;
 }
 
-void RenderProxy::destroyCanvas() {
-    SETUP_TASK(destroyCanvas);
+void RenderProxy::destroyCanvasAndSurface() {
+    SETUP_TASK(destroyCanvasAndSurface);
     args->context = mContext;
-    post(task);
+    // destroyCanvasAndSurface() needs a fence as when it returns the
+    // underlying BufferQueue is going to be released from under
+    // the render thread.
+    postAndWait(task);
 }
 
 CREATE_BRIDGE2(invokeFunctor, CanvasContext* context, Functor* functor) {
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 3eb8ed8..a112493 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -65,7 +65,7 @@
     ANDROID_API void setup(int width, int height);
     ANDROID_API void drawDisplayList(RenderNode* displayList,
             int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom);
-    ANDROID_API void destroyCanvas();
+    ANDROID_API void destroyCanvasAndSurface();
 
     ANDROID_API void invokeFunctor(Functor* functor, bool waitForCompletion);