Add a RenderBuffer object to store stencil buffers.
Bug #7146141

This change is needed to add a render buffer cache to avoid
creating and destroying stencil buffers on every frame.

This change also allows the renderer to use a 1 bit or 4 bit
stencil buffer whenever possible.

Finally this change fixes a bug introduced by a previous CL
which causes the stencil buffer to not be updated in certain
conditions. The fix relies on a new optional parameter in
drawColorRects() that can be used to avoid performing a
quickReject on rectangles generated by the clip region.

Change-Id: I2f55a8e807009887b276a83cde9f53fd5c01199f
diff --git a/libs/hwui/Stencil.cpp b/libs/hwui/Stencil.cpp
index 4fcd51d..ba2e6f2 100644
--- a/libs/hwui/Stencil.cpp
+++ b/libs/hwui/Stencil.cpp
@@ -14,14 +14,23 @@
  * limitations under the License.
  */
 
-#include <GLES2/gl2.h>
-
+#include "Extensions.h"
 #include "Properties.h"
 #include "Stencil.h"
 
+#include <GLES2/gl2ext.h>
+
 namespace android {
 namespace uirenderer {
 
+#if DEBUG_STENCIL
+#define STENCIL_WRITE_VALUE 0xff
+#define STENCIL_MASK_VALUE 0xff
+#else
+#define STENCIL_WRITE_VALUE 0x1
+#define STENCIL_MASK_VALUE 0x1
+#endif
+
 Stencil::Stencil(): mState(kDisabled) {
 }
 
@@ -29,6 +38,18 @@
     return STENCIL_BUFFER_SIZE;
 }
 
+GLenum Stencil::getSmallestStencilFormat() {
+#if !DEBUG_STENCIL
+    const Extensions& extensions = Extensions::getInstance();
+    if (extensions.has1BitStencil()) {
+        return GL_STENCIL_INDEX1_OES;
+    } else if (extensions.has4BitStencil()) {
+        return GL_STENCIL_INDEX4_OES;
+    }
+#endif
+    return GL_STENCIL_INDEX8;
+}
+
 void Stencil::clear() {
     glClearStencil(0);
     glClear(GL_STENCIL_BUFFER_BIT);
@@ -37,7 +58,7 @@
 void Stencil::enableTest() {
     if (mState != kTest) {
         enable();
-        glStencilFunc(GL_EQUAL, 0xff, 0xff);
+        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);
@@ -48,7 +69,7 @@
 void Stencil::enableWrite() {
     if (mState != kWrite) {
         enable();
-        glStencilFunc(GL_ALWAYS, 0xff, 0xff);
+        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);