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

Commit 59acbc8

Browse files
committed
Make more aggressive for kSource, limit to root pass, and set the clear color
1 parent 92c37cf commit 59acbc8

File tree

5 files changed

+72
-22
lines changed

5 files changed

+72
-22
lines changed

impeller/aiks/aiks_unittests.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2000,5 +2000,17 @@ TEST_P(AiksTest, OpacityPeepHoleApplicationTest) {
20002000
ASSERT_TRUE(delegate->CanCollapseIntoParentPass(entity_pass.get()));
20012001
}
20022002

2003+
TEST_P(AiksTest, DrawPaintAbsorbsClears) {
2004+
Canvas canvas;
2005+
canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
2006+
canvas.DrawPaint(
2007+
{.color = Color::CornflowerBlue(), .blend_mode = BlendMode::kSource});
2008+
2009+
Picture picture = canvas.EndRecordingAsPicture();
2010+
2011+
ASSERT_EQ(picture.pass->GetElementCount(), 0u);
2012+
ASSERT_EQ(picture.pass->GetClearColor(), Color::CornflowerBlue());
2013+
}
2014+
20032015
} // namespace testing
20042016
} // namespace impeller

impeller/aiks/canvas.cc

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,15 @@ void Canvas::DrawPath(const Path& path, const Paint& paint) {
167167
}
168168

