From 0346d04ae94d5fb3593339bcc13cae6dde4d84df Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 10 Oct 2023 18:14:23 -0700 Subject: [PATCH] [Impeller] Allow pipelines to have differing defaults. --- impeller/entity/contents/content_context.cc | 182 +++++++------------- impeller/entity/contents/content_context.h | 79 +++++++-- 2 files changed, 123 insertions(+), 138 deletions(-) diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index a5c1e4d26d216..f531345342660 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -187,142 +187,84 @@ ContentContext::ContentContext( if (!context_ || !context_->IsValid()) { return; } - default_options_ = ContentContextOptions{ + auto options = ContentContextOptions{ .sample_count = SampleCount::kCount4, .color_attachment_pixel_format = context_->GetCapabilities()->GetDefaultColorFormat()}; #ifdef IMPELLER_DEBUG - checkerboard_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); + checkerboard_pipelines_.CreateDefault(*context_, options); #endif // IMPELLER_DEBUG - solid_fill_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); + solid_fill_pipelines_.CreateDefault(*context_, options); if (context_->GetCapabilities()->SupportsSSBO()) { - linear_gradient_ssbo_fill_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - radial_gradient_ssbo_fill_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - conical_gradient_ssbo_fill_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - sweep_gradient_ssbo_fill_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); + linear_gradient_ssbo_fill_pipelines_.CreateDefault(*context_, options); + radial_gradient_ssbo_fill_pipelines_.CreateDefault(*context_, options); + conical_gradient_ssbo_fill_pipelines_.CreateDefault(*context_, options); + sweep_gradient_ssbo_fill_pipelines_.CreateDefault(*context_, options); } else { - linear_gradient_fill_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - radial_gradient_fill_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - conical_gradient_fill_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - sweep_gradient_fill_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); + linear_gradient_fill_pipelines_.CreateDefault(*context_, options); + radial_gradient_fill_pipelines_.CreateDefault(*context_, options); + conical_gradient_fill_pipelines_.CreateDefault(*context_, options); + sweep_gradient_fill_pipelines_.CreateDefault(*context_, options); } if (context_->GetCapabilities()->SupportsFramebufferFetch()) { - framebuffer_blend_color_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - framebuffer_blend_colorburn_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - framebuffer_blend_colordodge_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - framebuffer_blend_darken_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - framebuffer_blend_difference_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - framebuffer_blend_exclusion_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - framebuffer_blend_hardlight_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - framebuffer_blend_hue_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - framebuffer_blend_lighten_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - framebuffer_blend_luminosity_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - framebuffer_blend_multiply_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - framebuffer_blend_overlay_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - framebuffer_blend_saturation_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - framebuffer_blend_screen_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - framebuffer_blend_softlight_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); + framebuffer_blend_color_pipelines_.CreateDefault(*context_, options); + framebuffer_blend_colorburn_pipelines_.CreateDefault(*context_, options); + framebuffer_blend_colordodge_pipelines_.CreateDefault(*context_, options); + framebuffer_blend_darken_pipelines_.CreateDefault(*context_, options); + framebuffer_blend_difference_pipelines_.CreateDefault(*context_, options); + framebuffer_blend_exclusion_pipelines_.CreateDefault(*context_, options); + framebuffer_blend_hardlight_pipelines_.CreateDefault(*context_, options); + framebuffer_blend_hue_pipelines_.CreateDefault(*context_, options); + framebuffer_blend_lighten_pipelines_.CreateDefault(*context_, options); + framebuffer_blend_luminosity_pipelines_.CreateDefault(*context_, options); + framebuffer_blend_multiply_pipelines_.CreateDefault(*context_, options); + framebuffer_blend_overlay_pipelines_.CreateDefault(*context_, options); + framebuffer_blend_saturation_pipelines_.CreateDefault(*context_, options); + framebuffer_blend_screen_pipelines_.CreateDefault(*context_, options); + framebuffer_blend_softlight_pipelines_.CreateDefault(*context_, options); } - blend_color_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - blend_colorburn_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - blend_colordodge_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - blend_darken_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - blend_difference_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - blend_exclusion_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - blend_hardlight_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - blend_hue_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - blend_lighten_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - blend_luminosity_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - blend_multiply_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - blend_overlay_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - blend_saturation_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - blend_screen_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - blend_softlight_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - - rrect_blur_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - texture_blend_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - texture_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - position_uv_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - tiled_texture_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - gaussian_blur_noalpha_decal_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - gaussian_blur_noalpha_nodecal_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - border_mask_blur_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - morphology_filter_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - color_matrix_color_filter_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - linear_to_srgb_filter_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - srgb_to_linear_filter_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - glyph_atlas_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - glyph_atlas_color_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - geometry_color_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - yuv_to_rgb_filter_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); - porter_duff_blend_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); + blend_color_pipelines_.CreateDefault(*context_, options); + blend_colorburn_pipelines_.CreateDefault(*context_, options); + blend_colordodge_pipelines_.CreateDefault(*context_, options); + blend_darken_pipelines_.CreateDefault(*context_, options); + blend_difference_pipelines_.CreateDefault(*context_, options); + blend_exclusion_pipelines_.CreateDefault(*context_, options); + blend_hardlight_pipelines_.CreateDefault(*context_, options); + blend_hue_pipelines_.CreateDefault(*context_, options); + blend_lighten_pipelines_.CreateDefault(*context_, options); + blend_luminosity_pipelines_.CreateDefault(*context_, options); + blend_multiply_pipelines_.CreateDefault(*context_, options); + blend_overlay_pipelines_.CreateDefault(*context_, options); + blend_saturation_pipelines_.CreateDefault(*context_, options); + blend_screen_pipelines_.CreateDefault(*context_, options); + blend_softlight_pipelines_.CreateDefault(*context_, options); + + rrect_blur_pipelines_.CreateDefault(*context_, options); + texture_blend_pipelines_.CreateDefault(*context_, options); + texture_pipelines_.CreateDefault(*context_, options); + position_uv_pipelines_.CreateDefault(*context_, options); + tiled_texture_pipelines_.CreateDefault(*context_, options); + gaussian_blur_noalpha_decal_pipelines_.CreateDefault(*context_, options); + gaussian_blur_noalpha_nodecal_pipelines_.CreateDefault(*context_, options); + border_mask_blur_pipelines_.CreateDefault(*context_, options); + morphology_filter_pipelines_.CreateDefault(*context_, options); + color_matrix_color_filter_pipelines_.CreateDefault(*context_, options); + linear_to_srgb_filter_pipelines_.CreateDefault(*context_, options); + srgb_to_linear_filter_pipelines_.CreateDefault(*context_, options); + glyph_atlas_pipelines_.CreateDefault(*context_, options); + glyph_atlas_color_pipelines_.CreateDefault(*context_, options); + geometry_color_pipelines_.CreateDefault(*context_, options); + yuv_to_rgb_filter_pipelines_.CreateDefault(*context_, options); + porter_duff_blend_pipelines_.CreateDefault(*context_, options); // GLES only shader. #ifdef IMPELLER_ENABLE_OPENGLES if (GetContext()->GetBackendType() == Context::BackendType::kOpenGLES) { - texture_external_pipelines_[default_options_] = - CreateDefaultPipeline(*context_); + texture_external_pipelines_.CreateDefault(*context_, options); } #endif // IMPELLER_ENABLE_OPENGLES if (context_->GetCapabilities()->SupportsCompute()) { @@ -358,8 +300,8 @@ ContentContext::ContentContext( } clip_pipeline_descriptor->SetColorAttachmentDescriptors( std::move(clip_color_attachments)); - clip_pipelines_[default_options_] = - std::make_unique(*context_, clip_pipeline_descriptor); + clip_pipelines_.SetDefault(options, std::make_unique( + *context_, clip_pipeline_descriptor)); is_valid_ = true; } diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index 4c4c17c43b194..a5f0aab9bd6a8 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -721,11 +721,59 @@ class ContentContext { std::shared_ptr context_; std::shared_ptr lazy_glyph_atlas_; - template - using Variants = std::unordered_map, - ContentContextOptions::Hash, - ContentContextOptions::Equal>; + template + class Variants { + public: + Variants() = default; + + void Set(const ContentContextOptions& options, + std::unique_ptr pipeline) { + pipelines_[options] = std::move(pipeline); + } + + void SetDefault(const ContentContextOptions& options, + std::unique_ptr pipeline) { + default_options_ = options; + Set(options, std::move(pipeline)); + } + + void CreateDefault(const Context& context, + const ContentContextOptions& options) { + auto desc = PipelineT::Builder::MakeDefaultPipelineDescriptor(context); + if (!desc.has_value()) { + VALIDATION_LOG << "Failed to create default pipeline."; + return; + } + options.ApplyToPipelineDescriptor(*desc); + SetDefault(options, std::make_unique(context, desc)); + } + + PipelineT* Get(const ContentContextOptions& options) const { + if (auto found = pipelines_.find(options); found != pipelines_.end()) { + return found->second.get(); + } + return nullptr; + } + + PipelineT* GetDefault() const { + if (!default_options_.has_value()) { + return nullptr; + } + return Get(default_options_.value()); + } + + size_t GetPipelineCount() const { return pipelines_.size(); } + + private: + std::optional default_options_; + std::unordered_map, + ContentContextOptions::Hash, + ContentContextOptions::Equal> + pipelines_; + + FML_DISALLOW_COPY_AND_ASSIGN(Variants); + }; // These are mutable because while the prototypes are created eagerly, any // variants requested from that are lazily created and cached in the variants @@ -824,12 +872,6 @@ class ContentContext { point_field_compute_pipelines_; mutable std::shared_ptr> uv_compute_pipelines_; - // The values for the default context options must be cached on - // initial creation. In the presence of wide gamut and platform views, - // it is possible that secondary surfaces will have a different default - // pixel format, which would cause the prototype check in GetPipeline - // below to fail. - ContentContextOptions default_options_; template std::shared_ptr> GetPipeline( @@ -843,29 +885,30 @@ class ContentContext { opts.wireframe = true; } - if (auto found = container.find(opts); found != container.end()) { - return found->second->WaitAndGet(); + if (auto found = container.Get(opts)) { + return found->WaitAndGet(); } - auto prototype = container.find(default_options_); + auto prototype = container.GetDefault(); // The prototype must always be initialized in the constructor. - FML_CHECK(prototype != container.end()); + FML_CHECK(prototype != nullptr); - auto pipeline = prototype->second->WaitAndGet(); + auto pipeline = prototype->WaitAndGet(); if (!pipeline) { return nullptr; } auto variant_future = pipeline->CreateVariant( - [&opts, variants_count = container.size()](PipelineDescriptor& desc) { + [&opts, variants_count = + container.GetPipelineCount()](PipelineDescriptor& desc) { opts.ApplyToPipelineDescriptor(desc); desc.SetLabel( SPrintF("%s V#%zu", desc.GetLabel().c_str(), variants_count)); }); auto variant = std::make_unique(std::move(variant_future)); auto variant_pipeline = variant->WaitAndGet(); - container[opts] = std::move(variant); + container.Set(opts, std::move(variant)); return variant_pipeline; }