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

Commit 0d86d52

Browse files
authored
[Impeller] Allow pipeline variant sets to have differing defaults. (#46751)
Track default prototype options along side pipeline variant sets, allowing differing defaults to be assigned during ContentContext construction.
1 parent 8086814 commit 0d86d52

File tree

2 files changed

+123
-138
lines changed

2 files changed

+123
-138
lines changed

impeller/entity/contents/content_context.cc

Lines changed: 62 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -187,142 +187,84 @@ ContentContext::ContentContext(
187187
if (!context_ || !context_->IsValid()) {
188188
return;
189189
}
190-
default_options_ = ContentContextOptions{
190+
auto options = ContentContextOptions{
191191
.sample_count = SampleCount::kCount4,
192192
.color_attachment_pixel_format =
193193
context_->GetCapabilities()->GetDefaultColorFormat()};
194194

195195
#ifdef IMPELLER_DEBUG
196-
checkerboard_pipelines_[default_options_] =
197-
CreateDefaultPipeline<CheckerboardPipeline>(*context_);
196+
checkerboard_pipelines_.CreateDefault(*context_, options);
198197
#endif // IMPELLER_DEBUG
199198

200-
solid_fill_pipelines_[default_options_] =
201-
CreateDefaultPipeline<SolidFillPipeline>(*context_);
199+
solid_fill_pipelines_.CreateDefault(*context_, options);
202200

203201
if (context_->GetCapabilities()->SupportsSSBO()) {
204-
linear_gradient_ssbo_fill_pipelines_[default_options_] =
205-
CreateDefaultPipeline<LinearGradientSSBOFillPipeline>(*context_);
206-
radial_gradient_ssbo_fill_pipelines_[default_options_] =
207-
CreateDefaultPipeline<RadialGradientSSBOFillPipeline>(*context_);
208-
conical_gradient_ssbo_fill_pipelines_[default_options_] =
209-
CreateDefaultPipeline<ConicalGradientSSBOFillPipeline>(*context_);
210-
sweep_gradient_ssbo_fill_pipelines_[default_options_] =
211-
CreateDefaultPipeline<SweepGradientSSBOFillPipeline>(*context_);
202+
linear_gradient_ssbo_fill_pipelines_.CreateDefault(*context_, options);
203+
radial_gradient_ssbo_fill_pipelines_.CreateDefault(*context_, options);
204+
conical_gradient_ssbo_fill_pipelines_.CreateDefault(*context_, options);
205+
sweep_gradient_ssbo_fill_pipelines_.CreateDefault(*context_, options);
212206
} else {
213-
linear_gradient_fill_pipelines_[default_options_] =
214-
CreateDefaultPipeline<LinearGradientFillPipeline>(*context_);
215-
radial_gradient_fill_pipelines_[default_options_] =
216-
CreateDefaultPipeline<RadialGradientFillPipeline>(*context_);
217-
conical_gradient_fill_pipelines_[default_options_] =
218-
CreateDefaultPipeline<ConicalGradientFillPipeline>(*context_);
219-
sweep_gradient_fill_pipelines_[default_options_] =
220-
CreateDefaultPipeline<SweepGradientFillPipeline>(*context_);
207+
linear_gradient_fill_pipelines_.CreateDefault(*context_, options);
208+
radial_gradient_fill_pipelines_.CreateDefault(*context_, options);
209+
conical_gradient_fill_pipelines_.CreateDefault(*context_, options);
210+
sweep_gradient_fill_pipelines_.CreateDefault(*context_, options);
221211
}
222212

223213
if (context_->GetCapabilities()->SupportsFramebufferFetch()) {
224-
framebuffer_blend_color_pipelines_[default_options_] =
225-
CreateDefaultPipeline<FramebufferBlendColorPipeline>(*context_);
226-
framebuffer_blend_colorburn_pipelines_[default_options_] =
227-
CreateDefaultPipeline<FramebufferBlendColorBurnPipeline>(*context_);
228-
framebuffer_blend_colordodge_pipelines_[default_options_] =
229-
CreateDefaultPipeline<FramebufferBlendColorDodgePipeline>(*context_);
230-
framebuffer_blend_darken_pipelines_[default_options_] =
231-
CreateDefaultPipeline<FramebufferBlendDarkenPipeline>(*context_);
232-
framebuffer_blend_difference_pipelines_[default_options_] =
233-
CreateDefaultPipeline<FramebufferBlendDifferencePipeline>(*context_);
234-
framebuffer_blend_exclusion_pipelines_[default_options_] =
235-
CreateDefaultPipeline<FramebufferBlendExclusionPipeline>(*context_);
236-
framebuffer_blend_hardlight_pipelines_[default_options_] =
237-
CreateDefaultPipeline<FramebufferBlendHardLightPipeline>(*context_);
238-
framebuffer_blend_hue_pipelines_[default_options_] =
239-
CreateDefaultPipeline<FramebufferBlendHuePipeline>(*context_);
240-
framebuffer_blend_lighten_pipelines_[default_options_] =
241-
CreateDefaultPipeline<FramebufferBlendLightenPipeline>(*context_);
242-
framebuffer_blend_luminosity_pipelines_[default_options_] =
243-
CreateDefaultPipeline<FramebufferBlendLuminosityPipeline>(*context_);
244-
framebuffer_blend_multiply_pipelines_[default_options_] =
245-
CreateDefaultPipeline<FramebufferBlendMultiplyPipeline>(*context_);
246-
framebuffer_blend_overlay_pipelines_[default_options_] =
247-
CreateDefaultPipeline<FramebufferBlendOverlayPipeline>(*context_);
248-
framebuffer_blend_saturation_pipelines_[default_options_] =
249-
CreateDefaultPipeline<FramebufferBlendSaturationPipeline>(*context_);
250-
framebuffer_blend_screen_pipelines_[default_options_] =
251-
CreateDefaultPipeline<FramebufferBlendScreenPipeline>(*context_);
252-
framebuffer_blend_softlight_pipelines_[default_options_] =
253-
CreateDefaultPipeline<FramebufferBlendSoftLightPipeline>(*context_);
214+
framebuffer_blend_color_pipelines_.CreateDefault(*context_, options);
215+
framebuffer_blend_colorburn_pipelines_.CreateDefault(*context_, options);
216+
framebuffer_blend_colordodge_pipelines_.CreateDefault(*context_, options);
217+
framebuffer_blend_darken_pipelines_.CreateDefault(*context_, options);
218+
framebuffer_blend_difference_pipelines_.CreateDefault(*context_, options);
219+
framebuffer_blend_exclusion_pipelines_.CreateDefault(*context_, options);
220+
framebuffer_blend_hardlight_pipelines_.CreateDefault(*context_, options);
221+
framebuffer_blend_hue_pipelines_.CreateDefault(*context_, options);
222+
framebuffer_blend_lighten_pipelines_.CreateDefault(*context_, options);
223+
framebuffer_blend_luminosity_pipelines_.CreateDefault(*context_, options);
224+
framebuffer_blend_multiply_pipelines_.CreateDefault(*context_, options);
225+
framebuffer_blend_overlay_pipelines_.CreateDefault(*context_, options);
226+
framebuffer_blend_saturation_pipelines_.CreateDefault(*context_, options);
227+
framebuffer_blend_screen_pipelines_.CreateDefault(*context_, options);
228+
framebuffer_blend_softlight_pipelines_.CreateDefault(*context_, options);
254229
}
255230

256-
blend_color_pipelines_[default_options_] =
257-
CreateDefaultPipeline<BlendColorPipeline>(*context_);
258-
blend_colorburn_pipelines_[default_options_] =
259-
CreateDefaultPipeline<BlendColorBurnPipeline>(*context_);
260-
blend_colordodge_pipelines_[default_options_] =
261-
CreateDefaultPipeline<BlendColorDodgePipeline>(*context_);
262-
blend_darken_pipelines_[default_options_] =
263-
CreateDefaultPipeline<BlendDarkenPipeline>(*context_);
264-
blend_difference_pipelines_[default_options_] =
265-
CreateDefaultPipeline<BlendDifferencePipeline>(*context_);
266-
blend_exclusion_pipelines_[default_options_] =
267-
CreateDefaultPipeline<BlendExclusionPipeline>(*context_);
268-
blend_hardlight_pipelines_[default_options_] =
269-
CreateDefaultPipeline<BlendHardLightPipeline>(*context_);
270-
blend_hue_pipelines_[default_options_] =
271-
CreateDefaultPipeline<BlendHuePipeline>(*context_);
272-
blend_lighten_pipelines_[default_options_] =
273-
CreateDefaultPipeline<BlendLightenPipeline>(*context_);
274-
blend_luminosity_pipelines_[default_options_] =
275-
CreateDefaultPipeline<BlendLuminosityPipeline>(*context_);
276-
blend_multiply_pipelines_[default_options_] =
277-
CreateDefaultPipeline<BlendMultiplyPipeline>(*context_);
278-
blend_overlay_pipelines_[default_options_] =
279-
CreateDefaultPipeline<BlendOverlayPipeline>(*context_);
280-
blend_saturation_pipelines_[default_options_] =
281-
CreateDefaultPipeline<BlendSaturationPipeline>(*context_);
282-
blend_screen_pipelines_[default_options_] =
283-
CreateDefaultPipeline<BlendScreenPipeline>(*context_);
284-
blend_softlight_pipelines_[default_options_] =
285-
CreateDefaultPipeline<BlendSoftLightPipeline>(*context_);
286-
287-
rrect_blur_pipelines_[default_options_] =
288-
CreateDefaultPipeline<RRectBlurPipeline>(*context_);
289-
texture_blend_pipelines_[default_options_] =
290-
CreateDefaultPipeline<BlendPipeline>(*context_);
291-
texture_pipelines_[default_options_] =
292-
CreateDefaultPipeline<TexturePipeline>(*context_);
293-
position_uv_pipelines_[default_options_] =
294-
CreateDefaultPipeline<PositionUVPipeline>(*context_);
295-
tiled_texture_pipelines_[default_options_] =
296-
CreateDefaultPipeline<TiledTexturePipeline>(*context_);
297-
gaussian_blur_noalpha_decal_pipelines_[default_options_] =
298-
CreateDefaultPipeline<GaussianBlurDecalPipeline>(*context_);
299-
gaussian_blur_noalpha_nodecal_pipelines_[default_options_] =
300-
CreateDefaultPipeline<GaussianBlurPipeline>(*context_);
301-
border_mask_blur_pipelines_[default_options_] =
302-
CreateDefaultPipeline<BorderMaskBlurPipeline>(*context_);
303-
morphology_filter_pipelines_[default_options_] =
304-
CreateDefaultPipeline<MorphologyFilterPipeline>(*context_);
305-
color_matrix_color_filter_pipelines_[default_options_] =
306-
CreateDefaultPipeline<ColorMatrixColorFilterPipeline>(*context_);
307-
linear_to_srgb_filter_pipelines_[default_options_] =
308-
CreateDefaultPipeline<LinearToSrgbFilterPipeline>(*context_);
309-
srgb_to_linear_filter_pipelines_[default_options_] =
310-
CreateDefaultPipeline<SrgbToLinearFilterPipeline>(*context_);
311-
glyph_atlas_pipelines_[default_options_] =
312-
CreateDefaultPipeline<GlyphAtlasPipeline>(*context_);
313-
glyph_atlas_color_pipelines_[default_options_] =
314-
CreateDefaultPipeline<GlyphAtlasColorPipeline>(*context_);
315-
geometry_color_pipelines_[default_options_] =
316-
CreateDefaultPipeline<GeometryColorPipeline>(*context_);
317-
yuv_to_rgb_filter_pipelines_[default_options_] =
318-
CreateDefaultPipeline<YUVToRGBFilterPipeline>(*context_);
319-
porter_duff_blend_pipelines_[default_options_] =
320-
CreateDefaultPipeline<PorterDuffBlendPipeline>(*context_);
231+
blend_color_pipelines_.CreateDefault(*context_, options);
232+
blend_colorburn_pipelines_.CreateDefault(*context_, options);
233+
blend_colordodge_pipelines_.CreateDefault(*context_, options);
234+
blend_darken_pipelines_.CreateDefault(*context_, options);
235+
blend_difference_pipelines_.CreateDefault(*context_, options);
236+
blend_exclusion_pipelines_.CreateDefault(*context_, options);
237+
blend_hardlight_pipelines_.CreateDefault(*context_, options);
238+
blend_hue_pipelines_.CreateDefault(*context_, options);
239+
blend_lighten_pipelines_.CreateDefault(*context_, options);
240+
blend_luminosity_pipelines_.CreateDefault(*context_, options);
241+
blend_multiply_pipelines_.CreateDefault(*context_, options);
242+
blend_overlay_pipelines_.CreateDefault(*context_, options);
243+
blend_saturation_pipelines_.CreateDefault(*context_, options);
244+
blend_screen_pipelines_.CreateDefault(*context_, options);
245+
blend_softlight_pipelines_.CreateDefault(*context_, options);
246+
247+
rrect_blur_pipelines_.CreateDefault(*context_, options);
248+
texture_blend_pipelines_.CreateDefault(*context_, options);
249+
texture_pipelines_.CreateDefault(*context_, options);
250+
position_uv_pipelines_.CreateDefault(*context_, options);
251+
tiled_texture_pipelines_.CreateDefault(*context_, options);
252+
gaussian_blur_noalpha_decal_pipelines_.CreateDefault(*context_, options);
253+
gaussian_blur_noalpha_nodecal_pipelines_.CreateDefault(*context_, options);
254+
border_mask_blur_pipelines_.CreateDefault(*context_, options);
255+
morphology_filter_pipelines_.CreateDefault(*context_, options);
256+
color_matrix_color_filter_pipelines_.CreateDefault(*context_, options);
257+
linear_to_srgb_filter_pipelines_.CreateDefault(*context_, options);
258+
srgb_to_linear_filter_pipelines_.CreateDefault(*context_, options);
259+
glyph_atlas_pipelines_.CreateDefault(*context_, options);
260+
glyph_atlas_color_pipelines_.CreateDefault(*context_, options);
261+
geometry_color_pipelines_.CreateDefault(*context_, options);
262+
yuv_to_rgb_filter_pipelines_.CreateDefault(*context_, options);
263+
porter_duff_blend_pipelines_.CreateDefault(*context_, options);
321264
// GLES only shader.
322265
#ifdef IMPELLER_ENABLE_OPENGLES
323266
if (GetContext()->GetBackendType() == Context::BackendType::kOpenGLES) {
324-
texture_external_pipelines_[default_options_] =
325-
CreateDefaultPipeline<TextureExternalPipeline>(*context_);
267+
texture_external_pipelines_.CreateDefault(*context_, options);
326268
}
327269
#endif // IMPELLER_ENABLE_OPENGLES
328270
if (context_->GetCapabilities()->SupportsCompute()) {
@@ -358,8 +300,8 @@ ContentContext::ContentContext(
358300
}
359301
clip_pipeline_descriptor->SetColorAttachmentDescriptors(
360302
std::move(clip_color_attachments));
361-
clip_pipelines_[default_options_] =
362-
std::make_unique<ClipPipeline>(*context_, clip_pipeline_descriptor);
303+
clip_pipelines_.SetDefault(options, std::make_unique<ClipPipeline>(
304+
*context_, clip_pipeline_descriptor));
363305

364306
is_valid_ = true;
365307
}

impeller/entity/contents/content_context.h

Lines changed: 61 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -721,11 +721,59 @@ class ContentContext {
721721
std::shared_ptr<Context> context_;
722722
std::shared_ptr<LazyGlyphAtlas> lazy_glyph_atlas_;
723723

724-
template <class T>
725-
using Variants = std::unordered_map<ContentContextOptions,
726-
std::unique_ptr<T>,
727-
ContentContextOptions::Hash,
728-
ContentContextOptions::Equal>;
724+
template <class PipelineT>
725+
class Variants {
726+
public:
727+
Variants() = default;
728+
729+
void Set(const ContentContextOptions& options,
730+
std::unique_ptr<PipelineT> pipeline) {
731+
pipelines_[options] = std::move(pipeline);
732+
}
733+
734+
void SetDefault(const ContentContextOptions& options,
735+
std::unique_ptr<PipelineT> pipeline) {
736+
default_options_ = options;
737+
Set(options, std::move(pipeline));
738+
}
739+
740+
void CreateDefault(const Context& context,
741+
const ContentContextOptions& options) {
742+
auto desc = PipelineT::Builder::MakeDefaultPipelineDescriptor(context);
743+
if (!desc.has_value()) {
744+
VALIDATION_LOG << "Failed to create default pipeline.";
745+
return;
746+
}
747+
options.ApplyToPipelineDescriptor(*desc);
748+
SetDefault(options, std::make_unique<PipelineT>(context, desc));
749+
}
750+
751+
PipelineT* Get(const ContentContextOptions& options) const {
752+
if (auto found = pipelines_.find(options); found != pipelines_.end()) {
753+
return found->second.get();
754+
}
755+
return nullptr;
756+
}
757+
758+
PipelineT* GetDefault() const {
759+
if (!default_options_.has_value()) {
760+
return nullptr;
761+
}
762+
return Get(default_options_.value());
763+
}
764+
765+
size_t GetPipelineCount() const { return pipelines_.size(); }
766+
767+
private:
768+
std::optional<ContentContextOptions> default_options_;
769+
std::unordered_map<ContentContextOptions,
770+
std::unique_ptr<PipelineT>,
771+
ContentContextOptions::Hash,
772+
ContentContextOptions::Equal>
773+
pipelines_;
774+
775+
FML_DISALLOW_COPY_AND_ASSIGN(Variants);
776+
};
729777

730778
// These are mutable because while the prototypes are created eagerly, any
731779
// variants requested from that are lazily created and cached in the variants
@@ -824,12 +872,6 @@ class ContentContext {
824872
point_field_compute_pipelines_;
825873
mutable std::shared_ptr<Pipeline<ComputePipelineDescriptor>>
826874
uv_compute_pipelines_;
827-
// The values for the default context options must be cached on
828-
// initial creation. In the presence of wide gamut and platform views,
829-
// it is possible that secondary surfaces will have a different default
830-
// pixel format, which would cause the prototype check in GetPipeline
831-
// below to fail.
832-
ContentContextOptions default_options_;
833875

834876
template <class TypedPipeline>
835877
std::shared_ptr<Pipeline<PipelineDescriptor>> GetPipeline(
@@ -843,29 +885,30 @@ class ContentContext {
843885
opts.wireframe = true;
844886
}
845887

846-
if (auto found = container.find(opts); found != container.end()) {
847-
return found->second->WaitAndGet();
888+
if (auto found = container.Get(opts)) {
889+
return found->WaitAndGet();
848890
}
849891

850-
auto prototype = container.find(default_options_);
892+
auto prototype = container.GetDefault();
851893

852894
// The prototype must always be initialized in the constructor.
853-
FML_CHECK(prototype != container.end());
895+
FML_CHECK(prototype != nullptr);
854896

855-
auto pipeline = prototype->second->WaitAndGet();
897+
auto pipeline = prototype->WaitAndGet();
856898
if (!pipeline) {
857899
return nullptr;
858900
}
859901

860902
auto variant_future = pipeline->CreateVariant(
861-
[&opts, variants_count = container.size()](PipelineDescriptor& desc) {
903+
[&opts, variants_count =
904+
container.GetPipelineCount()](PipelineDescriptor& desc) {
862905
opts.ApplyToPipelineDescriptor(desc);
863906
desc.SetLabel(
864907
SPrintF("%s V#%zu", desc.GetLabel().c_str(), variants_count));
865908
});
866909
auto variant = std::make_unique<TypedPipeline>(std::move(variant_future));
867910
auto variant_pipeline = variant->WaitAndGet();
868-
container[opts] = std::move(variant);
911+
container.Set(opts, std::move(variant));
869912
return variant_pipeline;
870913
}
871914

0 commit comments

Comments
 (0)