Clip projected ripples to outlines
bug:27343928
Also fixes positioning of ripples to a scrolled projection receiver.
Change-Id: I74b7233c46d7c15839ca8bf50e188ba6646d7432
diff --git a/libs/hwui/BakedOpState.cpp b/libs/hwui/BakedOpState.cpp
index 682bd04..26653f7 100644
--- a/libs/hwui/BakedOpState.cpp
+++ b/libs/hwui/BakedOpState.cpp
@@ -63,9 +63,22 @@
clipState = nullptr;
clippedBounds.setEmpty();
} else {
- // Not rejected! compute true clippedBounds and clipSideFlags
+ // Not rejected! compute true clippedBounds, clipSideFlags, and path mask
clipSideFlags = computeClipSideFlags(clipRect, clippedBounds);
clippedBounds.doIntersect(clipRect);
+
+ if (CC_UNLIKELY(snapshot.projectionPathMask)) {
+ // map projection path mask from render target space into op space,
+ // so intersection with op geometry is possible
+ Matrix4 inverseTransform;
+ inverseTransform.loadInverse(transform);
+ SkMatrix skInverseTransform;
+ inverseTransform.copyTo(skInverseTransform);
+
+ auto localMask = allocator.create<SkPath>();
+ snapshot.projectionPathMask->transform(skInverseTransform, localMask);
+ localProjectionPathMask = localMask;
+ }
}
}
@@ -73,13 +86,15 @@
: transform(*snapshot.transform)
, clipState(snapshot.mutateClipArea().serializeClip(allocator))
, clippedBounds(clipState->rect)
- , clipSideFlags(OpClipSideFlags::Full) {}
+ , clipSideFlags(OpClipSideFlags::Full)
+ , localProjectionPathMask(nullptr) {}
ResolvedRenderState::ResolvedRenderState(const ClipRect* clipRect, const Rect& dstRect)
: transform(Matrix4::identity())
, clipState(clipRect)
, clippedBounds(dstRect)
- , clipSideFlags(computeClipSideFlags(clipRect->rect, dstRect)) {
+ , clipSideFlags(computeClipSideFlags(clipRect->rect, dstRect))
+ , localProjectionPathMask(nullptr) {
clippedBounds.doIntersect(clipRect->rect);
}