New layers API for Views.

This API can be used to back a view and its children with either a
software layer (bitmap) or hardware layer (FBO). Layers have
various usages, including color filtering and performance
improvements during animations.

Change-Id: Ifc3bea847918042730fc5a8c2d4206dd6c9420a3
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index a780183..7d54d3b 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -26,6 +26,7 @@
 #include <SkXfermode.h>
 
 #include "Rect.h"
+#include "SkiaColorFilter.h"
 
 namespace android {
 namespace uirenderer {
@@ -93,6 +94,11 @@
      * have been drawn.
      */
     Region region;
+
+    /**
+     * Color filter used to draw this layer. Optional.
+     */
+    SkiaColorFilter* colorFilter;
 }; // struct Layer
 
 }; // namespace uirenderer
diff --git a/libs/hwui/LayerCache.cpp b/libs/hwui/LayerCache.cpp
index 9ce0359..ec186a4 100644
--- a/libs/hwui/LayerCache.cpp
+++ b/libs/hwui/LayerCache.cpp
@@ -102,6 +102,7 @@
         layer->blend = true;
         layer->empty = true;
         layer->fbo = 0;
+        layer->colorFilter = NULL;
 
         glGenTextures(1, &layer->texture);
         glBindTexture(GL_TEXTURE_2D, layer->texture);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index eec8d8c..9613c5f 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -406,6 +406,7 @@
     layer->layer.set(bounds);
     layer->texCoords.set(0.0f, bounds.getHeight() / float(layer->height),
             bounds.getWidth() / float(layer->width), 0.0f);
+    layer->colorFilter = mColorFilter;
 
     // Save the layer in the snapshot
     snapshot->flags |= Snapshot::kFlagIsLayer;
@@ -459,7 +460,6 @@
     snapshot->flags |= Snapshot::kFlagIsFboLayer;
     snapshot->fbo = layer->fbo;
     snapshot->resetTransform(-bounds.left, -bounds.top, 0.0f);
-    //snapshot->resetClip(0.0f, 0.0f, bounds.getWidth(), bounds.getHeight());
     snapshot->resetClip(clip.left, clip.top, clip.right, clip.bottom);
     snapshot->viewport.set(0.0f, 0.0f, bounds.getWidth(), bounds.getHeight());
     snapshot->height = bounds.getHeight();
@@ -544,7 +544,13 @@
     // drawing only the dirty region
     if (fboLayer) {
         dirtyLayer(rect.left, rect.top, rect.right, rect.bottom, *previous->transform);
+        if (layer->colorFilter) {
+            setupColorFilter(layer->colorFilter);
+        }
         composeLayerRegion(layer, rect);
+        if (layer->colorFilter) {
+            resetColorFilter();
+        }
     } else {
         dirtyLayer(rect.left, rect.top, rect.right, rect.bottom);
         composeLayerRect(layer, rect, true);