Clipping performance improvements

Create a ClipArea class to handle tracking clip regions. This class can
select the most efficient implementation depending on the types of
clipping presented.

ClipArea re-used the rectangle and region-based clipping
implementations as well as adding a "list of rotated rectangles"
approach that is more efficient for rotated views with children.

Change-Id: I2133761a2462ebc0852b394220e265974b3086f0
diff --git a/libs/hwui/Stencil.cpp b/libs/hwui/Stencil.cpp
index 8ce57db..f56a02e 100644
--- a/libs/hwui/Stencil.cpp
+++ b/libs/hwui/Stencil.cpp
@@ -32,7 +32,8 @@
 #define STENCIL_MASK_VALUE 0x1
 #endif
 
-Stencil::Stencil(): mState(kDisabled) {
+Stencil::Stencil()
+        : mState(kDisabled) {
 }
 
 uint8_t Stencil::getStencilSize() {
@@ -56,24 +57,36 @@
     glClear(GL_STENCIL_BUFFER_BIT);
 }
 
-void Stencil::enableTest() {
+void Stencil::enableTest(int incrementThreshold) {
     if (mState != kTest) {
         enable();
-        glStencilFunc(GL_EQUAL, STENCIL_WRITE_VALUE, STENCIL_MASK_VALUE);
+        if (incrementThreshold > 0) {
+            glStencilFunc(GL_EQUAL, incrementThreshold, 0xff);
+        } else {
+            glStencilFunc(GL_EQUAL, STENCIL_WRITE_VALUE, STENCIL_MASK_VALUE);
+        }
         // We only want to test, let's keep everything
         glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+        glStencilMask(0);
         mState = kTest;
     }
 }
 
-void Stencil::enableWrite() {
+void Stencil::enableWrite(int incrementThreshold) {
     if (mState != kWrite) {
         enable();
-        glStencilFunc(GL_ALWAYS, STENCIL_WRITE_VALUE, STENCIL_MASK_VALUE);
-        // The test always passes so the first two values are meaningless
-        glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+        if (incrementThreshold > 0) {
+            glStencilFunc(GL_ALWAYS, 1, 0xff);
+            // The test always passes so the first two values are meaningless
+            glStencilOp(GL_INCR, GL_INCR, GL_INCR);
+        } else {
+            glStencilFunc(GL_ALWAYS, STENCIL_WRITE_VALUE, STENCIL_MASK_VALUE);
+            // The test always passes so the first two values are meaningless
+            glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+        }
         glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+        glStencilMask(0xff);
         mState = kWrite;
     }
 }