Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 20 additions & 12 deletions impeller/aiks/experimental_canvas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,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 +133,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 +381,9 @@ void ExperimentalCanvas::SaveLayer(
return filter;
};

auto input_texture = FlipBackdrop(render_passes_, GetGlobalPassPosition(),
clip_coverage_stack_, renderer_);
auto input_texture =
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When doing the clip replay for a bdf, what value should be used as the clip depth comparison? @bdero

Copy link
Member

@bdero bdero Aug 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for the late reply. When doing a clip restore:

  • The MSAA backdrop should be the very first thing drawn, but I set the clip depth to std::numeric_limits<uint32_t>::max() anyway. This helps to ensure we're not unnecessarily writing depth for the MSAA backdrop (the depth/stencil are disabled with TextureContents::SetStencilEnabled(false)).
  • Afterwards, each clip being replayed should have the same depth they had the first time they were being drawn.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated this to use max int32 for bdf restores, other flip backdrops (emulated advanced blend) use the entity depth

FlipBackdrop(render_passes_, GetGlobalPassPosition(), current_depth_,
clip_coverage_stack_, renderer_);
if (!input_texture) {
// Validation failures are logged in FlipBackdrop.
return;
Expand Down Expand Up @@ -532,9 +539,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 +719,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