|
3 | 3 | // found in the LICENSE file. |
4 | 4 |
|
5 | 5 | #include "impeller/aiks/experimental_canvas.h" |
| 6 | +#include <limits> |
6 | 7 | #include "fml/logging.h" |
7 | 8 | #include "fml/trace_event.h" |
8 | 9 | #include "impeller/aiks/canvas.h" |
@@ -57,6 +58,7 @@ static void ApplyFramebufferBlend(Entity& entity) { |
57 | 58 | static std::shared_ptr<Texture> FlipBackdrop( |
58 | 59 | std::vector<LazyRenderingConfig>& render_passes, |
59 | 60 | Point global_pass_position, |
| 61 | + size_t current_clip_depth, |
60 | 62 | EntityPassClipStack& clip_coverage_stack, |
61 | 63 | ContentContext& renderer) { |
62 | 64 | auto rendering_config = std::move(render_passes.back()); |
@@ -132,16 +134,21 @@ static std::shared_ptr<Texture> FlipBackdrop( |
132 | 134 |
|
133 | 135 | // Restore any clips that were recorded before the backdrop filter was |
134 | 136 | // applied. |
135 | | - auto& replay_entities = clip_coverage_stack.GetReplayEntities(); |
136 | | - for (const auto& replay : replay_entities) { |
| 137 | + clip_coverage_stack.ActivateClipReplay(); |
| 138 | + |
| 139 | + // If there are any pending clips to replay, render any that may affect |
| 140 | + // the entity we're about to render. |
| 141 | + while (const EntityPassClipStack::ReplayResult* next_replay_clip = |
| 142 | + clip_coverage_stack.GetNextReplayResult(current_clip_depth)) { |
| 143 | + auto& replay_entity = next_replay_clip->entity; |
137 | 144 | SetClipScissor( |
138 | | - clip_coverage_stack.CurrentClipCoverage(), |
| 145 | + next_replay_clip->clip_coverage, |
139 | 146 | *render_passes.back().inline_pass_context->GetRenderPass(0).pass, |
140 | 147 | global_pass_position); |
141 | | - if (!replay.entity.Render( |
| 148 | + if (!replay_entity.Render( |
142 | 149 | renderer, |
143 | 150 | *render_passes.back().inline_pass_context->GetRenderPass(0).pass)) { |
144 | | - VALIDATION_LOG << "Failed to render entity for clip restore."; |
| 151 | + VALIDATION_LOG << "Failed to render entity for clip replay."; |
145 | 152 | } |
146 | 153 | } |
147 | 154 |
|
@@ -375,8 +382,12 @@ void ExperimentalCanvas::SaveLayer( |
375 | 382 | return filter; |
376 | 383 | }; |
377 | 384 |
|
378 | | - auto input_texture = FlipBackdrop(render_passes_, GetGlobalPassPosition(), |
379 | | - clip_coverage_stack_, renderer_); |
| 385 | + auto input_texture = FlipBackdrop(render_passes_, // |
| 386 | + GetGlobalPassPosition(), // |
| 387 | + std::numeric_limits<uint32_t>::max(), // |
| 388 | + clip_coverage_stack_, // |
| 389 | + renderer_ // |
| 390 | + ); |
380 | 391 | if (!input_texture) { |
381 | 392 | // Validation failures are logged in FlipBackdrop. |
382 | 393 | return; |
@@ -532,9 +543,9 @@ bool ExperimentalCanvas::Restore() { |
532 | 543 | // to the render target texture so far need to execute before it's bound |
533 | 544 | // for blending (otherwise the blend pass will end up executing before |
534 | 545 | // all the previous commands in the active pass). |
535 | | - auto input_texture = |
536 | | - FlipBackdrop(render_passes_, GetGlobalPassPosition(), |
537 | | - clip_coverage_stack_, renderer_); |
| 546 | + auto input_texture = FlipBackdrop( |
| 547 | + render_passes_, GetGlobalPassPosition(), |
| 548 | + element_entity.GetClipDepth(), clip_coverage_stack_, renderer_); |
538 | 549 | if (!input_texture) { |
539 | 550 | return false; |
540 | 551 | } |
@@ -712,8 +723,9 @@ void ExperimentalCanvas::AddRenderEntityToCurrentPass(Entity entity, |
712 | 723 | // to the render target texture so far need to execute before it's bound |
713 | 724 | // for blending (otherwise the blend pass will end up executing before |
714 | 725 | // all the previous commands in the active pass). |
715 | | - auto input_texture = FlipBackdrop(render_passes_, GetGlobalPassPosition(), |
716 | | - clip_coverage_stack_, renderer_); |
| 726 | + auto input_texture = |
| 727 | + FlipBackdrop(render_passes_, GetGlobalPassPosition(), |
| 728 | + entity.GetClipDepth(), clip_coverage_stack_, renderer_); |
717 | 729 | if (!input_texture) { |
718 | 730 | return; |
719 | 731 | } |
|
0 commit comments