Add support for advanced blend modes with the framebuffer.

This adds the ability to blend with the framebuffer using Darken,
Lighten, Add, Multiply, Overlay and Screen.

Change-Id: Iae01a53797d4ad39c373cba6ff2a42293129da1a
diff --git a/libs/hwui/ProgramCache.h b/libs/hwui/ProgramCache.h
index f211ab6..8f5304d 100644
--- a/libs/hwui/ProgramCache.h
+++ b/libs/hwui/ProgramCache.h
@@ -35,7 +35,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 // Debug
-#define DEBUG_PROGRAM_CACHE 0
+#define DEBUG_PROGRAM_CACHE 1
 
 // Debug
 #if DEBUG_PROGRAM_CACHE
@@ -61,6 +61,7 @@
 #define PROGRAM_MAX_XFERMODE 0x1f
 #define PROGRAM_XFERMODE_SHADER_SHIFT 26
 #define PROGRAM_XFERMODE_COLOR_OP_SHIFT 20
+#define PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT 14
 
 #define PROGRAM_BITMAP_WRAPS_SHIFT 9
 #define PROGRAM_BITMAP_WRAPT_SHIFT 11
@@ -93,7 +94,8 @@
         hasBitmap(false), isBitmapNpot(false), hasGradient(false),
         shadersMode(SkXfermode::kClear_Mode), isBitmapFirst(false),
         bitmapWrapS(GL_CLAMP_TO_EDGE), bitmapWrapT(GL_CLAMP_TO_EDGE),
-        colorOp(kColorNone), colorMode(SkXfermode::kClear_Mode) {
+        colorOp(kColorNone), colorMode(SkXfermode::kClear_Mode),
+        framebufferMode(SkXfermode::kClear_Mode) {
     }
 
     // Texturing
@@ -113,6 +115,10 @@
     int colorOp;
     SkXfermode::Mode colorMode;
 
+    // Framebuffer blending (requires Extensions.hasFramebufferFetch())
+    // Ignored for all values < SkXfermode::kPlus_Mode
+    SkXfermode::Mode framebufferMode;
+
     inline uint32_t getEnumForWrap(GLenum wrap) const {
         switch (wrap) {
             case GL_CLAMP_TO_EDGE:
@@ -156,6 +162,7 @@
             case kColorNone:
                 break;
         }
+        key |= (framebufferMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT;
         return key;
     }
 }; // struct ProgramDescription