Implement clipRect with a transform, clipRegion & clipPath
Bug #7146141
When non-rectangular clipping occurs in a layer the render buffer
used as the stencil buffer is not cached. If this happens on a
View's hardware layer the render buffer will live for as long
as the layer is bound to the view. When a stencil buffer is
required because of a call to Canvas.saveLayer() it will be allocated
on every frame. A future change will address this problem.
If "show GPU overdraw" is enabled, non-rectangular clips are not
supported anymore and we fall back to rectangular clips instead.
This is a limitation imposed by OpenGL ES that cannot be worked
around at this time.
This change also improves the Matrix4 implementation to easily
detect when a rect remains a rect after transform.
Change-Id: I0e69fb901792d38bc0c4ca1bf9fdb02d7db415b9
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 181eb6c..9ef4894 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -48,7 +48,12 @@
Layer(const uint32_t layerWidth, const uint32_t layerHeight);
~Layer();
- void removeFbo();
+ /**
+ * Calling this method will remove (either by recycling or
+ * destroying) the associated FBO, if present, and any render
+ * buffer (stencil for instance.)
+ */
+ void removeFbo(bool flush = true);
/**
* Sets this layer's region to a rectangle. Computes the appropriate
@@ -134,6 +139,14 @@
return fbo;
}
+ inline void setStencilRenderBuffer(GLuint renderBuffer) {
+ this->stencil = renderBuffer;
+ }
+
+ inline GLuint getStencilRenderBuffer() {
+ return stencil;
+ }
+
inline GLuint getTexture() {
return texture.id;
}
@@ -212,10 +225,6 @@
texture.id = 0;
}
- inline void deleteFbo() {
- if (fbo) glDeleteFramebuffers(1, &fbo);
- }
-
inline void allocateTexture(GLenum format, GLenum storage) {
#if DEBUG_LAYERS
ALOGD(" Allocate layer: %dx%d", getWidth(), getHeight());
@@ -275,6 +284,12 @@
GLuint fbo;
/**
+ * Name of the render buffer used as the stencil buffer. If the
+ * name is 0, this layer does not have a stencil buffer.
+ */
+ GLuint stencil;
+
+ /**
* Indicates whether this layer has been used already.
*/
bool empty;