Layer changes

Bug: 17208461

* Switch Layer to be VirtualLightRefBase instead of
  Caches' side-channel ref-counting
* Include active layers in gfxinfo dump
* Run gfxinfo dump on the correct thread
* Dump gfxinfo on Layer creation failure

Change-Id: I28d195699e2334518e215ab28c7a17355aee9678
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 9d2ae8b..b499dd0 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -236,6 +236,8 @@
 
     if (status & DrawGlInfo::kStatusDrew) {
         swapBuffers();
+    } else {
+        mEglManager.cancelFrame();
     }
 
     profiler().finishFrame();
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index e37aafc..9bd6f41 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -73,7 +73,8 @@
         , mAllowPreserveBuffer(load_dirty_regions_property())
         , mCurrentSurface(EGL_NO_SURFACE)
         , mAtlasMap(NULL)
-        , mAtlasMapSize(0) {
+        , mAtlasMapSize(0)
+        , mInFrame(false) {
     mCanSetPreserveBuffer = mAllowPreserveBuffer;
     ALOGD("Use EGL_SWAP_BEHAVIOR_PRESERVED: %s", mAllowPreserveBuffer ? "true" : "false");
 }
@@ -105,10 +106,12 @@
 void EglManager::requireGlContext() {
     LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY, "No EGL context");
 
-    // We can't be certain about the state of the current surface (whether
-    // or not it is destroyed, for example), so err on the side of using
-    // the pbuffer surface which we fully control
-    usePBufferSurface();
+    if (!mInFrame) {
+        // We can't be certain about the state of the current surface (whether
+        // or not it is destroyed, for example), so err on the side of using
+        // the pbuffer surface which we fully control
+        usePBufferSurface();
+    }
 }
 
 void EglManager::loadConfig() {
@@ -251,9 +254,11 @@
         eglQuerySurface(mEglDisplay, surface, EGL_HEIGHT, height);
     }
     eglBeginFrame(mEglDisplay, surface);
+    mInFrame = true;
 }
 
 bool EglManager::swapBuffers(EGLSurface surface) {
+    mInFrame = false;
     eglSwapBuffers(mEglDisplay, surface);
     EGLint err = eglGetError();
     if (CC_LIKELY(err == EGL_SUCCESS)) {
@@ -272,6 +277,10 @@
     return false;
 }
 
+void EglManager::cancelFrame() {
+    mInFrame = false;
+}
+
 bool EglManager::setPreserveBuffer(EGLSurface surface, bool preserve) {
     if (CC_UNLIKELY(!mAllowPreserveBuffer)) return false;
 
diff --git a/libs/hwui/renderthread/EglManager.h b/libs/hwui/renderthread/EglManager.h
index ae03ea1..e12db3a 100644
--- a/libs/hwui/renderthread/EglManager.h
+++ b/libs/hwui/renderthread/EglManager.h
@@ -48,6 +48,7 @@
     bool makeCurrent(EGLSurface surface);
     void beginFrame(EGLSurface surface, EGLint* width, EGLint* height);
     bool swapBuffers(EGLSurface surface);
+    void cancelFrame();
 
     // Returns true iff the surface is now preserving buffers.
     bool setPreserveBuffer(EGLSurface surface, bool preserve);
@@ -80,6 +81,12 @@
     sp<GraphicBuffer> mAtlasBuffer;
     int64_t* mAtlasMap;
     size_t mAtlasMapSize;
+
+    // Whether or not we are in the middle of drawing a frame. This is used
+    // to avoid switching surfaces mid-frame if requireGlContext() is called
+    // TODO: Need to be better about surface/context management so that this isn't
+    // necessary
+    bool mInFrame;
 };
 
 } /* namespace renderthread */
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 8f99b4e..5d55ea6 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -235,12 +235,7 @@
         // waitForCompletion = true is expected to be fairly rare and only
         // happen in destruction. Thus it should be fine to temporarily
         // create a Mutex
-        Mutex mutex;
-        Condition condition;
-        SignalingRenderTask syncTask(task, &mutex, &condition);
-        AutoMutex _lock(mutex);
-        thread.queue(&syncTask);
-        condition.wait(mutex);
+        staticPostAndWait(task);
     } else {
         thread.queue(task);
     }
@@ -258,17 +253,6 @@
     postAndWait(task);
 }
 
-CREATE_BRIDGE1(destroyLayer, Layer* layer) {
-    LayerRenderer::destroyLayer(args->layer);
-    return NULL;
-}
-
-void RenderProxy::enqueueDestroyLayer(Layer* layer) {
-    SETUP_TASK(destroyLayer);
-    args->layer = layer;
-    RenderThread::getInstance().queue(task);
-}
-
 CREATE_BRIDGE2(createTextureLayer, RenderThread* thread, CanvasContext* context) {
     Layer* layer = args->context->createTextureLayer();
     if (!layer) return 0;
@@ -400,6 +384,17 @@
     postAndWait(task);
 }
 
+CREATE_BRIDGE1(outputLogBuffer, int fd) {
+    RenderNode::outputLogBuffer(args->fd);
+    return NULL;
+}
+
+void RenderProxy::outputLogBuffer(int fd) {
+    SETUP_TASK(outputLogBuffer);
+    args->fd = fd;
+    staticPostAndWait(task);
+}
+
 CREATE_BRIDGE4(setTextureAtlas, RenderThread* thread, GraphicBuffer* buffer, int64_t* map, size_t size) {
     CanvasContext::setTextureAtlas(*args->thread, args->buffer, args->map, args->size);
     args->buffer->decStrong(0);
@@ -430,6 +425,19 @@
     return retval;
 }
 
+void* RenderProxy::staticPostAndWait(MethodInvokeRenderTask* task) {
+    RenderThread& thread = RenderThread::getInstance();
+    void* retval;
+    task->setReturnPtr(&retval);
+    Mutex mutex;
+    Condition condition;
+    SignalingRenderTask syncTask(task, &mutex, &condition);
+    AutoMutex _lock(mutex);
+    thread.queue(&syncTask);
+    condition.wait(mutex);
+    return retval;
+}
+
 } /* namespace renderthread */
 } /* namespace uirenderer */
 } /* namespace android */
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index dddf0c7..4989b14 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -81,7 +81,6 @@
 
     ANDROID_API void runWithGlContext(RenderTask* task);
 
-    static void enqueueDestroyLayer(Layer* layer);
     ANDROID_API DeferredLayerUpdater* createTextureLayer();
     ANDROID_API void buildLayer(RenderNode* node);
     ANDROID_API bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
@@ -97,6 +96,7 @@
     ANDROID_API void notifyFramePending();
 
     ANDROID_API void dumpProfileInfo(int fd);
+    ANDROID_API static void outputLogBuffer(int fd);
 
     ANDROID_API void setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t size);
 
@@ -114,6 +114,8 @@
     void post(RenderTask* task);
     void* postAndWait(MethodInvokeRenderTask* task);
 
+    static void* staticPostAndWait(MethodInvokeRenderTask* task);
+
     // Friend class to help with bridging
     friend class RenderProxyBridge;
 };
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 403e164..f887103 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -168,7 +168,7 @@
 void RenderThread::initThreadLocals() {
     initializeDisplayEventReceiver();
     mEglManager = new EglManager(*this);
-    mRenderState = new RenderState();
+    mRenderState = new RenderState(*this);
 }
 
 int RenderThread::displayEventReceiverCallback(int fd, int events, void* data) {