169169
void Canvas::DrawPaint(const Paint& paint) {
170-
bool is_clear = (paint.blend_mode == BlendMode::kSource &&
171-
paint.color == Color::BlackTransparent());
172-
if (is_clear && GetCurrentPass().GetElementCount() == 0) {
170+
bool is_clear =
171+
paint.blend_mode == BlendMode::kSource ||
172+
(paint.blend_mode == BlendMode::kSourceOver && paint.color.alpha == 1);
173+
if (xformation_stack_.size() == 1 && // If we're recording the root pass,
174+
GetCurrentPass().GetElementCount() == 0 && // and this is the first item,
175+
is_clear // and the backdrop is being replaced
176+
) {
177+
// Then we can absorb this drawPaint as the clear color of the pass.
178+
GetCurrentPass().SetClearColor(paint.color);
173179
return;
174180
}
175181

impeller/entity/entity_pass.cc

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,8 @@ EntityPass* EntityPass::AddSubpass(std::unique_ptr<EntityPass> pass) {
144144

145145
static EntityPassTarget CreateRenderTarget(ContentContext& renderer,
146146
ISize size,
147-
bool readable) {
147+
bool readable,
148+
const Color& clear_color) {
148149
auto context = renderer.GetContext();
149150

150151
/// All of the load/store actions are managed by `InlinePassContext` when
@@ -163,7 +164,7 @@ static EntityPassTarget CreateRenderTarget(ContentContext& renderer,
163164
.resolve_storage_mode = StorageMode::kDevicePrivate,
164165
.load_action = LoadAction::kDontCare,
165166
.store_action = StoreAction::kMultisampleResolve,
166-
}, // color_attachment_config
167+
.clear_color = clear_color}, // color_attachment_config
167168
RenderTarget::AttachmentConfig{
168169
.storage_mode = readable ? StorageMode::kDevicePrivate
169170
: StorageMode::kDeviceTransient,
@@ -203,13 +204,18 @@ uint32_t EntityPass::GetTotalPassReads(ContentContext& renderer) const {
203204

204205
bool EntityPass::Render(ContentContext& renderer,
205206
const RenderTarget& render_target) const {
207+
if (render_target.GetColorAttachments().empty()) {
208+
VALIDATION_LOG << "The root RenderTarget must have a color attachment.";
209+
return false;
210+
}
211+
206212
StencilCoverageStack stencil_coverage_stack = {StencilCoverageLayer{
207213
.coverage = Rect::MakeSize(render_target.GetRenderTargetSize()),
208214
.stencil_depth = 0}};
209215

210216
if (GetTotalPassReads(renderer) > 0) {
211-
auto offscreen_target =
212-
CreateRenderTarget(renderer, render_target.GetRenderTargetSize(), true);
217+
auto offscreen_target = CreateRenderTarget(
218+
renderer, render_target.GetRenderTargetSize(), true, clear_color_);
213219

214220
if (!OnRender(renderer, // renderer
215221
offscreen_target.GetRenderTarget()
@@ -269,18 +275,25 @@ bool EntityPass::Render(ContentContext& renderer,
269275
return true;
270276
}
271277

278+
// Set up the clear color of the root pass.
279+
auto color0 = render_target.GetColorAttachments().find(0)->second;
280+
color0.clear_color = clear_color_;
281+
282+
auto root_render_target = render_target;
283+
root_render_target.SetColorAttachment(color0, 0);
284+
272285
EntityPassTarget pass_target(
273-
render_target,
286+
root_render_target,
274287
renderer.GetDeviceCapabilities().SupportsReadFromResolve());
275288

276-
return OnRender( //
277-
renderer, // renderer
278-
render_target.GetRenderTargetSize(), // root_pass_size
279-
pass_target, // pass_target
280-
Point(), // global_pass_position
281-
Point(), // local_pass_position
282-
0, // pass_depth
283-
stencil_coverage_stack); // stencil_coverage_stack
289+
return OnRender( //
290+
renderer, // renderer
291+
root_render_target.GetRenderTargetSize(), // root_pass_size
292+
pass_target, // pass_target
293+
Point(), // global_pass_position
294+
Point(), // local_pass_position
295+
0, // pass_depth
296+
stencil_coverage_stack); // stencil_coverage_stack
284297
}
285298

286299
EntityPass::EntityResult EntityPass::GetEntityForElement(
@@ -386,9 +399,10 @@ EntityPass::EntityResult EntityPass::GetEntityForElement(
386399
subpass_coverage->Intersection(Rect::MakeSize(root_pass_size));
387400

388401
auto subpass_target =
389-
CreateRenderTarget(renderer, //
390-
ISize(subpass_coverage->size), //
391-
subpass->GetTotalPassReads(renderer) > 0);
402+
CreateRenderTarget(renderer, //
403+
ISize(subpass_coverage->size), //
404+
subpass->GetTotalPassReads(renderer) > 0, //
405+
clear_color_);
392406

393407
auto subpass_texture =
394408
subpass_target.GetRenderTarget().GetRenderTargetTexture();
@@ -739,6 +753,14 @@ void EntityPass::SetBlendMode(BlendMode blend_mode) {
739753
cover_whole_screen_ = Entity::IsBlendModeDestructive(blend_mode);
740754
}
741755

756+
void EntityPass::SetClearColor(Color clear_color) {
757+
clear_color_ = clear_color;
758+
}
759+
760+
Color EntityPass::GetClearColor() const {
761+
return clear_color_;
762+
}
763+
742764
void EntityPass::SetBackdropFilter(std::optional<BackdropFilterProc> proc) {
743765
if (superpass_) {
744766
VALIDATION_LOG << "Backdrop filters cannot be set on EntityPasses that "

impeller/entity/entity_pass.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ class EntityPass {
8686

8787
void SetBlendMode(BlendMode blend_mode);
8888

89+
void SetClearColor(Color clear_color);
90+
91+
Color GetClearColor() const;
92+
8993
void SetBackdropFilter(std::optional<BackdropFilterProc> proc);
9094

9195
std::optional<Rect> GetSubpassCoverage(
@@ -204,6 +208,7 @@ class EntityPass {
204208
size_t stencil_depth_ = 0u;
205209
BlendMode blend_mode_ = BlendMode::kSourceOver;
206210
bool cover_whole_screen_ = false;
211+
Color clear_color_ = Color::BlackTransparent();
207212

208213
/// These values are incremented whenever something is added to the pass that
209214
/// requires reading from the backdrop texture. Currently, this can happen in

impeller/renderer/render_target.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,30 +23,35 @@ class RenderTarget final {
2323
StorageMode storage_mode;
2424
LoadAction load_action;
2525
StoreAction store_action;
26+
Color clear_color;
2627
};
2728

2829
struct AttachmentConfigMSAA {
2930
StorageMode storage_mode;
3031
StorageMode resolve_storage_mode;
3132
LoadAction load_action;
3233
StoreAction store_action;
34+
Color clear_color;
3335
};
3436

3537
static constexpr AttachmentConfig kDefaultColorAttachmentConfig = {
3638
.storage_mode = StorageMode::kDevicePrivate,
3739
.load_action = LoadAction::kClear,
38-
.store_action = StoreAction::kStore};
40+
.store_action = StoreAction::kStore,
41+
.clear_color = Color::BlackTransparent()};
3942

4043
static constexpr AttachmentConfigMSAA kDefaultColorAttachmentConfigMSAA = {
4144
.storage_mode = StorageMode::kDeviceTransient,
4245
.resolve_storage_mode = StorageMode::kDevicePrivate,
4346
.load_action = LoadAction::kClear,
44-
.store_action = StoreAction::kMultisampleResolve};
47+
.store_action = StoreAction::kMultisampleResolve,
48+
.clear_color = Color::BlackTransparent()};
4549

4650
static constexpr AttachmentConfig kDefaultStencilAttachmentConfig = {
4751
.storage_mode = StorageMode::kDeviceTransient,
4852
.load_action = LoadAction::kClear,
49-
.store_action = StoreAction::kDontCare};
53+
.store_action = StoreAction::kDontCare,
54+
.clear_color = Color::BlackTransparent()};
5055

5156
static RenderTarget CreateOffscreen(
5257
const Context& context,

0 commit comments

Comments
 (0)