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 all commits
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
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