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/Extensions.h b/libs/hwui/Extensions.h
index bdaa3cc..a069a6a 100644
--- a/libs/hwui/Extensions.h
+++ b/libs/hwui/Extensions.h
@@ -17,62 +17,24 @@
 #ifndef ANDROID_HWUI_EXTENSIONS_H
 #define ANDROID_HWUI_EXTENSIONS_H
 
+#include <utils/Singleton.h>
 #include <utils/SortedVector.h>
 #include <utils/String8.h>
 
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 
-#include "Debug.h"
-
 namespace android {
 namespace uirenderer {
 
 ///////////////////////////////////////////////////////////////////////////////
-// Defines
-///////////////////////////////////////////////////////////////////////////////
-
-// Debug
-#if DEBUG_EXTENSIONS
-    #define EXT_LOGD(...) ALOGD(__VA_ARGS__)
-#else
-    #define EXT_LOGD(...)
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
 // Classes
 ///////////////////////////////////////////////////////////////////////////////
 
-class Extensions {
+class Extensions: public Singleton<Extensions> {
 public:
-    Extensions() {
-        const char* buffer = (const char*) glGetString(GL_EXTENSIONS);
-        const char* current = buffer;
-        const char* head = current;
-        EXT_LOGD("Available GL extensions:");
-        do {
-            head = strchr(current, ' ');
-            String8 s(current, head ? head - current : strlen(current));
-            if (s.length()) {
-                mExtensionList.add(s);
-                EXT_LOGD("  %s", s.string());
-            }
-            current = head + 1;
-        } while (head);
-
-        mHasNPot = hasExtension("GL_OES_texture_npot");
-        mHasFramebufferFetch = hasExtension("GL_NV_shader_framebuffer_fetch");
-        mHasDiscardFramebuffer = hasExtension("GL_EXT_discard_framebuffer");
-        mHasDebugMarker = hasExtension("GL_EXT_debug_marker");
-        mHasDebugLabel = hasExtension("GL_EXT_debug_label");
-        mHasTiledRendering = hasExtension("GL_QCOM_tiled_rendering");
-
-        mExtensions = strdup(buffer);
-    }
-
-    ~Extensions() {
-        free(mExtensions);
-    }
+    Extensions();
+    ~Extensions();
 
     inline bool hasNPot() const { return mHasNPot; }
     inline bool hasFramebufferFetch() const { return mHasFramebufferFetch; }
@@ -80,17 +42,16 @@
     inline bool hasDebugMarker() const { return mHasDebugMarker; }
     inline bool hasDebugLabel() const { return mHasDebugLabel; }
     inline bool hasTiledRendering() const { return mHasTiledRendering; }
+    inline bool has1BitStencil() const { return mHas1BitStencil; }
+    inline bool has4BitStencil() const { return mHas4BitStencil; }
 
-    bool hasExtension(const char* extension) const {
-        const String8 s(extension);
-        return mExtensionList.indexOf(s) >= 0;
-    }
+    bool hasExtension(const char* extension) const;
 
-    void dump() {
-        ALOGD("Supported extensions:\n%s", mExtensions);
-    }
+    void dump() const;
 
 private:
+    friend class Singleton<Extensions>;
+
     SortedVector<String8> mExtensionList;
 
     char* mExtensions;
@@ -101,6 +62,8 @@
     bool mHasDebugMarker;
     bool mHasDebugLabel;
     bool mHasTiledRendering;
+    bool mHas1BitStencil;
+    bool mHas4BitStencil;
 }; // class Extensions
 
 }; // namespace uirenderer