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);