diff options
author | 2016-03-01 13:27:54 -0800 | |
---|---|---|
committer | 2016-03-02 10:29:15 -0800 | |
commit | 678ff81105753656aa4822f4f675ef96dc9d2b83 (patch) | |
tree | 695ff095d9b5c839a51316c9b3f8976682be7d5e /libs/hwui/FrameBuilder.cpp | |
parent | 82197c33a23a130acd93dcf54e70138a7e7ba970 (diff) |
Clip projected ripples to outlines
bug:27343928
Also fixes positioning of ripples to a scrolled projection receiver.
Change-Id: I74b7233c46d7c15839ca8bf50e188ba6646d7432
Diffstat (limited to 'libs/hwui/FrameBuilder.cpp')
-rw-r--r-- | libs/hwui/FrameBuilder.cpp | 33 |
1 files changed, 15 insertions, 18 deletions
diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp index 04de98afe85c..b586a0109c27 100644 --- a/libs/hwui/FrameBuilder.cpp +++ b/libs/hwui/FrameBuilder.cpp @@ -389,34 +389,31 @@ void FrameBuilder::deferShadow(const RenderNodeOp& casterNodeOp) { } void FrameBuilder::deferProjectedChildren(const RenderNode& renderNode) { - const SkPath* projectionReceiverOutline = renderNode.properties().getOutline().getPath(); int count = mCanvasState.save(SaveFlags::MatrixClip); + const SkPath* projectionReceiverOutline = renderNode.properties().getOutline().getPath(); - // can't be null, since DL=null node rejection happens before deferNodePropsAndOps - const DisplayList& displayList = *(renderNode.getDisplayList()); - - const RecordedOp* op = (displayList.getOps()[displayList.projectionReceiveIndex]); - const RenderNodeOp* backgroundOp = static_cast<const RenderNodeOp*>(op); - const RenderProperties& backgroundProps = backgroundOp->renderNode->properties(); - - // Transform renderer to match background we're projecting onto - // (by offsetting canvas by translationX/Y of background rendernode, since only those are set) - mCanvasState.translate(backgroundProps.getTranslationX(), backgroundProps.getTranslationY()); - - // If the projection receiver has an outline, we mask projected content to it - // (which we know, apriori, are all tessellated paths) - mCanvasState.setProjectionPathMask(mAllocator, projectionReceiverOutline); + SkPath transformedMaskPath; // on stack, since BakedOpState makes a deep copy + if (projectionReceiverOutline) { + // transform the mask for this projector into render target space + // TODO: consider combining both transforms by stashing transform instead of applying + SkMatrix skCurrentTransform; + mCanvasState.currentTransform()->copyTo(skCurrentTransform); + projectionReceiverOutline->transform( + skCurrentTransform, + &transformedMaskPath); + mCanvasState.setProjectionPathMask(mAllocator, &transformedMaskPath); + } - // draw projected nodes for (size_t i = 0; i < renderNode.mProjectedNodes.size(); i++) { RenderNodeOp* childOp = renderNode.mProjectedNodes[i]; - int restoreTo = mCanvasState.save(SaveFlags::Matrix); + + // Apply transform between ancestor and projected descendant mCanvasState.concatMatrix(childOp->transformFromCompositingAncestor); + deferRenderNodeOpImpl(*childOp); mCanvasState.restoreToCount(restoreTo); } - mCanvasState.restoreToCount(count); } |