Skip to content

Commit 4ecc6eb

Browse files
bdero0xZOne
authored andcommitted
[Impeller] Don't use unnecessary stencil attachments (flutter#39537)
1 parent 632bfa1 commit 4ecc6eb

File tree

10 files changed

+192
-120
lines changed

10 files changed

+192
-120
lines changed

impeller/entity/contents/content_context.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ void ContentContextOptions::ApplyToPipelineDescriptor(
121121
}
122122
desc.SetColorAttachmentDescriptor(0u, color0);
123123

124+
if (!has_stencil_attachment) {
125+
desc.ClearStencilAttachments();
126+
}
127+
124128
if (desc.GetFrontStencilAttachmentDescriptor().has_value()) {
125129
StencilAttachmentDescriptor stencil =
126130
desc.GetFrontStencilAttachmentDescriptor().value();

impeller/entity/contents/content_context.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,17 +179,29 @@ using GeometryColorPipeline =
179179
using YUVToRGBFilterPipeline =
180180
RenderPipelineT<YuvToRgbFilterVertexShader, YuvToRgbFilterFragmentShader>;
181181

182+
/// Pipeline state configuration.
183+
///
184+
/// Each unique combination of these options requires a different pipeline state
185+
/// object to be built. This struct is used as a key for the per-pipeline
186+
/// variant cache.
187+
///
188+
/// When adding fields to this key, reliant features should take care to limit
189+
/// the combinatorical explosion of variations. A sufficiently complicated
190+
/// Flutter application may easily require building hundreds of PSOs in total,
191+
/// but they shouldn't require e.g. 10s of thousands.
182192
struct ContentContextOptions {
183193
SampleCount sample_count = SampleCount::kCount1;
184194
BlendMode blend_mode = BlendMode::kSourceOver;
185195
CompareFunction stencil_compare = CompareFunction::kEqual;
186196
StencilOperation stencil_operation = StencilOperation::kKeep;
187197
PrimitiveType primitive_type = PrimitiveType::kTriangle;
198+
bool has_stencil_attachment = true;
188199

189200
struct Hash {
190201
constexpr std::size_t operator()(const ContentContextOptions& o) const {
191202
return fml::HashCombine(o.sample_count, o.blend_mode, o.stencil_compare,
192-
o.stencil_operation, o.primitive_type);
203+
o.stencil_operation, o.primitive_type,
204+
o.has_stencil_attachment);
193205
}
194206
};
195207

@@ -200,7 +212,8 @@ struct ContentContextOptions {
200212
lhs.blend_mode == rhs.blend_mode &&
201213
lhs.stencil_compare == rhs.stencil_compare &&
202214
lhs.stencil_operation == rhs.stencil_operation &&
203-
lhs.primitive_type == rhs.primitive_type;
215+
lhs.primitive_type == rhs.primitive_type &&
216+
lhs.has_stencil_attachment == rhs.has_stencil_attachment;
204217
}
205218
};
206219

