Improve clip support (add intersect, union and replace.)
This change also modifies the way the clip is stored. The clip is now
always stored in screen-space coordinates.
Change-Id: I96375784d82dfe975bc6477a159e6866e7052487
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index decfecf..d950ffa 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -244,7 +244,7 @@
glBindFramebuffer(GL_FRAMEBUFFER, previous->fbo);
// Restore the clip from the previous snapshot
- const Rect& clip = previous->getMappedClip();
+ const Rect& clip = previous->clipRect;
glScissor(clip.left, mHeight - clip.bottom, clip.getWidth(), clip.getHeight());
Layer* layer = current->layer;
@@ -339,12 +339,11 @@
saveSnapshot();
// TODO: This doesn't preserve other transformations (check Skia first)
mSnapshot->transform.loadTranslate(-left, -top, 0.0f);
- mSnapshot->setClip(left, top, right, bottom);
+ mSnapshot->setClip(0.0f, 0.0f, right - left, bottom - top);
mSnapshot->height = bottom - top;
setScissorFromClip();
- mSnapshot->flags = Snapshot::kFlagDirtyTransform | Snapshot::kFlagDirtyOrtho |
- Snapshot::kFlagClipSet;
+ mSnapshot->flags = Snapshot::kFlagDirtyOrtho | Snapshot::kFlagClipSet;
mSnapshot->orthoMatrix.load(mOrthoMatrix);
// Change the ortho projection
@@ -359,22 +358,18 @@
void OpenGLRenderer::translate(float dx, float dy) {
mSnapshot->transform.translate(dx, dy, 0.0f);
- mSnapshot->flags |= Snapshot::kFlagDirtyTransform;
}
void OpenGLRenderer::rotate(float degrees) {
mSnapshot->transform.rotate(degrees, 0.0f, 0.0f, 1.0f);
- mSnapshot->flags |= Snapshot::kFlagDirtyTransform;
}
void OpenGLRenderer::scale(float sx, float sy) {
mSnapshot->transform.scale(sx, sy, 1.0f);
- mSnapshot->flags |= Snapshot::kFlagDirtyTransform;
}
void OpenGLRenderer::setMatrix(SkMatrix* matrix) {
mSnapshot->transform.load(*matrix);
- mSnapshot->flags |= Snapshot::kFlagDirtyTransform;
}
void OpenGLRenderer::getMatrix(SkMatrix* matrix) {
@@ -384,7 +379,6 @@
void OpenGLRenderer::concatMatrix(SkMatrix* matrix) {
mat4 m(*matrix);
mSnapshot->transform.multiply(m);
- mSnapshot->flags |= Snapshot::kFlagDirtyTransform;
}
///////////////////////////////////////////////////////////////////////////////
@@ -392,38 +386,26 @@
///////////////////////////////////////////////////////////////////////////////
void OpenGLRenderer::setScissorFromClip() {
- const Rect& clip = mSnapshot->getMappedClip();
+ const Rect& clip = mSnapshot->clipRect;
glScissor(clip.left, mSnapshot->height - clip.bottom, clip.getWidth(), clip.getHeight());
}
const Rect& OpenGLRenderer::getClipBounds() {
- return mSnapshot->clipRect;
+ return mSnapshot->getLocalClip();
}
bool OpenGLRenderer::quickReject(float left, float top, float right, float bottom) {
- /*
- * The documentation of quickReject() indicates that the specified rect
- * is transformed before being compared to the clip rect. However, the
- * clip rect is not stored transformed in the snapshot and can thus be
- * compared directly
- *
- * The following code can be used instead to performed a mapped comparison:
- *
- * mSnapshot->transform.mapRect(r);
- * const Rect& clip = mSnapshot->getMappedClip();
- * return !clip.intersects(r);
- */
Rect r(left, top, right, bottom);
+ mSnapshot->transform.mapRect(r);
return !mSnapshot->clipRect.intersects(r);
}
-bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom) {
- bool clipped = mSnapshot->clip(left, top, right, bottom);
+bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) {
+ bool clipped = mSnapshot->clip(left, top, right, bottom, op);
if (clipped) {
- mSnapshot->flags |= Snapshot::kFlagClipSet;
setScissorFromClip();
}
- return clipped;
+ return !mSnapshot->clipRect.isEmpty();
}
///////////////////////////////////////////////////////////////////////////////
@@ -504,7 +486,7 @@
}
void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
- const Rect& clip = mSnapshot->getMappedClip();
+ const Rect& clip = mSnapshot->clipRect;
drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode, true);
}
@@ -584,22 +566,20 @@
mModelView.loadTranslate(left, top, 0.0f);
mModelView.scale(right - left, bottom - top, 1.0f);
- // TODO: Pick the program matching the current shader
- sp<DrawColorProgram> program = mDrawColorProgram;
- if (!useProgram(program)) {
+ if (!useProgram(mDrawColorProgram)) {
const GLvoid* p = &gDrawColorVertices[0].position[0];
- glVertexAttribPointer(program->position, 2, GL_FLOAT, GL_FALSE,
+ glVertexAttribPointer(mDrawColorProgram->position, 2, GL_FLOAT, GL_FALSE,
gDrawColorVertexStride, p);
}
if (!ignoreTransform) {
- program->set(mOrthoMatrix, mModelView, mSnapshot->transform);
+ mDrawColorProgram->set(mOrthoMatrix, mModelView, mSnapshot->transform);
} else {
mat4 identity;
- program->set(mOrthoMatrix, mModelView, identity);
+ mDrawColorProgram->set(mOrthoMatrix, mModelView, identity);
}
- glUniform4f(program->color, r, g, b, a);
+ glUniform4f(mDrawColorProgram->color, r, g, b, a);
glDrawArrays(GL_TRIANGLE_STRIP, 0, gDrawColorVertexCount);
}