-
Notifications
You must be signed in to change notification settings - Fork 6k
[Impeller] fix clip culling with exp canvas. #54701
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -82,6 +82,20 @@ bool ClipContents::CanInheritOpacity(const Entity& entity) const { | |||
|
||||
void ClipContents::SetInheritedOpacity(Scalar opacity) {} | ||||
|
||||
bool ClipContents::CanSkip(ISize render_pass_size, const Matrix& ctm) const { | ||||
if (clip_op_ == Entity::ClipOperation::kIntersect && | ||||
geometry_->IsAxisAlignedRect() && ctm.IsTranslationScaleOnly()) { | ||||
std::optional<Rect> coverage = geometry_->GetCoverage(ctm); | ||||
if (coverage.has_value() && | ||||
coverage->Contains(Rect::MakeSize(render_pass_size))) { | ||||
// Skip axis-aligned intersect clips that cover the whole render target | ||||
// since they won't draw anything to the depth buffer. | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The DL code can deal with non-axis alignment but unfortunately it doesn't have access to this information. If we are axis aligned then this is the fast answer, but if we aren't then a slightly slower answer is to reverse transform the existin clip bounds corners by the ctm and then see if they are inside the geometry. See:
Also, it uses a different test - IsAligned2D instead of IsTranslationScaleOnly. Aligned allows for 90 degree rotations I think. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, why only do this on the render pass size? Why not skip it if it covers the entire existing clip bounds? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm, we actually are also checking the clip bounds. These should already include the render pass size. Maybe this logic isn't necessary at all There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ahh, so the problem is that we always report the clip coverage as changing: Even if the new clip coverage is bigger than the old clip coverage. We could move this check into the clip coverage stack and simplify this everywhere. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, lets just move this logic into the clip coverage stack |
||||
return true; | ||||
} | ||||
} | ||||
return false; | ||||
} | ||||
|
||||
bool ClipContents::Render(const ContentContext& renderer, | ||||
const Entity& entity, | ||||
RenderPass& pass) const { | ||||
|
@@ -91,17 +105,8 @@ bool ClipContents::Render(const ContentContext& renderer, | |||
|
||||
using VS = ClipPipeline::VertexShader; | ||||
|
||||
if (clip_op_ == Entity::ClipOperation::kIntersect && | ||||
geometry_->IsAxisAlignedRect() && | ||||
entity.GetTransform().IsTranslationScaleOnly()) { | ||||
std::optional<Rect> coverage = | ||||
geometry_->GetCoverage(entity.GetTransform()); | ||||
if (coverage.has_value() && | ||||
coverage->Contains(Rect::MakeSize(pass.GetRenderTargetSize()))) { | ||||
// Skip axis-aligned intersect clips that cover the whole render target | ||||
// since they won't draw anything to the depth buffer. | ||||
return true; | ||||
} | ||||
if (CanSkip(pass.GetRenderTargetSize(), entity.GetTransform())) { | ||||
return true; | ||||
} | ||||
|
||||
VS::FrameInfo info; | ||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once we switch to exp canvas we can delete the cull rect and just use the clip stack which is 99% the same data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the intention here is that if something outside of a DL applies an image filter then you need to cull the sub-dl by the "GetSourceCoverage" of that filter. No, it doesn't take that into account, the caller specifying the cull rect was supposed to...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, wait, layers. We do expand the bounds of sub-layers by a filter applied on a parent layer...
engine/display_list/dl_builder.cc
Line 680 in 09fa101
If rtree, then here:
engine/display_list/dl_builder.cc
Line 722 in 09fa101
And if no rtree, then here:
engine/display_list/dl_builder.cc
Line 730 in 09fa101
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment isn't really accurate. I updated it to document that the cull rect logic gets deleted with new canvas.