Skip to content

Commit

Permalink
[Impeller] port clip stack fixes to new canvas. (#54727)
Browse files Browse the repository at this point in the history
From c99eda4
  • Loading branch information
jonahwilliams authored Aug 28, 2024
1 parent e8521f6 commit a80d775
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 16 deletions.
36 changes: 24 additions & 12 deletions impeller/aiks/experimental_canvas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// found in the LICENSE file.

#include "impeller/aiks/experimental_canvas.h"
#include <limits>
#include "fml/logging.h"
#include "fml/trace_event.h"
#include "impeller/aiks/canvas.h"
Expand Down Expand Up @@ -57,6 +58,7 @@ static void ApplyFramebufferBlend(Entity& entity) {
static std::shared_ptr<Texture> FlipBackdrop(
std::vector<LazyRenderingConfig>& render_passes,
Point global_pass_position,
size_t current_clip_depth,
EntityPassClipStack& clip_coverage_stack,
ContentContext& renderer) {
auto rendering_config = std::move(render_passes.back());
Expand Down Expand Up @@ -132,16 +134,21 @@ static std::shared_ptr<Texture> FlipBackdrop(

// Restore any clips that were recorded before the backdrop filter was
// applied.
auto& replay_entities = clip_coverage_stack.GetReplayEntities();
for (const auto& replay : replay_entities) {
clip_coverage_stack.ActivateClipReplay();

// If there are any pending clips to replay, render any that may affect
// the entity we're about to render.
while (const EntityPassClipStack::ReplayResult* next_replay_clip =
clip_coverage_stack.GetNextReplayResult(current_clip_depth)) {
auto& replay_entity = next_replay_clip->entity;
SetClipScissor(
clip_coverage_stack.CurrentClipCoverage(),
next_replay_clip->clip_coverage,
*render_passes.back().inline_pass_context->GetRenderPass(0).pass,
global_pass_position);
if (!replay.entity.Render(
if (!replay_entity.Render(
renderer,
*render_passes.back().inline_pass_context->GetRenderPass(0).pass)) {
VALIDATION_LOG << "Failed to render entity for clip restore.";
VALIDATION_LOG << "Failed to render entity for clip replay.";
}
}

Expand Down Expand Up @@ -375,8 +382,12 @@ void ExperimentalCanvas::SaveLayer(
return filter;
};

auto input_texture = FlipBackdrop(render_passes_, GetGlobalPassPosition(),
clip_coverage_stack_, renderer_);
auto input_texture = FlipBackdrop(render_passes_, //
GetGlobalPassPosition(), //
std::numeric_limits<uint32_t>::max(), //
clip_coverage_stack_, //
renderer_ //
);
if (!input_texture) {
// Validation failures are logged in FlipBackdrop.
return;
Expand Down Expand Up @@ -532,9 +543,9 @@ bool ExperimentalCanvas::Restore() {
// to the render target texture so far need to execute before it's bound
// for blending (otherwise the blend pass will end up executing before
// all the previous commands in the active pass).
auto input_texture =
FlipBackdrop(render_passes_, GetGlobalPassPosition(),
clip_coverage_stack_, renderer_);
auto input_texture = FlipBackdrop(
render_passes_, GetGlobalPassPosition(),
element_entity.GetClipDepth(), clip_coverage_stack_, renderer_);
if (!input_texture) {
return false;
}
Expand Down Expand Up @@ -712,8 +723,9 @@ void ExperimentalCanvas::AddRenderEntityToCurrentPass(Entity entity,
// to the render target texture so far need to execute before it's bound
// for blending (otherwise the blend pass will end up executing before
// all the previous commands in the active pass).
auto input_texture = FlipBackdrop(render_passes_, GetGlobalPassPosition(),
clip_coverage_stack_, renderer_);
auto input_texture =
FlipBackdrop(render_passes_, GetGlobalPassPosition(),
entity.GetClipDepth(), clip_coverage_stack_, renderer_);
if (!input_texture) {
return;
}
Expand Down
3 changes: 2 additions & 1 deletion impeller/entity/entity_pass.cc
Original file line number Diff line number Diff line change
Expand Up @@ -852,7 +852,8 @@ bool EntityPass::RenderElement(Entity& element_entity,
// If there are any pending clips to replay, render any that may affect
// the entity we're about to render.
while (const EntityPassClipStack::ReplayResult* next_replay_clip =
clip_coverage_stack.GetNextReplayResult(element_entity)) {
clip_coverage_stack.GetNextReplayResult(
element_entity.GetClipDepth())) {
auto& replay_entity = next_replay_clip->entity;
SetClipScissor(next_replay_clip->clip_coverage, *result.pass,
global_pass_position);
Expand Down
4 changes: 2 additions & 2 deletions impeller/entity/entity_pass_clip_stack.cc
Original file line number Diff line number Diff line change
Expand Up @@ -178,15 +178,15 @@ void EntityPassClipStack::ActivateClipReplay() {
}

const EntityPassClipStack::ReplayResult*
EntityPassClipStack::GetNextReplayResult(const Entity& entity) {
EntityPassClipStack::GetNextReplayResult(size_t current_clip_depth) {
if (next_replay_index_ >=
subpass_state_.back().rendered_clip_entities.size()) {
// No clips need to be replayed.
return nullptr;
}
ReplayResult* next_replay =
&subpass_state_.back().rendered_clip_entities[next_replay_index_];
if (next_replay->entity.GetClipDepth() < entity.GetClipDepth()) {
if (next_replay->entity.GetClipDepth() < current_clip_depth) {
// The next replay clip doesn't affect the current entity, so don't replay
// it yet.
return nullptr;
Expand Down
2 changes: 1 addition & 1 deletion impeller/entity/entity_pass_clip_stack.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class EntityPassClipStack {

/// @brief Returns the next Entity that should be replayed. If there are no
/// enities to replay, then nullptr is returned.
const ReplayResult* GetNextReplayResult(const Entity& entity);
const ReplayResult* GetNextReplayResult(size_t current_clip_depth);

// Visible for testing.
const std::vector<ClipCoverageLayer> GetClipCoverageLayers() const;
Expand Down

0 comments on commit a80d775

Please sign in to comment.