Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 31e4626

Browse files
committed
[Impeller] distinguish between no clear color and transparent black clear color.
1 parent 45b95f2 commit 31e4626

File tree

4 files changed

+42
-14
lines changed

4 files changed

+42
-14
lines changed

impeller/aiks/aiks_unittests.cc

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4555,5 +4555,24 @@ TEST_P(AiksTest, GaussianBlurWithoutDecalSupport) {
45554555
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
45564556
}
45574557

4558+
TEST_P(AiksTest, SubpassWithClearColorOptimization) {
4559+
Canvas canvas;
4560+
4561+
// Use a non-srcOver blend mode to ensure that we don't detect this as an
4562+
// opacity peephole optimization.
4563+
canvas.SaveLayer(
4564+
{.color = Color::Blue().WithAlpha(0.5), .blend_mode = BlendMode::kSource},
4565+
Rect::MakeLTRB(0, 0, 200, 200));
4566+
canvas.DrawPaint(
4567+
{.color = Color::BlackTransparent(), .blend_mode = BlendMode::kSource});
4568+
canvas.Restore();
4569+
4570+
canvas.SaveLayer(
4571+
{.color = Color::Blue(), .blend_mode = BlendMode::kDestinationOver});
4572+
canvas.Restore();
4573+
4574+
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
4575+
}
4576+
45584577
} // namespace testing
45594578
} // namespace impeller

impeller/aiks/paint_pass_delegate.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include "impeller/entity/contents/texture_contents.h"
1111
#include "impeller/entity/entity_pass.h"
1212
#include "impeller/geometry/color.h"
13-
#include "impeller/geometry/path_builder.h"
1413

1514
namespace impeller {
1615

impeller/entity/entity_pass.cc

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,8 @@ bool EntityPass::Render(ContentContext& renderer,
342342
if (reads_from_onscreen_backdrop) {
343343
auto offscreen_target =
344344
CreateRenderTarget(renderer, root_render_target.GetRenderTargetSize(),
345-
GetClearColor(render_target.GetRenderTargetSize()));
345+
GetClearColor(render_target.GetRenderTargetSize())
346+
.value_or(Color::BlackTransparent()));
346347

347348
if (!OnRender(renderer, // renderer
348349
capture, // capture
@@ -447,7 +448,8 @@ bool EntityPass::Render(ContentContext& renderer,
447448
}
448449

449450
// Set up the clear color of the root pass.
450-
color0.clear_color = GetClearColor(render_target.GetRenderTargetSize());
451+
color0.clear_color = GetClearColor(render_target.GetRenderTargetSize())
452+
.value_or(Color::BlackTransparent());
451453
root_render_target.SetColorAttachment(color0, 0);
452454

453455
EntityPassTarget pass_target(
@@ -600,9 +602,10 @@ EntityPass::EntityResult EntityPass::GetEntityForElement(
600602
}
601603

602604
auto subpass_target = CreateRenderTarget(
603-
renderer, // renderer
604-
subpass_size, // size
605-
subpass->GetClearColor(subpass_size)); // clear_color
605+
renderer, // renderer
606+
subpass_size, // size
607+
subpass->GetClearColor(subpass_size)
608+
.value_or(Color::BlackTransparent())); // clear_color
606609

607610
if (!subpass_target.IsValid()) {
608611
VALIDATION_LOG << "Subpass render target is invalid.";
@@ -845,8 +848,7 @@ bool EntityPass::OnRender(
845848
}
846849
auto clear_color_size = pass_target.GetRenderTarget().GetRenderTargetSize();
847850

848-
if (!collapsed_parent_pass &&
849-
!GetClearColor(clear_color_size).IsTransparent()) {
851+
if (!collapsed_parent_pass && GetClearColor(clear_color_size).has_value()) {
850852
// Force the pass context to create at least one new pass if the clear color
851853
// is present.
852854
pass_context.GetRenderPass(pass_depth);
@@ -1139,21 +1141,25 @@ void EntityPass::SetBlendMode(BlendMode blend_mode) {
11391141
flood_clip_ = Entity::IsBlendModeDestructive(blend_mode);
11401142
}
11411143

1142-
Color EntityPass::GetClearColor(ISize target_size) const {
1143-
Color result = Color::BlackTransparent();
1144+
std::optional<Color> EntityPass::GetClearColor(ISize target_size) const {
11441145
if (backdrop_filter_proc_) {
1145-
return result;
1146+
return std::nullopt;
11461147
}
11471148

1149+
std::optional<Color> result = std::nullopt;
11481150
for (const Element& element : elements_) {
11491151
auto [entity_color, blend_mode] =
11501152
ElementAsBackgroundColor(element, target_size);
11511153
if (!entity_color.has_value()) {
11521154
break;
11531155
}
1154-
result = result.Blend(entity_color.value(), blend_mode);
1156+
result = result.value_or(Color::BlackTransparent())
1157+
.Blend(entity_color.value(), blend_mode);
1158+
}
1159+
if (result.has_value()) {
1160+
return result->Premultiply();
11551161
}
1156-
return result.Premultiply();
1162+
return result;
11571163
}
11581164

11591165
void EntityPass::SetBackdropFilter(BackdropFilterProc proc) {

impeller/entity/entity_pass.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,11 @@ class EntityPass {
136136

137137
void SetBlendMode(BlendMode blend_mode);
138138

139-
Color GetClearColor(ISize size = ISize::Infinite()) const;
139+
/// @brief Return the clear color of the pass entities.
140+
///
141+
/// If the returned value is std::nullopt, the clear color can be assumed to
142+
/// be transparent black.
143+
std::optional<Color> GetClearColor(ISize size = ISize::Infinite()) const;
140144

141145
void SetBackdropFilter(BackdropFilterProc proc);
142146

0 commit comments

Comments
 (0)