impeller/entity/contents/contents.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,17 @@ namespace impeller {
1616
ContentContextOptions OptionsFromPass(const RenderPass& pass) {
1717
ContentContextOptions opts;
1818
opts.sample_count = pass.GetRenderTarget().GetSampleCount();
19+
opts.has_stencil_attachment =
20+
pass.GetRenderTarget().GetStencilAttachment().has_value();
1921
return opts;
2022
}
2123

2224
ContentContextOptions OptionsFromPassAndEntity(const RenderPass& pass,
2325
const Entity& entity) {
2426
ContentContextOptions opts;
2527
opts.sample_count = pass.GetRenderTarget().GetSampleCount();
28+
opts.has_stencil_attachment =
29+
pass.GetRenderTarget().GetStencilAttachment().has_value();
2630
opts.blend_mode = entity.GetBlendMode();
2731
return opts;
2832
}

impeller/entity/contents/scene_contents.cc

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,20 @@ bool SceneContents::Render(const ContentContext& renderer,
4545
}
4646

4747
RenderTarget subpass_target = RenderTarget::CreateOffscreenMSAA(
48-
*renderer.GetContext(), // context
49-
ISize(coverage.value().size), // size
50-
"SceneContents", // label
51-
StorageMode::kDeviceTransient, // color_storage_mode
52-
StorageMode::kDevicePrivate, // color_resolve_storage_mode
53-
LoadAction::kClear, // color_load_action
54-
StoreAction::kMultisampleResolve, // color_store_action
55-
StorageMode::kDeviceTransient, // stencil_storage_mode
56-
LoadAction::kDontCare, // stencil_load_action
57-
StoreAction::kDontCare // stencil_store_action
48+
*renderer.GetContext(), // context
49+
ISize(coverage.value().size), // size
50+
"SceneContents", // label
51+
RenderTarget::AttachmentConfigMSAA{
52+
.storage_mode = StorageMode::kDeviceTransient,
53+
.resolve_storage_mode = StorageMode::kDevicePrivate,
54+
.load_action = LoadAction::kClear,
55+
.store_action = StoreAction::kMultisampleResolve,
56+
}, // color_attachment_config
57+
RenderTarget::AttachmentConfig{
58+
.storage_mode = StorageMode::kDeviceTransient,
59+
.load_action = LoadAction::kDontCare,
60+
.store_action = StoreAction::kDontCare,
61+
} // stencil_attachment_config
5862
);
5963
if (!subpass_target.IsValid()) {
6064
return false;

impeller/entity/entity_pass.cc

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -156,31 +156,39 @@ static RenderTarget CreateRenderTarget(ContentContext& renderer,
156156

157157
if (context->SupportsOffscreenMSAA()) {
158158
return RenderTarget::CreateOffscreenMSAA(
159-
*context, // context
160-
size, // size
161-
"EntityPass", // label
162-
StorageMode::kDeviceTransient, // color_storage_mode
163-
StorageMode::kDevicePrivate, // color_resolve_storage_mode
164-
LoadAction::kDontCare, // color_load_action
165-
StoreAction::kMultisampleResolve, // color_store_action
166-
readable ? StorageMode::kDevicePrivate
167-
: StorageMode::kDeviceTransient, // stencil_storage_mode
168-
LoadAction::kDontCare, // stencil_load_action
169-
StoreAction::kDontCare // stencil_store_action
159+
*context, // context
160+
size, // size
161+
"EntityPass", // label
162+
RenderTarget::AttachmentConfigMSAA{
163+
.storage_mode = StorageMode::kDeviceTransient,
164+
.resolve_storage_mode = StorageMode::kDevicePrivate,
165+
.load_action = LoadAction::kDontCare,
166+
.store_action = StoreAction::kMultisampleResolve,
167+
}, // color_attachment_config
168+
RenderTarget::AttachmentConfig{
169+
.storage_mode = readable ? StorageMode::kDevicePrivate
170+
: StorageMode::kDeviceTransient,
171+
.load_action = LoadAction::kDontCare,
172+
.store_action = StoreAction::kDontCare,
173+
} // stencil_attachment_config
170174
);
171175
}
172176

173177
return RenderTarget::CreateOffscreen(
174-
*context, // context
175-
size, // size
176-
"EntityPass", // label
177-
StorageMode::kDevicePrivate, // color_storage_mode
178-
LoadAction::kDontCare, // color_load_action
179-
StoreAction::kDontCare, // color_store_action
180-
readable ? StorageMode::kDevicePrivate
181-
: StorageMode::kDeviceTransient, // stencil_storage_mode
182-
LoadAction::kDontCare, // stencil_load_action
183-
StoreAction::kDontCare // stencil_store_action
178+
*context, // context
179+
size, // size
180+
"EntityPass", // label
181+
RenderTarget::AttachmentConfig{
182+
.storage_mode = StorageMode::kDevicePrivate,
183+
.load_action = LoadAction::kDontCare,
184+
.store_action = StoreAction::kDontCare,
185+
}, // color_attachment_config
186+
RenderTarget::AttachmentConfig{
187+
.storage_mode = readable ? StorageMode::kDevicePrivate
188+
: StorageMode::kDeviceTransient,
189+
.load_action = LoadAction::kDontCare,
190+
.store_action = StoreAction::kDontCare,
191+
} // stencil_attachment_config
184192
);
185193
}
186194

impeller/playground/imgui/imgui_impl_impeller.cc

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,8 @@ bool ImGui_ImplImpeller_Init(
9494
auto desc = impeller::PipelineBuilder<impeller::ImguiRasterVertexShader,
9595
impeller::ImguiRasterFragmentShader>::
9696
MakeDefaultPipelineDescriptor(*context);
97-
desc->SetStencilPixelFormat(impeller::PixelFormat::kUnknown);
98-
desc->SetStencilAttachmentDescriptors(std::nullopt);
99-
desc->SetDepthPixelFormat(impeller::PixelFormat::kUnknown);
100-
desc->SetDepthStencilAttachmentDescriptor(std::nullopt);
97+
desc->ClearStencilAttachments();
98+
desc->ClearDepthAttachment();
10199

102100
bd->pipeline =
103101
context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();

impeller/renderer/pipeline_descriptor.cc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,26 @@ PipelineDescriptor& PipelineDescriptor::SetStencilAttachmentDescriptors(
153153
return *this;
154154
}
155155

156+
void PipelineDescriptor::ClearStencilAttachments() {
157+
back_stencil_attachment_descriptor_.reset();
158+
front_stencil_attachment_descriptor_.reset();
159+
SetStencilPixelFormat(impeller::PixelFormat::kUnknown);
160+
}
161+
162+
void PipelineDescriptor::ClearDepthAttachment() {
163+
depth_attachment_descriptor_.reset();
164+
SetDepthPixelFormat(impeller::PixelFormat::kUnknown);
165+
}
166+
167+
void PipelineDescriptor::ClearColorAttachment(size_t index) {
168+
if (color_attachment_descriptors_.find(index) ==
169+
color_attachment_descriptors_.end()) {
170+
return;
171+
}
172+
173+
color_attachment_descriptors_.erase(index);
174+
}
175+
156176
void PipelineDescriptor::ResetAttachments() {
157177
color_attachment_descriptors_.clear();
158178
depth_attachment_descriptor_.reset();

impeller/renderer/pipeline_descriptor.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ class PipelineDescriptor final : public Comparable<PipelineDescriptor> {
8383
std::optional<StencilAttachmentDescriptor> front,
8484
std::optional<StencilAttachmentDescriptor> back);
8585

86+
void ClearStencilAttachments();
87+
88+
void ClearDepthAttachment();
89+
90+
void ClearColorAttachment(size_t index);
91+
8692
std::optional<StencilAttachmentDescriptor>
8793
GetFrontStencilAttachmentDescriptor() const;
8894

0 commit comments

Comments
 (0)