Fix onTrimMemory for HardwareRenderer

 Also fixes detachFunctor possibly drawing after return

 Bug: 15189843
 Bug: 15990672

Change-Id: I64c48cb674c461a8eeaba407b697e09f72c98ce3
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 9c3cf44..524ee62dd 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -30,6 +30,9 @@
 #include "../OpenGLRenderer.h"
 #include "../Stencil.h"
 
+#define TRIM_MEMORY_COMPLETE 80
+#define TRIM_MEMORY_UI_HIDDEN 20
+
 namespace android {
 namespace uirenderer {
 namespace renderthread {
@@ -156,6 +159,10 @@
     }
 }
 
+void CanvasContext::stopDrawing() {
+    mRenderThread.removeFrameCallback(this);
+}
+
 void CanvasContext::notifyFramePending() {
     ATRACE_CALL();
     mRenderThread.pushBackFrameCallback(this);
@@ -216,8 +223,6 @@
     profiler().startFrame();
 
     TreeInfo info(TreeInfo::MODE_RT_ONLY, mRenderThread.renderState());
-    info.prepareTextures = false;
-
     prepareTree(info);
     if (info.out.canDrawThisFrame) {
         draw();
@@ -241,10 +246,25 @@
     return LayerRenderer::copyLayer(mRenderThread.renderState(), layer->backingLayer(), bitmap);
 }
 
-void CanvasContext::flushCaches(Caches::FlushMode flushMode) {
+void CanvasContext::destroyHardwareResources() {
+    stopDrawing();
     if (mEglManager.hasEglContext()) {
         requireGlContext();
-        Caches::getInstance().flush(flushMode);
+        TreeInfo info(TreeInfo::MODE_DESTROY_RESOURCES, mRenderThread.renderState());
+        mRootRenderNode->prepareTree(info);
+        Caches::getInstance().flush(Caches::kFlushMode_Layers);
+    }
+}
+
+void CanvasContext::trimMemory(RenderThread& thread, int level) {
+    // No context means nothing to free
+    if (!thread.eglManager().hasEglContext()) return;
+
+    if (level >= TRIM_MEMORY_COMPLETE) {
+        Caches::getInstance().flush(Caches::kFlushMode_Full);
+        thread.eglManager().destroy();
+    } else if (level >= TRIM_MEMORY_UI_HIDDEN) {
+        Caches::getInstance().flush(Caches::kFlushMode_Moderate);
     }
 }
 
@@ -264,11 +284,7 @@
 }
 
 void CanvasContext::requireGlContext() {
-    if (mEglSurface != EGL_NO_SURFACE) {
-        makeCurrent();
-    } else {
-        mEglManager.usePBufferSurface();
-    }
+    mEglManager.requireGlContext();
 }
 
 void CanvasContext::setTextureAtlas(RenderThread& thread,