mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Impeller] port clip stack fixes to new canvas. (flutter/engine#54727)
From adbc360970
This commit is contained in:
parent
62541b1434
commit
5ecc028848
@ -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"
|
||||
@ -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());
|
||||
@ -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.";
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -178,7 +178,7 @@ 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.
|
||||
@ -186,7 +186,7 @@ EntityPassClipStack::GetNextReplayResult(const Entity& entity) {
|
||||
}
|
||||
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;
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user