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/Snapshot.h b/libs/hwui/Snapshot.h
index 32fee32..96dfab9 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -22,6 +22,8 @@
#include <utils/RefBase.h>
+#include <SkRegion.h>
+
#include "Layer.h"
#include "Matrix.h"
#include "Rect.h"
@@ -40,7 +42,7 @@
*/
class Snapshot: public LightRefBase<Snapshot> {
public:
- Snapshot(): layer(NULL), fbo(0) { }
+ Snapshot(): flags(0x0), previous(NULL), layer(NULL), fbo(0) { }
/**
* Copies the specified snapshot. Only the transform and clip rectangle
@@ -52,12 +54,10 @@
height(s->height),
transform(s->transform),
clipRect(s->clipRect),
- flags(kFlagDirtyTransform),
+ flags(0x0),
previous(s),
layer(NULL),
fbo(s->fbo) {
- mappedClip.set(s->clipRect);
- transform.mapRect(mappedClip);
}
/**
@@ -70,38 +70,48 @@
*/
kFlagClipSet = 0x1,
/**
- * Indicates that the snapshot holds new transform
- * information.
- */
- kFlagDirtyTransform = 0x2,
- /**
* Indicates that this snapshot was created when saving
* a new layer.
*/
- kFlagIsLayer = 0x4,
+ kFlagIsLayer = 0x2,
/**
* Indicates that this snapshot has changed the ortho matrix.
*/
- kFlagDirtyOrtho = 0x8,
+ kFlagDirtyOrtho = 0x4,
};
/**
- * Returns the current clip region mapped by the current transform.
- */
- const Rect& getMappedClip() {
- return mappedClip;
- }
-
- /**
* Intersects the current clip with the new clip rectangle.
*/
- bool clip(float left, float top, float right, float bottom) {
- bool clipped = clipRect.intersect(left, top, right, bottom);
- if (flags & kFlagDirtyTransform) {
- flags &= ~kFlagDirtyTransform;
- mappedClip.set(clipRect);
- transform.mapRect(mappedClip);
+ bool clip(float left, float top, float right, float bottom, SkRegion::Op op) {
+ bool clipped = false;
+
+ Rect r(left, top, right, bottom);
+ transform.mapRect(r);
+
+ switch (op) {
+ case SkRegion::kDifference_Op:
+ break;
+ case SkRegion::kIntersect_Op:
+ clipped = clipRect.intersect(r);
+ break;
+ case SkRegion::kUnion_Op:
+ clipped = clipRect.unionWith(r);
+ break;
+ case SkRegion::kXOR_Op:
+ break;
+ case SkRegion::kReverseDifference_Op:
+ break;
+ case SkRegion::kReplace_Op:
+ clipRect.set(r);
+ clipped = true;
+ break;
}
+
+ if (clipped) {
+ flags |= Snapshot::kFlagClipSet;
+ }
+
return clipped;
}
@@ -110,11 +120,15 @@
*/
void setClip(float left, float top, float right, float bottom) {
clipRect.set(left, top, right, bottom);
- if (flags & kFlagDirtyTransform) {
- flags &= ~kFlagDirtyTransform;
- mappedClip.set(clipRect);
- transform.mapRect(mappedClip);
- }
+ flags |= Snapshot::kFlagClipSet;
+ }
+
+ const Rect& getLocalClip() {
+ mat4 inverse;
+ inverse.loadInverse(transform);
+ localClip.set(clipRect);
+ inverse.mapRect(localClip);
+ return localClip;
}
/**
@@ -129,7 +143,8 @@
mat4 transform;
/**
- * Current clip region.
+ * Current clip region. The clip is stored in canvas-space coordinates,
+ * (screen-space coordinates in the regular case.)
*/
Rect clipRect;
@@ -155,8 +170,8 @@
mat4 orthoMatrix;
private:
- // Clipping rectangle mapped with the transform
- Rect mappedClip;
+ Rect localClip;
+
}; // class Snapshot
}; // namespace uirenderer