Support HardwareLayers in RenderThread

 Also has a few HardwareLayer lifecycle fixes

Change-Id: I6308cb05f8f199eed72189ace768013a46815941
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 34f1961..0c667fd 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -22,7 +22,9 @@
 #include "RenderTask.h"
 #include "RenderThread.h"
 
+#include "../DeferredLayerUpdater.h"
 #include "../DisplayList.h"
+#include "../LayerRenderer.h"
 #include "../Rect.h"
 
 namespace android {
@@ -31,6 +33,7 @@
 
 #define ARGS(method) method ## Args
 
+#define CREATE_BRIDGE0(name) CREATE_BRIDGE(name,,,,,,,,)
 #define CREATE_BRIDGE1(name, a1) CREATE_BRIDGE(name, a1,,,,,,,)
 #define CREATE_BRIDGE2(name, a1, a2) CREATE_BRIDGE(name, a1,a2,,,,,,)
 #define CREATE_BRIDGE3(name, a1, a2, a3) CREATE_BRIDGE(name, a1,a2,a3,,,,,)
@@ -114,13 +117,14 @@
     post(task);
 }
 
-CREATE_BRIDGE3(drawDisplayList, CanvasContext* context, DisplayList* displayList,
-        Rect dirty) {
+CREATE_BRIDGE4(drawDisplayList, CanvasContext* context, DisplayList* displayList,
+        Rect dirty, const Vector<DeferredLayerUpdater*>* layerUpdates) {
     Rect* dirty = &args->dirty;
     if (dirty->bottom == -1 && dirty->left == -1 &&
             dirty->top == -1 && dirty->right == -1) {
         dirty = 0;
     }
+    args->context->processLayerUpdates(args->layerUpdates);
     args->context->drawDisplayList(args->displayList, dirty);
     return NULL;
 }
@@ -131,6 +135,7 @@
     args->context = mContext;
     args->displayList = displayList;
     args->dirty.set(dirtyLeft, dirtyTop, dirtyRight, dirtyBottom);
+    args->layerUpdates = &mLayers;
     // TODO: Switch to post() once some form of thread safety strategy is in place
     postAndWait(task);
 }
@@ -182,6 +187,70 @@
     postAndWait(task);
 }
 
+CREATE_BRIDGE2(createDisplayListLayer, int width, int height) {
+    Layer* layer = LayerRenderer::createRenderLayer(args->width, args->height);
+    if (!layer) return 0;
+
+    OpenGLRenderer* renderer = new LayerRenderer(layer);
+    renderer->initProperties();
+    return new DeferredLayerUpdater(layer, renderer);
+}
+
+DeferredLayerUpdater* RenderProxy::createDisplayListLayer(int width, int height) {
+    SETUP_TASK(createDisplayListLayer);
+    args->width = width;
+    args->height = height;
+    void* retval = postAndWait(task);
+    DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(retval);
+    mLayers.push(layer);
+    return layer;
+}
+
+CREATE_BRIDGE0(createTextureLayer) {
+    Layer* layer = LayerRenderer::createTextureLayer();
+    if (!layer) return 0;
+    return new DeferredLayerUpdater(layer);
+}
+
+DeferredLayerUpdater* RenderProxy::createTextureLayer() {
+    SETUP_TASK(createTextureLayer);
+    void* retval = postAndWait(task);
+    DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(retval);
+    mLayers.push(layer);
+    return layer;
+}
+
+CREATE_BRIDGE1(destroyLayer, Layer* layer) {
+    LayerRenderer::destroyLayer(args->layer);
+    return NULL;
+}
+
+CREATE_BRIDGE3(copyLayerInto, CanvasContext* context, DeferredLayerUpdater* layer,
+        SkBitmap* bitmap) {
+    bool success = args->context->copyLayerInto(args->layer, args->bitmap);
+    return (void*) success;
+}
+
+bool RenderProxy::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
+    SETUP_TASK(copyLayerInto);
+    args->context = mContext;
+    args->layer = layer;
+    args->bitmap = bitmap;
+    return (bool) postAndWait(task);
+}
+
+void RenderProxy::destroyLayer(DeferredLayerUpdater* layer) {
+    for (size_t i = 0; i < mLayers.size(); i++) {
+        if (mLayers[i] == layer) {
+            mLayers.removeAt(i);
+            break;
+        }
+    }
+    SETUP_TASK(destroyLayer);
+    args->layer = layer->detachBackingLayer();
+    post(task);
+}
+
 MethodInvokeRenderTask* RenderProxy::createTask(RunnableMethod method) {
     // TODO: Consider having a small pool of these to avoid alloc churn
     return new MethodInvokeRenderTask(method);