Flutter Impeller
content_context.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
6 
7 #include <memory>
8 #include <utility>
9 
10 #include "fml/trace_event.h"
12 #include "impeller/core/formats.h"
17 #include "impeller/entity/entity.h"
26 
27 namespace impeller {
28 
29 namespace {
30 
31 /// Holds multiple Pipelines associated with the same PipelineHandle types.
32 ///
33 /// For example, it may have multiple
34 /// RenderPipelineHandle<SolidFillVertexShader, SolidFillFragmentShader>
35 /// instances for different blend modes. From them you can access the
36 /// Pipeline.
37 ///
38 /// See also:
39 /// - impeller::ContentContextOptions - options from which variants are
40 /// created.
41 /// - impeller::Pipeline::CreateVariant
42 /// - impeller::RenderPipelineHandle<> - The type of objects this typically
43 /// contains.
44 template <class PipelineHandleT>
45 class Variants {
46  static_assert(
47  ShaderStageCompatibilityChecker<
48  typename PipelineHandleT::VertexShader,
49  typename PipelineHandleT::FragmentShader>::Check(),
50  "The output slots for the fragment shader don't have matches in the "
51  "vertex shader's output slots. This will result in a linker error.");
52 
53  public:
54  Variants() = default;
55 
56  void Set(const ContentContextOptions& options,
57  std::unique_ptr<PipelineHandleT> pipeline) {
58  uint64_t p_key = options.ToKey();
59  for (const auto& [key, pipeline] : pipelines_) {
60  if (key == p_key) {
61  return;
62  }
63  }
64  pipelines_.push_back(std::make_pair(p_key, std::move(pipeline)));
65  }
66 
67  void SetDefault(const ContentContextOptions& options,
68  std::unique_ptr<PipelineHandleT> pipeline) {
69  default_options_ = options;
70  if (pipeline) {
71  Set(options, std::move(pipeline));
72  }
73  }
74 
75  void SetDefaultDescriptor(std::optional<PipelineDescriptor> desc) {
76  desc_ = std::move(desc);
77  }
78 
79  void CreateDefault(const Context& context,
80  const ContentContextOptions& options,
81  const std::vector<Scalar>& constants = {}) {
82  auto desc = PipelineHandleT::Builder::MakeDefaultPipelineDescriptor(
83  context, constants);
84  if (!desc.has_value()) {
85  VALIDATION_LOG << "Failed to create default pipeline.";
86  return;
87  }
88  options.ApplyToPipelineDescriptor(*desc);
89  desc_ = desc;
90  if (context.GetFlags().lazy_shader_mode) {
91  SetDefault(options, nullptr);
92  } else {
93  SetDefault(options, std::make_unique<PipelineHandleT>(context, desc_,
94  /*async=*/true));
95  }
96  }
97 
98  PipelineHandleT* Get(const ContentContextOptions& options) const {
99  uint64_t p_key = options.ToKey();
100  for (const auto& [key, pipeline] : pipelines_) {
101  if (key == p_key) {
102  return pipeline.get();
103  }
104  }
105  return nullptr;
106  }
107 
108  bool IsDefault(const ContentContextOptions& opts) {
109  return default_options_.has_value() &&
110  opts.ToKey() == default_options_.value().ToKey();
111  }
112 
113  PipelineHandleT* GetDefault(const Context& context) {
114  if (!default_options_.has_value()) {
115  return nullptr;
116  }
117  PipelineHandleT* result = Get(default_options_.value());
118  if (result != nullptr) {
119  return result;
120  }
121  SetDefault(default_options_.value(), std::make_unique<PipelineHandleT>(
122  context, desc_, /*async=*/false));
123  return Get(default_options_.value());
124  }
125 
126  size_t GetPipelineCount() const { return pipelines_.size(); }
127 
128  private:
129  std::optional<PipelineDescriptor> desc_;
130  std::optional<ContentContextOptions> default_options_;
131  std::vector<std::pair<uint64_t, std::unique_ptr<PipelineHandleT>>> pipelines_;
132 
133  Variants(const Variants&) = delete;
134 
135  Variants& operator=(const Variants&) = delete;
136 };
137 
138 template <class RenderPipelineHandleT>
139 RenderPipelineHandleT* CreateIfNeeded(
140  const ContentContext* context,
141  Variants<RenderPipelineHandleT>& container,
142  ContentContextOptions opts) {
143  if (!context->IsValid()) {
144  return nullptr;
145  }
146 
147  if (RenderPipelineHandleT* found = container.Get(opts)) {
148  return found;
149  }
150 
151  RenderPipelineHandleT* default_handle =
152  container.GetDefault(*context->GetContext());
153  if (container.IsDefault(opts)) {
154  return default_handle;
155  }
156 
157  // The default must always be initialized in the constructor.
158  FML_CHECK(default_handle != nullptr);
159 
160  const std::shared_ptr<Pipeline<PipelineDescriptor>>& pipeline =
161  default_handle->WaitAndGet();
162  if (!pipeline) {
163  return nullptr;
164  }
165 
166  auto variant_future = pipeline->CreateVariant(
167  /*async=*/false, [&opts, variants_count = container.GetPipelineCount()](
168  PipelineDescriptor& desc) {
169  opts.ApplyToPipelineDescriptor(desc);
170  desc.SetLabel(
171  SPrintF("%s V#%zu", desc.GetLabel().data(), variants_count));
172  });
173  std::unique_ptr<RenderPipelineHandleT> variant =
174  std::make_unique<RenderPipelineHandleT>(std::move(variant_future));
175  container.Set(opts, std::move(variant));
176  return container.Get(opts);
177 }
178 
179 template <class TypedPipeline>
180 PipelineRef GetPipeline(const ContentContext* context,
181  Variants<TypedPipeline>& container,
182  ContentContextOptions opts) {
183  TypedPipeline* pipeline = CreateIfNeeded(context, container, opts);
184  if (!pipeline) {
185  return raw_ptr<Pipeline<PipelineDescriptor>>();
186  }
187  return raw_ptr(pipeline->WaitAndGet());
188 }
189 
190 } // namespace
191 
193  // clang-format off
194  Variants<BlendColorBurnPipeline> blend_colorburn;
195  Variants<BlendColorDodgePipeline> blend_colordodge;
196  Variants<BlendColorPipeline> blend_color;
197  Variants<BlendDarkenPipeline> blend_darken;
198  Variants<BlendDifferencePipeline> blend_difference;
199  Variants<BlendExclusionPipeline> blend_exclusion;
200  Variants<BlendHardLightPipeline> blend_hardlight;
201  Variants<BlendHuePipeline> blend_hue;
202  Variants<BlendLightenPipeline> blend_lighten;
203  Variants<BlendLuminosityPipeline> blend_luminosity;
204  Variants<BlendMultiplyPipeline> blend_multiply;
205  Variants<BlendOverlayPipeline> blend_overlay;
206  Variants<BlendSaturationPipeline> blend_saturation;
207  Variants<BlendScreenPipeline> blend_screen;
208  Variants<BlendSoftLightPipeline> blend_softlight;
209  Variants<BorderMaskBlurPipeline> border_mask_blur;
210  Variants<ClipPipeline> clip;
211  Variants<ColorMatrixColorFilterPipeline> color_matrix_color_filter;
212  Variants<ConicalGradientFillConicalPipeline> conical_gradient_fill;
213  Variants<ConicalGradientFillRadialPipeline> conical_gradient_fill_radial;
214  Variants<ConicalGradientFillStripPipeline> conical_gradient_fill_strip;
215  Variants<ConicalGradientFillStripRadialPipeline> conical_gradient_fill_strip_and_radial;
216  Variants<ConicalGradientSSBOFillPipeline> conical_gradient_ssbo_fill;
217  Variants<ConicalGradientSSBOFillPipeline> conical_gradient_ssbo_fill_radial;
218  Variants<ConicalGradientSSBOFillPipeline> conical_gradient_ssbo_fill_strip_and_radial;
219  Variants<ConicalGradientSSBOFillPipeline> conical_gradient_ssbo_fill_strip;
220  Variants<ConicalGradientUniformFillConicalPipeline> conical_gradient_uniform_fill;
221  Variants<ConicalGradientUniformFillRadialPipeline> conical_gradient_uniform_fill_radial;
222  Variants<ConicalGradientUniformFillStripPipeline> conical_gradient_uniform_fill_strip;
223  Variants<ConicalGradientUniformFillStripRadialPipeline> conical_gradient_uniform_fill_strip_and_radial;
224  Variants<FastGradientPipeline> fast_gradient;
225  Variants<FramebufferBlendColorBurnPipeline> framebuffer_blend_colorburn;
226  Variants<FramebufferBlendColorDodgePipeline> framebuffer_blend_colordodge;
227  Variants<FramebufferBlendColorPipeline> framebuffer_blend_color;
228  Variants<FramebufferBlendDarkenPipeline> framebuffer_blend_darken;
229  Variants<FramebufferBlendDifferencePipeline> framebuffer_blend_difference;
230  Variants<FramebufferBlendExclusionPipeline> framebuffer_blend_exclusion;
231  Variants<FramebufferBlendHardLightPipeline> framebuffer_blend_hardlight;
232  Variants<FramebufferBlendHuePipeline> framebuffer_blend_hue;
233  Variants<FramebufferBlendLightenPipeline> framebuffer_blend_lighten;
234  Variants<FramebufferBlendLuminosityPipeline> framebuffer_blend_luminosity;
235  Variants<FramebufferBlendMultiplyPipeline> framebuffer_blend_multiply;
236  Variants<FramebufferBlendOverlayPipeline> framebuffer_blend_overlay;
237  Variants<FramebufferBlendSaturationPipeline> framebuffer_blend_saturation;
238  Variants<FramebufferBlendScreenPipeline> framebuffer_blend_screen;
239  Variants<FramebufferBlendSoftLightPipeline> framebuffer_blend_softlight;
240  Variants<GaussianBlurPipeline> gaussian_blur;
241  Variants<GlyphAtlasPipeline> glyph_atlas;
242  Variants<LinePipeline> line;
243  Variants<LinearGradientFillPipeline> linear_gradient_fill;
244  Variants<LinearGradientSSBOFillPipeline> linear_gradient_ssbo_fill;
245  Variants<LinearGradientUniformFillPipeline> linear_gradient_uniform_fill;
246  Variants<LinearToSrgbFilterPipeline> linear_to_srgb_filter;
247  Variants<MorphologyFilterPipeline> morphology_filter;
248  Variants<PorterDuffBlendPipeline> clear_blend;
249  Variants<PorterDuffBlendPipeline> destination_a_top_blend;
250  Variants<PorterDuffBlendPipeline> destination_blend;
251  Variants<PorterDuffBlendPipeline> destination_in_blend;
252  Variants<PorterDuffBlendPipeline> destination_out_blend;
253  Variants<PorterDuffBlendPipeline> destination_over_blend;
254  Variants<PorterDuffBlendPipeline> modulate_blend;
255  Variants<PorterDuffBlendPipeline> plus_blend;
256  Variants<PorterDuffBlendPipeline> screen_blend;
257  Variants<PorterDuffBlendPipeline> source_a_top_blend;
258  Variants<PorterDuffBlendPipeline> source_blend;
259  Variants<PorterDuffBlendPipeline> source_in_blend;
260  Variants<PorterDuffBlendPipeline> source_out_blend;
261  Variants<PorterDuffBlendPipeline> source_over_blend;
262  Variants<PorterDuffBlendPipeline> xor_blend;
263  Variants<RadialGradientFillPipeline> radial_gradient_fill;
264  Variants<RadialGradientSSBOFillPipeline> radial_gradient_ssbo_fill;
265  Variants<RadialGradientUniformFillPipeline> radial_gradient_uniform_fill;
266  Variants<RRectBlurPipeline> rrect_blur;
267  Variants<SolidFillPipeline> solid_fill;
268  Variants<SrgbToLinearFilterPipeline> srgb_to_linear_filter;
269  Variants<SweepGradientFillPipeline> sweep_gradient_fill;
270  Variants<SweepGradientSSBOFillPipeline> sweep_gradient_ssbo_fill;
271  Variants<SweepGradientUniformFillPipeline> sweep_gradient_uniform_fill;
272  Variants<TextureDownsamplePipeline> texture_downsample;
273  Variants<TexturePipeline> texture;
274  Variants<TextureStrictSrcPipeline> texture_strict_src;
275  Variants<TiledTexturePipeline> tiled_texture;
276  Variants<VerticesUber1Shader> vertices_uber_1_;
277  Variants<VerticesUber2Shader> vertices_uber_2_;
278  Variants<YUVToRGBFilterPipeline> yuv_to_rgb_filter;
279 
280 #ifdef IMPELLER_ENABLE_OPENGLES
281  Variants<TiledTextureExternalPipeline> tiled_texture_external;
282  Variants<TextureDownsampleGlesPipeline> texture_downsample_gles;
283  Variants<TiledTextureUvExternalPipeline> tiled_texture_uv_external;
284 #endif // IMPELLER_ENABLE_OPENGLES
285  // clang-format on
286 };
287 
289  PipelineDescriptor& desc) const {
290  auto pipeline_blend = blend_mode;
292  VALIDATION_LOG << "Cannot use blend mode " << static_cast<int>(blend_mode)
293  << " as a pipeline blend.";
294  pipeline_blend = BlendMode::kSrcOver;
295  }
296 
298 
304 
305  switch (pipeline_blend) {
306  case BlendMode::kClear:
314  } else {
319  }
320  break;
321  case BlendMode::kSrc:
322  color0.blending_enabled = false;
327  break;
328  case BlendMode::kDst:
334  break;
335  case BlendMode::kSrcOver:
340  break;
341  case BlendMode::kDstOver:
346  break;
347  case BlendMode::kSrcIn:
352  break;
353  case BlendMode::kDstIn:
358  break;
359  case BlendMode::kSrcOut:
364  break;
365  case BlendMode::kDstOut:
370  break;
371  case BlendMode::kSrcATop:
376  break;
377  case BlendMode::kDstATop:
382  break;
383  case BlendMode::kXor:
388  break;
389  case BlendMode::kPlus:
394  break;
400  break;
401  default:
402  FML_UNREACHABLE();
403  }
404  desc.SetColorAttachmentDescriptor(0u, color0);
405 
407  desc.ClearDepthAttachment();
409  }
410 
411  auto maybe_stencil = desc.GetFrontStencilAttachmentDescriptor();
412  auto maybe_depth = desc.GetDepthStencilAttachmentDescriptor();
413  FML_DCHECK(has_depth_stencil_attachments == maybe_depth.has_value())
414  << "Depth attachment doesn't match expected pipeline state. "
415  "has_depth_stencil_attachments="
417  FML_DCHECK(has_depth_stencil_attachments == maybe_stencil.has_value())
418  << "Stencil attachment doesn't match expected pipeline state. "
419  "has_depth_stencil_attachments="
421  if (maybe_stencil.has_value()) {
422  StencilAttachmentDescriptor front_stencil = maybe_stencil.value();
423  StencilAttachmentDescriptor back_stencil = front_stencil;
424 
425  switch (stencil_mode) {
429  desc.SetStencilAttachmentDescriptors(front_stencil);
430  break;
432  // The stencil ref should be 0 on commands that use this mode.
437  desc.SetStencilAttachmentDescriptors(front_stencil, back_stencil);
438  break;
440  // The stencil ref should be 0 on commands that use this mode.
444  desc.SetStencilAttachmentDescriptors(front_stencil);
445  break;
447  // The stencil ref should be 0 on commands that use this mode.
449  front_stencil.depth_stencil_pass =
451  desc.SetStencilAttachmentDescriptors(front_stencil);
452  break;
454  // The stencil ref should be 0 on commands that use this mode.
457  desc.SetStencilAttachmentDescriptors(front_stencil);
458  break;
462  desc.SetStencilAttachmentDescriptors(front_stencil);
463  break;
465  front_stencil.stencil_compare = CompareFunction::kLess;
466  front_stencil.depth_stencil_pass =
468  desc.SetStencilAttachmentDescriptors(front_stencil);
469  break;
470  }
471  }
472  if (maybe_depth.has_value()) {
473  DepthAttachmentDescriptor depth = maybe_depth.value();
477  }
478 
481 }
482 
483 std::array<std::vector<Scalar>, 15> GetPorterDuffSpecConstants(
484  bool supports_decal) {
485  Scalar x = supports_decal ? 1 : 0;
486  return {{
487  {x, 0, 0, 0, 0, 0}, // Clear
488  {x, 1, 0, 0, 0, 0}, // Source
489  {x, 0, 0, 1, 0, 0}, // Destination
490  {x, 1, 0, 1, -1, 0}, // SourceOver
491  {x, 1, -1, 1, 0, 0}, // DestinationOver
492  {x, 0, 1, 0, 0, 0}, // SourceIn
493  {x, 0, 0, 0, 1, 0}, // DestinationIn
494  {x, 1, -1, 0, 0, 0}, // SourceOut
495  {x, 0, 0, 1, -1, 0}, // DestinationOut
496  {x, 0, 1, 1, -1, 0}, // SourceATop
497  {x, 1, -1, 0, 1, 0}, // DestinationATop
498  {x, 1, -1, 1, -1, 0}, // Xor
499  {x, 1, 0, 1, 0, 0}, // Plus
500  {x, 0, 0, 0, 0, 1}, // Modulate
501  {x, 0, 0, 1, 0, -1}, // Screen
502  }};
503 }
504 
505 template <typename PipelineT>
506 static std::unique_ptr<PipelineT> CreateDefaultPipeline(
507  const Context& context) {
508  auto desc = PipelineT::Builder::MakeDefaultPipelineDescriptor(context);
509  if (!desc.has_value()) {
510  return nullptr;
511  }
512  // Apply default ContentContextOptions to the descriptor.
513  const auto default_color_format =
514  context.GetCapabilities()->GetDefaultColorFormat();
516  .primitive_type = PrimitiveType::kTriangleStrip,
517  .color_attachment_pixel_format = default_color_format}
518  .ApplyToPipelineDescriptor(*desc);
519  return std::make_unique<PipelineT>(context, desc);
520 }
521 
523  std::shared_ptr<Context> context,
524  std::shared_ptr<TypographerContext> typographer_context,
525  std::shared_ptr<RenderTargetAllocator> render_target_allocator)
526  : context_(std::move(context)),
527  lazy_glyph_atlas_(
528  std::make_shared<LazyGlyphAtlas>(std::move(typographer_context))),
529  pipelines_(new Pipelines()),
530  tessellator_(std::make_shared<Tessellator>()),
531  render_target_cache_(render_target_allocator == nullptr
532  ? std::make_shared<RenderTargetCache>(
533  context_->GetResourceAllocator())
534  : std::move(render_target_allocator)),
535  host_buffer_(HostBuffer::Create(context_->GetResourceAllocator(),
536  context_->GetIdleWaiter())),
537  text_shadow_cache_(std::make_unique<TextShadowCache>()) {
538  if (!context_ || !context_->IsValid()) {
539  return;
540  }
541 
542  {
543  TextureDescriptor desc;
546  desc.size = ISize{1, 1};
547  empty_texture_ = GetContext()->GetResourceAllocator()->CreateTexture(desc);
548 
549  std::array<uint8_t, 4> data = Color::BlackTransparent().ToR8G8B8A8();
550  std::shared_ptr<CommandBuffer> cmd_buffer =
551  GetContext()->CreateCommandBuffer();
552  std::shared_ptr<BlitPass> blit_pass = cmd_buffer->CreateBlitPass();
553  HostBuffer& host_buffer = GetTransientsBuffer();
554  BufferView buffer_view = host_buffer.Emplace(data);
555  blit_pass->AddCopy(buffer_view, empty_texture_);
556 
557  if (!blit_pass->EncodeCommands() || !GetContext()
558  ->GetCommandQueue()
559  ->Submit({std::move(cmd_buffer)})
560  .ok()) {
561  VALIDATION_LOG << "Failed to create empty texture.";
562  }
563  }
564 
565  auto options = ContentContextOptions{
567  .color_attachment_pixel_format =
568  context_->GetCapabilities()->GetDefaultColorFormat()};
569  auto options_trianglestrip = ContentContextOptions{
571  .primitive_type = PrimitiveType::kTriangleStrip,
572  .color_attachment_pixel_format =
573  context_->GetCapabilities()->GetDefaultColorFormat()};
574  auto options_no_msaa_no_depth_stencil = ContentContextOptions{
576  .primitive_type = PrimitiveType::kTriangleStrip,
577  .color_attachment_pixel_format =
578  context_->GetCapabilities()->GetDefaultColorFormat(),
579  .has_depth_stencil_attachments = false};
580  const auto supports_decal = static_cast<Scalar>(
581  context_->GetCapabilities()->SupportsDecalSamplerAddressMode());
582 
583  // Futures for the following pipelines may block in case the first frame is
584  // rendered without the pipelines being ready. Put pipelines that are more
585  // likely to be used first.
586  {
587  pipelines_->glyph_atlas.CreateDefault(
588  *context_, options,
589  {static_cast<Scalar>(
590  GetContext()->GetCapabilities()->GetDefaultGlyphAtlasFormat() ==
592  pipelines_->solid_fill.CreateDefault(*context_, options);
593  pipelines_->texture.CreateDefault(*context_, options);
594  pipelines_->fast_gradient.CreateDefault(*context_, options);
595  pipelines_->line.CreateDefault(*context_, options);
596 
597  if (context_->GetCapabilities()->SupportsSSBO()) {
598  pipelines_->linear_gradient_ssbo_fill.CreateDefault(*context_, options);
599  pipelines_->radial_gradient_ssbo_fill.CreateDefault(*context_, options);
600  pipelines_->conical_gradient_ssbo_fill.CreateDefault(*context_, options,
601  {3.0});
602  pipelines_->conical_gradient_ssbo_fill_radial.CreateDefault(
603  *context_, options, {1.0});
604  pipelines_->conical_gradient_ssbo_fill_strip.CreateDefault(
605  *context_, options, {2.0});
606  pipelines_->conical_gradient_ssbo_fill_strip_and_radial.CreateDefault(
607  *context_, options, {0.0});
608  pipelines_->sweep_gradient_ssbo_fill.CreateDefault(*context_, options);
609  } else {
610  pipelines_->linear_gradient_uniform_fill.CreateDefault(*context_,
611  options);
612  pipelines_->radial_gradient_uniform_fill.CreateDefault(*context_,
613  options);
614  pipelines_->conical_gradient_uniform_fill.CreateDefault(*context_,
615  options);
616  pipelines_->conical_gradient_uniform_fill_radial.CreateDefault(*context_,
617  options);
618  pipelines_->conical_gradient_uniform_fill_strip.CreateDefault(*context_,
619  options);
620  pipelines_->conical_gradient_uniform_fill_strip_and_radial.CreateDefault(
621  *context_, options);
622  pipelines_->sweep_gradient_uniform_fill.CreateDefault(*context_, options);
623 
624  pipelines_->linear_gradient_fill.CreateDefault(*context_, options);
625  pipelines_->radial_gradient_fill.CreateDefault(*context_, options);
626  pipelines_->conical_gradient_fill.CreateDefault(*context_, options);
627  pipelines_->conical_gradient_fill_radial.CreateDefault(*context_,
628  options);
629  pipelines_->conical_gradient_fill_strip.CreateDefault(*context_, options);
630  pipelines_->conical_gradient_fill_strip_and_radial.CreateDefault(
631  *context_, options);
632  pipelines_->sweep_gradient_fill.CreateDefault(*context_, options);
633  }
634 
635  /// Setup default clip pipeline.
636  auto clip_pipeline_descriptor =
638  if (!clip_pipeline_descriptor.has_value()) {
639  return;
640  }
643  .color_attachment_pixel_format =
644  context_->GetCapabilities()->GetDefaultColorFormat()}
645  .ApplyToPipelineDescriptor(*clip_pipeline_descriptor);
646  // Disable write to all color attachments.
647  auto clip_color_attachments =
648  clip_pipeline_descriptor->GetColorAttachmentDescriptors();
649  for (auto& color_attachment : clip_color_attachments) {
650  color_attachment.second.write_mask = ColorWriteMaskBits::kNone;
651  }
652  clip_pipeline_descriptor->SetColorAttachmentDescriptors(
653  std::move(clip_color_attachments));
654  if (GetContext()->GetFlags().lazy_shader_mode) {
655  pipelines_->clip.SetDefaultDescriptor(clip_pipeline_descriptor);
656  pipelines_->clip.SetDefault(options, nullptr);
657  } else {
658  pipelines_->clip.SetDefault(
659  options,
660  std::make_unique<ClipPipeline>(*context_, clip_pipeline_descriptor));
661  }
662  pipelines_->texture_downsample.CreateDefault(
663  *context_, options_no_msaa_no_depth_stencil);
664  pipelines_->rrect_blur.CreateDefault(*context_, options_trianglestrip);
665  pipelines_->texture_strict_src.CreateDefault(*context_, options);
666  pipelines_->tiled_texture.CreateDefault(*context_, options,
667  {supports_decal});
668  pipelines_->gaussian_blur.CreateDefault(
669  *context_, options_no_msaa_no_depth_stencil, {supports_decal});
670  pipelines_->border_mask_blur.CreateDefault(*context_,
671  options_trianglestrip);
672  pipelines_->color_matrix_color_filter.CreateDefault(*context_,
673  options_trianglestrip);
674  pipelines_->vertices_uber_1_.CreateDefault(*context_, options,
675  {supports_decal});
676  pipelines_->vertices_uber_2_.CreateDefault(*context_, options,
677  {supports_decal});
678 
679  const std::array<std::vector<Scalar>, 15> porter_duff_constants =
680  GetPorterDuffSpecConstants(supports_decal);
681  pipelines_->clear_blend.CreateDefault(*context_, options_trianglestrip,
682  porter_duff_constants[0]);
683  pipelines_->source_blend.CreateDefault(*context_, options_trianglestrip,
684  porter_duff_constants[1]);
685  pipelines_->destination_blend.CreateDefault(
686  *context_, options_trianglestrip, porter_duff_constants[2]);
687  pipelines_->source_over_blend.CreateDefault(
688  *context_, options_trianglestrip, porter_duff_constants[3]);
689  pipelines_->destination_over_blend.CreateDefault(
690  *context_, options_trianglestrip, porter_duff_constants[4]);
691  pipelines_->source_in_blend.CreateDefault(*context_, options_trianglestrip,
692  porter_duff_constants[5]);
693  pipelines_->destination_in_blend.CreateDefault(
694  *context_, options_trianglestrip, porter_duff_constants[6]);
695  pipelines_->source_out_blend.CreateDefault(*context_, options_trianglestrip,
696  porter_duff_constants[7]);
697  pipelines_->destination_out_blend.CreateDefault(
698  *context_, options_trianglestrip, porter_duff_constants[8]);
699  pipelines_->source_a_top_blend.CreateDefault(
700  *context_, options_trianglestrip, porter_duff_constants[9]);
701  pipelines_->destination_a_top_blend.CreateDefault(
702  *context_, options_trianglestrip, porter_duff_constants[10]);
703  pipelines_->xor_blend.CreateDefault(*context_, options_trianglestrip,
704  porter_duff_constants[11]);
705  pipelines_->plus_blend.CreateDefault(*context_, options_trianglestrip,
706  porter_duff_constants[12]);
707  pipelines_->modulate_blend.CreateDefault(*context_, options_trianglestrip,
708  porter_duff_constants[13]);
709  pipelines_->screen_blend.CreateDefault(*context_, options_trianglestrip,
710  porter_duff_constants[14]);
711  }
712 
713  if (context_->GetCapabilities()->SupportsFramebufferFetch()) {
714  pipelines_->framebuffer_blend_color.CreateDefault(
715  *context_, options_trianglestrip,
716  {static_cast<Scalar>(BlendSelectValues::kColor), supports_decal});
717  pipelines_->framebuffer_blend_colorburn.CreateDefault(
718  *context_, options_trianglestrip,
719  {static_cast<Scalar>(BlendSelectValues::kColorBurn), supports_decal});
720  pipelines_->framebuffer_blend_colordodge.CreateDefault(
721  *context_, options_trianglestrip,
722  {static_cast<Scalar>(BlendSelectValues::kColorDodge), supports_decal});
723  pipelines_->framebuffer_blend_darken.CreateDefault(
724  *context_, options_trianglestrip,
725  {static_cast<Scalar>(BlendSelectValues::kDarken), supports_decal});
726  pipelines_->framebuffer_blend_difference.CreateDefault(
727  *context_, options_trianglestrip,
728  {static_cast<Scalar>(BlendSelectValues::kDifference), supports_decal});
729  pipelines_->framebuffer_blend_exclusion.CreateDefault(
730  *context_, options_trianglestrip,
731  {static_cast<Scalar>(BlendSelectValues::kExclusion), supports_decal});
732  pipelines_->framebuffer_blend_hardlight.CreateDefault(
733  *context_, options_trianglestrip,
734  {static_cast<Scalar>(BlendSelectValues::kHardLight), supports_decal});
735  pipelines_->framebuffer_blend_hue.CreateDefault(
736  *context_, options_trianglestrip,
737  {static_cast<Scalar>(BlendSelectValues::kHue), supports_decal});
738  pipelines_->framebuffer_blend_lighten.CreateDefault(
739  *context_, options_trianglestrip,
740  {static_cast<Scalar>(BlendSelectValues::kLighten), supports_decal});
741  pipelines_->framebuffer_blend_luminosity.CreateDefault(
742  *context_, options_trianglestrip,
743  {static_cast<Scalar>(BlendSelectValues::kLuminosity), supports_decal});
744  pipelines_->framebuffer_blend_multiply.CreateDefault(
745  *context_, options_trianglestrip,
746  {static_cast<Scalar>(BlendSelectValues::kMultiply), supports_decal});
747  pipelines_->framebuffer_blend_overlay.CreateDefault(
748  *context_, options_trianglestrip,
749  {static_cast<Scalar>(BlendSelectValues::kOverlay), supports_decal});
750  pipelines_->framebuffer_blend_saturation.CreateDefault(
751  *context_, options_trianglestrip,
752  {static_cast<Scalar>(BlendSelectValues::kSaturation), supports_decal});
753  pipelines_->framebuffer_blend_screen.CreateDefault(
754  *context_, options_trianglestrip,
755  {static_cast<Scalar>(BlendSelectValues::kScreen), supports_decal});
756  pipelines_->framebuffer_blend_softlight.CreateDefault(
757  *context_, options_trianglestrip,
758  {static_cast<Scalar>(BlendSelectValues::kSoftLight), supports_decal});
759  } else {
760  pipelines_->blend_color.CreateDefault(
761  *context_, options_trianglestrip,
762  {static_cast<Scalar>(BlendSelectValues::kColor), supports_decal});
763  pipelines_->blend_colorburn.CreateDefault(
764  *context_, options_trianglestrip,
765  {static_cast<Scalar>(BlendSelectValues::kColorBurn), supports_decal});
766  pipelines_->blend_colordodge.CreateDefault(
767  *context_, options_trianglestrip,
768  {static_cast<Scalar>(BlendSelectValues::kColorDodge), supports_decal});
769  pipelines_->blend_darken.CreateDefault(
770  *context_, options_trianglestrip,
771  {static_cast<Scalar>(BlendSelectValues::kDarken), supports_decal});
772  pipelines_->blend_difference.CreateDefault(
773  *context_, options_trianglestrip,
774  {static_cast<Scalar>(BlendSelectValues::kDifference), supports_decal});
775  pipelines_->blend_exclusion.CreateDefault(
776  *context_, options_trianglestrip,
777  {static_cast<Scalar>(BlendSelectValues::kExclusion), supports_decal});
778  pipelines_->blend_hardlight.CreateDefault(
779  *context_, options_trianglestrip,
780  {static_cast<Scalar>(BlendSelectValues::kHardLight), supports_decal});
781  pipelines_->blend_hue.CreateDefault(
782  *context_, options_trianglestrip,
783  {static_cast<Scalar>(BlendSelectValues::kHue), supports_decal});
784  pipelines_->blend_lighten.CreateDefault(
785  *context_, options_trianglestrip,
786  {static_cast<Scalar>(BlendSelectValues::kLighten), supports_decal});
787  pipelines_->blend_luminosity.CreateDefault(
788  *context_, options_trianglestrip,
789  {static_cast<Scalar>(BlendSelectValues::kLuminosity), supports_decal});
790  pipelines_->blend_multiply.CreateDefault(
791  *context_, options_trianglestrip,
792  {static_cast<Scalar>(BlendSelectValues::kMultiply), supports_decal});
793  pipelines_->blend_overlay.CreateDefault(
794  *context_, options_trianglestrip,
795  {static_cast<Scalar>(BlendSelectValues::kOverlay), supports_decal});
796  pipelines_->blend_saturation.CreateDefault(
797  *context_, options_trianglestrip,
798  {static_cast<Scalar>(BlendSelectValues::kSaturation), supports_decal});
799  pipelines_->blend_screen.CreateDefault(
800  *context_, options_trianglestrip,
801  {static_cast<Scalar>(BlendSelectValues::kScreen), supports_decal});
802  pipelines_->blend_softlight.CreateDefault(
803  *context_, options_trianglestrip,
804  {static_cast<Scalar>(BlendSelectValues::kSoftLight), supports_decal});
805  }
806 
807  pipelines_->morphology_filter.CreateDefault(*context_, options_trianglestrip,
808  {supports_decal});
809  pipelines_->linear_to_srgb_filter.CreateDefault(*context_,
810  options_trianglestrip);
811  pipelines_->srgb_to_linear_filter.CreateDefault(*context_,
812  options_trianglestrip);
813  pipelines_->yuv_to_rgb_filter.CreateDefault(*context_, options_trianglestrip);
814 
815 #if defined(IMPELLER_ENABLE_OPENGLES)
816  if (GetContext()->GetBackendType() == Context::BackendType::kOpenGLES) {
817 #if !defined(FML_OS_MACOSX)
818  // GLES only shader that is unsupported on macOS.
819  pipelines_->tiled_texture_external.CreateDefault(*context_, options);
820  pipelines_->tiled_texture_uv_external.CreateDefault(*context_, options);
821 #endif // !defined(FML_OS_MACOSX)
822  pipelines_->texture_downsample_gles.CreateDefault(*context_,
823  options_trianglestrip);
824  }
825 #endif // IMPELLER_ENABLE_OPENGLES
826 
827  is_valid_ = true;
828  InitializeCommonlyUsedShadersIfNeeded();
829 }
830 
832 
834  return is_valid_;
835 }
836 
837 std::shared_ptr<Texture> ContentContext::GetEmptyTexture() const {
838  return empty_texture_;
839 }
840 
841 fml::StatusOr<RenderTarget> ContentContext::MakeSubpass(
842  std::string_view label,
843  ISize texture_size,
844  const std::shared_ptr<CommandBuffer>& command_buffer,
845  const SubpassCallback& subpass_callback,
846  bool msaa_enabled,
847  bool depth_stencil_enabled,
848  int32_t mip_count) const {
849  const std::shared_ptr<Context>& context = GetContext();
850  RenderTarget subpass_target;
851 
852  std::optional<RenderTarget::AttachmentConfig> depth_stencil_config =
853  depth_stencil_enabled ? RenderTarget::kDefaultStencilAttachmentConfig
854  : std::optional<RenderTarget::AttachmentConfig>();
855 
856  if (context->GetCapabilities()->SupportsOffscreenMSAA() && msaa_enabled) {
857  subpass_target = GetRenderTargetCache()->CreateOffscreenMSAA(
858  *context, texture_size,
859  /*mip_count=*/mip_count, label,
861  } else {
862  subpass_target = GetRenderTargetCache()->CreateOffscreen(
863  *context, texture_size,
864  /*mip_count=*/mip_count, label,
865  RenderTarget::kDefaultColorAttachmentConfig, depth_stencil_config);
866  }
867  return MakeSubpass(label, subpass_target, command_buffer, subpass_callback);
868 }
869 
870 fml::StatusOr<RenderTarget> ContentContext::MakeSubpass(
871  std::string_view label,
872  const RenderTarget& subpass_target,
873  const std::shared_ptr<CommandBuffer>& command_buffer,
874  const SubpassCallback& subpass_callback) const {
875  const std::shared_ptr<Context>& context = GetContext();
876 
877  auto subpass_texture = subpass_target.GetRenderTargetTexture();
878  if (!subpass_texture) {
879  return fml::Status(fml::StatusCode::kUnknown, "");
880  }
881 
882  auto sub_renderpass = command_buffer->CreateRenderPass(subpass_target);
883  if (!sub_renderpass) {
884  return fml::Status(fml::StatusCode::kUnknown, "");
885  }
886  sub_renderpass->SetLabel(label);
887 
888  if (!subpass_callback(*this, *sub_renderpass)) {
889  return fml::Status(fml::StatusCode::kUnknown, "");
890  }
891 
892  if (!sub_renderpass->EncodeCommands()) {
893  return fml::Status(fml::StatusCode::kUnknown, "");
894  }
895 
896  const std::shared_ptr<Texture>& target_texture =
897  subpass_target.GetRenderTargetTexture();
898  if (target_texture->GetMipCount() > 1) {
899  fml::Status mipmap_status =
900  AddMipmapGeneration(command_buffer, context, target_texture);
901  if (!mipmap_status.ok()) {
902  return mipmap_status;
903  }
904  }
905 
906  return subpass_target;
907 }
908 
910  return *tessellator_;
911 }
912 
913 std::shared_ptr<Context> ContentContext::GetContext() const {
914  return context_;
915 }
916 
918  return *context_->GetCapabilities();
919 }
920 
922  const std::string& unique_entrypoint_name,
923  const ContentContextOptions& options,
924  const std::function<std::shared_ptr<Pipeline<PipelineDescriptor>>()>&
925  create_callback) const {
926  RuntimeEffectPipelineKey key{unique_entrypoint_name, options};
927  auto it = runtime_effect_pipelines_.find(key);
928  if (it == runtime_effect_pipelines_.end()) {
929  it = runtime_effect_pipelines_.insert(it, {key, create_callback()});
930  }
931  return raw_ptr(it->second);
932 }
933 
935  const std::string& unique_entrypoint_name) const {
936  for (auto it = runtime_effect_pipelines_.begin();
937  it != runtime_effect_pipelines_.end();) {
938  if (it->first.unique_entrypoint_name == unique_entrypoint_name) {
939  it = runtime_effect_pipelines_.erase(it);
940  } else {
941  it++;
942  }
943  }
944 }
945 
946 void ContentContext::InitializeCommonlyUsedShadersIfNeeded() const {
947  if (GetContext()->GetFlags().lazy_shader_mode) {
948  return;
949  }
950  GetContext()->InitializeCommonlyUsedShadersIfNeeded();
951 }
952 
954  ContentContextOptions opts) const {
955  return GetPipeline(this, pipelines_->fast_gradient, opts);
956 }
957 
959  ContentContextOptions opts) const {
960  return GetPipeline(this, pipelines_->linear_gradient_fill, opts);
961 }
962 
964  ContentContextOptions opts) const {
965  return GetPipeline(this, pipelines_->linear_gradient_uniform_fill, opts);
966 }
967 
969  ContentContextOptions opts) const {
970  return GetPipeline(this, pipelines_->radial_gradient_uniform_fill, opts);
971 }
972 
974  ContentContextOptions opts) const {
975  return GetPipeline(this, pipelines_->sweep_gradient_uniform_fill, opts);
976 }
977 
979  ContentContextOptions opts) const {
980  FML_DCHECK(GetDeviceCapabilities().SupportsSSBO());
981  return GetPipeline(this, pipelines_->linear_gradient_ssbo_fill, opts);
982 }
983 
985  ContentContextOptions opts) const {
986  FML_DCHECK(GetDeviceCapabilities().SupportsSSBO());
987  return GetPipeline(this, pipelines_->radial_gradient_ssbo_fill, opts);
988 }
989 
992  ConicalKind kind) const {
993  switch (kind) {
995  return GetPipeline(this, pipelines_->conical_gradient_uniform_fill, opts);
997  return GetPipeline(this, pipelines_->conical_gradient_uniform_fill_radial,
998  opts);
999  case ConicalKind::kStrip:
1000  return GetPipeline(this, pipelines_->conical_gradient_uniform_fill_strip,
1001  opts);
1003  return GetPipeline(
1004  this, pipelines_->conical_gradient_uniform_fill_strip_and_radial,
1005  opts);
1006  }
1007 }
1008 
1010  ContentContextOptions opts,
1011  ConicalKind kind) const {
1012  FML_DCHECK(GetDeviceCapabilities().SupportsSSBO());
1013  switch (kind) {
1014  case ConicalKind::kConical:
1015  return GetPipeline(this, pipelines_->conical_gradient_ssbo_fill, opts);
1016  case ConicalKind::kRadial:
1017  return GetPipeline(this, pipelines_->conical_gradient_ssbo_fill_radial,
1018  opts);
1019  case ConicalKind::kStrip:
1020  return GetPipeline(this, pipelines_->conical_gradient_ssbo_fill_strip,
1021  opts);
1023  return GetPipeline(
1024  this, pipelines_->conical_gradient_ssbo_fill_strip_and_radial, opts);
1025  }
1026 }
1027 
1029  ContentContextOptions opts) const {
1030  FML_DCHECK(GetDeviceCapabilities().SupportsSSBO());
1031  return GetPipeline(this, pipelines_->sweep_gradient_ssbo_fill, opts);
1032 }
1033 
1035  ContentContextOptions opts) const {
1036  return GetPipeline(this, pipelines_->radial_gradient_fill, opts);
1037 }
1038 
1040  ContentContextOptions opts,
1041  ConicalKind kind) const {
1042  switch (kind) {
1043  case ConicalKind::kConical:
1044  return GetPipeline(this, pipelines_->conical_gradient_fill, opts);
1045  case ConicalKind::kRadial:
1046  return GetPipeline(this, pipelines_->conical_gradient_fill_radial, opts);
1047  case ConicalKind::kStrip:
1048  return GetPipeline(this, pipelines_->conical_gradient_fill_strip, opts);
1050  return GetPipeline(
1051  this, pipelines_->conical_gradient_fill_strip_and_radial, opts);
1052  }
1053 }
1054 
1056  ContentContextOptions opts) const {
1057  return GetPipeline(this, pipelines_->rrect_blur, opts);
1058 }
1059 
1061  ContentContextOptions opts) const {
1062  return GetPipeline(this, pipelines_->sweep_gradient_fill, opts);
1063 }
1064 
1066  ContentContextOptions opts) const {
1067  return GetPipeline(this, pipelines_->solid_fill, opts);
1068 }
1069 
1071  ContentContextOptions opts) const {
1072  return GetPipeline(this, pipelines_->texture, opts);
1073 }
1074 
1076  ContentContextOptions opts) const {
1077  return GetPipeline(this, pipelines_->texture_strict_src, opts);
1078 }
1079 
1081  ContentContextOptions opts) const {
1082  return GetPipeline(this, pipelines_->tiled_texture, opts);
1083 }
1084 
1086  ContentContextOptions opts) const {
1087  return GetPipeline(this, pipelines_->gaussian_blur, opts);
1088 }
1089 
1091  ContentContextOptions opts) const {
1092  return GetPipeline(this, pipelines_->border_mask_blur, opts);
1093 }
1094 
1096  ContentContextOptions opts) const {
1097  return GetPipeline(this, pipelines_->morphology_filter, opts);
1098 }
1099 
1101  ContentContextOptions opts) const {
1102  return GetPipeline(this, pipelines_->color_matrix_color_filter, opts);
1103 }
1104 
1106  ContentContextOptions opts) const {
1107  return GetPipeline(this, pipelines_->linear_to_srgb_filter, opts);
1108 }
1109 
1111  ContentContextOptions opts) const {
1112  return GetPipeline(this, pipelines_->srgb_to_linear_filter, opts);
1113 }
1114 
1116  return GetPipeline(this, pipelines_->clip, opts);
1117 }
1118 
1120  ContentContextOptions opts) const {
1121  return GetPipeline(this, pipelines_->glyph_atlas, opts);
1122 }
1123 
1125  ContentContextOptions opts) const {
1126  return GetPipeline(this, pipelines_->yuv_to_rgb_filter, opts);
1127 }
1128 
1130  BlendMode mode,
1131  ContentContextOptions opts) const {
1132  switch (mode) {
1133  case BlendMode::kClear:
1134  return GetClearBlendPipeline(opts);
1135  case BlendMode::kSrc:
1136  return GetSourceBlendPipeline(opts);
1137  case BlendMode::kDst:
1138  return GetDestinationBlendPipeline(opts);
1139  case BlendMode::kSrcOver:
1140  return GetSourceOverBlendPipeline(opts);
1141  case BlendMode::kDstOver:
1142  return GetDestinationOverBlendPipeline(opts);
1143  case BlendMode::kSrcIn:
1144  return GetSourceInBlendPipeline(opts);
1145  case BlendMode::kDstIn:
1146  return GetDestinationInBlendPipeline(opts);
1147  case BlendMode::kSrcOut:
1148  return GetSourceOutBlendPipeline(opts);
1149  case BlendMode::kDstOut:
1150  return GetDestinationOutBlendPipeline(opts);
1151  case BlendMode::kSrcATop:
1152  return GetSourceATopBlendPipeline(opts);
1153  case BlendMode::kDstATop:
1154  return GetDestinationATopBlendPipeline(opts);
1155  case BlendMode::kXor:
1156  return GetXorBlendPipeline(opts);
1157  case BlendMode::kPlus:
1158  return GetPlusBlendPipeline(opts);
1159  case BlendMode::kModulate:
1160  return GetModulateBlendPipeline(opts);
1161  case BlendMode::kScreen:
1162  return GetScreenBlendPipeline(opts);
1163  case BlendMode::kOverlay:
1164  case BlendMode::kDarken:
1165  case BlendMode::kLighten:
1167  case BlendMode::kColorBurn:
1168  case BlendMode::kHardLight:
1169  case BlendMode::kSoftLight:
1171  case BlendMode::kExclusion:
1172  case BlendMode::kMultiply:
1173  case BlendMode::kHue:
1175  case BlendMode::kColor:
1177  VALIDATION_LOG << "Invalid porter duff blend mode "
1178  << BlendModeToString(mode);
1179  return GetClearBlendPipeline(opts);
1180  break;
1181  }
1182 }
1183 
1185  ContentContextOptions opts) const {
1186  return GetPipeline(this, pipelines_->clear_blend, opts);
1187 }
1188 
1190  ContentContextOptions opts) const {
1191  return GetPipeline(this, pipelines_->source_blend, opts);
1192 }
1193 
1195  ContentContextOptions opts) const {
1196  return GetPipeline(this, pipelines_->destination_blend, opts);
1197 }
1198 
1200  ContentContextOptions opts) const {
1201  return GetPipeline(this, pipelines_->source_over_blend, opts);
1202 }
1203 
1205  ContentContextOptions opts) const {
1206  return GetPipeline(this, pipelines_->destination_over_blend, opts);
1207 }
1208 
1210  ContentContextOptions opts) const {
1211  return GetPipeline(this, pipelines_->source_in_blend, opts);
1212 }
1213 
1215  ContentContextOptions opts) const {
1216  return GetPipeline(this, pipelines_->destination_in_blend, opts);
1217 }
1218 
1220  ContentContextOptions opts) const {
1221  return GetPipeline(this, pipelines_->source_out_blend, opts);
1222 }
1223 
1225  ContentContextOptions opts) const {
1226  return GetPipeline(this, pipelines_->destination_out_blend, opts);
1227 }
1228 
1230  ContentContextOptions opts) const {
1231  return GetPipeline(this, pipelines_->source_a_top_blend, opts);
1232 }
1233 
1235  ContentContextOptions opts) const {
1236  return GetPipeline(this, pipelines_->destination_a_top_blend, opts);
1237 }
1238 
1240  ContentContextOptions opts) const {
1241  return GetPipeline(this, pipelines_->xor_blend, opts);
1242 }
1243 
1245  ContentContextOptions opts) const {
1246  return GetPipeline(this, pipelines_->plus_blend, opts);
1247 }
1248 
1250  ContentContextOptions opts) const {
1251  return GetPipeline(this, pipelines_->modulate_blend, opts);
1252 }
1253 
1255  ContentContextOptions opts) const {
1256  return GetPipeline(this, pipelines_->screen_blend, opts);
1257 }
1258 
1260  ContentContextOptions opts) const {
1261  return GetPipeline(this, pipelines_->blend_color, opts);
1262 }
1263 
1265  ContentContextOptions opts) const {
1266  return GetPipeline(this, pipelines_->blend_colorburn, opts);
1267 }
1268 
1270  ContentContextOptions opts) const {
1271  return GetPipeline(this, pipelines_->blend_colordodge, opts);
1272 }
1273 
1275  ContentContextOptions opts) const {
1276  return GetPipeline(this, pipelines_->blend_darken, opts);
1277 }
1278 
1280  ContentContextOptions opts) const {
1281  return GetPipeline(this, pipelines_->blend_difference, opts);
1282 }
1283 
1285  ContentContextOptions opts) const {
1286  return GetPipeline(this, pipelines_->blend_exclusion, opts);
1287 }
1288 
1290  ContentContextOptions opts) const {
1291  return GetPipeline(this, pipelines_->blend_hardlight, opts);
1292 }
1293 
1295  ContentContextOptions opts) const {
1296  return GetPipeline(this, pipelines_->blend_hue, opts);
1297 }
1298 
1300  ContentContextOptions opts) const {
1301  return GetPipeline(this, pipelines_->blend_lighten, opts);
1302 }
1303 
1305  ContentContextOptions opts) const {
1306  return GetPipeline(this, pipelines_->blend_luminosity, opts);
1307 }
1308 
1310  ContentContextOptions opts) const {
1311  return GetPipeline(this, pipelines_->blend_multiply, opts);
1312 }
1313 
1315  ContentContextOptions opts) const {
1316  return GetPipeline(this, pipelines_->blend_overlay, opts);
1317 }
1318 
1320  ContentContextOptions opts) const {
1321  return GetPipeline(this, pipelines_->blend_saturation, opts);
1322 }
1323 
1325  ContentContextOptions opts) const {
1326  return GetPipeline(this, pipelines_->blend_screen, opts);
1327 }
1328 
1330  ContentContextOptions opts) const {
1331  return GetPipeline(this, pipelines_->blend_softlight, opts);
1332 }
1333 
1335  ContentContextOptions opts) const {
1336  return GetPipeline(this, pipelines_->texture_downsample, opts);
1337 }
1338 
1340  ContentContextOptions opts) const {
1341  FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
1342  return GetPipeline(this, pipelines_->framebuffer_blend_color, opts);
1343 }
1344 
1346  ContentContextOptions opts) const {
1347  FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
1348  return GetPipeline(this, pipelines_->framebuffer_blend_colorburn, opts);
1349 }
1350 
1352  ContentContextOptions opts) const {
1353  FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
1354  return GetPipeline(this, pipelines_->framebuffer_blend_colordodge, opts);
1355 }
1356 
1358  ContentContextOptions opts) const {
1359  FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
1360  return GetPipeline(this, pipelines_->framebuffer_blend_darken, opts);
1361 }
1362 
1364  ContentContextOptions opts) const {
1365  FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
1366  return GetPipeline(this, pipelines_->framebuffer_blend_difference, opts);
1367 }
1368 
1370  ContentContextOptions opts) const {
1371  FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
1372  return GetPipeline(this, pipelines_->framebuffer_blend_exclusion, opts);
1373 }
1374 
1376  ContentContextOptions opts) const {
1377  FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
1378  return GetPipeline(this, pipelines_->framebuffer_blend_hardlight, opts);
1379 }
1380 
1382  ContentContextOptions opts) const {
1383  FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
1384  return GetPipeline(this, pipelines_->framebuffer_blend_hue, opts);
1385 }
1386 
1388  ContentContextOptions opts) const {
1389  FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
1390  return GetPipeline(this, pipelines_->framebuffer_blend_lighten, opts);
1391 }
1392 
1394  ContentContextOptions opts) const {
1395  FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
1396  return GetPipeline(this, pipelines_->framebuffer_blend_luminosity, opts);
1397 }
1398 
1400  ContentContextOptions opts) const {
1401  FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
1402  return GetPipeline(this, pipelines_->framebuffer_blend_multiply, opts);
1403 }
1404 
1406  ContentContextOptions opts) const {
1407  FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
1408  return GetPipeline(this, pipelines_->framebuffer_blend_overlay, opts);
1409 }
1410 
1412  ContentContextOptions opts) const {
1413  FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
1414  return GetPipeline(this, pipelines_->framebuffer_blend_saturation, opts);
1415 }
1416 
1418  ContentContextOptions opts) const {
1419  FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
1420  return GetPipeline(this, pipelines_->framebuffer_blend_screen, opts);
1421 }
1422 
1424  ContentContextOptions opts) const {
1425  FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
1426  return GetPipeline(this, pipelines_->framebuffer_blend_softlight, opts);
1427 }
1428 
1430  BlendMode blend_mode,
1431  ContentContextOptions opts) const {
1432  if (blend_mode <= BlendMode::kHardLight) {
1433  return GetPipeline(this, pipelines_->vertices_uber_1_, opts);
1434  } else {
1435  return GetPipeline(this, pipelines_->vertices_uber_2_, opts);
1436  }
1437 }
1438 
1440  return GetPipeline(this, pipelines_->line, opts);
1441 }
1442 
1443 #ifdef IMPELLER_ENABLE_OPENGLES
1444 PipelineRef ContentContext::GetDownsampleTextureGlesPipeline(
1445  ContentContextOptions opts) const {
1446  return GetPipeline(this, pipelines_->texture_downsample_gles, opts);
1447 }
1448 
1449 PipelineRef ContentContext::GetTiledTextureExternalPipeline(
1450  ContentContextOptions opts) const {
1451  FML_DCHECK(GetContext()->GetBackendType() == Context::BackendType::kOpenGLES);
1452  return GetPipeline(this, pipelines_->tiled_texture_external, opts);
1453 }
1454 
1455 PipelineRef ContentContext::GetTiledTextureUvExternalPipeline(
1456  ContentContextOptions opts) const {
1457  FML_DCHECK(GetContext()->GetBackendType() == Context::BackendType::kOpenGLES);
1458  return GetPipeline(this, pipelines_->tiled_texture_uv_external, opts);
1459 }
1460 #endif // IMPELLER_ENABLE_OPENGLES
1461 
1462 } // namespace impeller
BufferView buffer_view
PipelineRef GetBlendLuminosityPipeline(ContentContextOptions opts) const
HostBuffer & GetTransientsBuffer() const
Retrieve the currnent host buffer for transient storage.
PipelineRef GetTiledTexturePipeline(ContentContextOptions opts) const
PipelineRef GetFramebufferBlendColorPipeline(ContentContextOptions opts) const
PipelineRef GetDownsamplePipeline(ContentContextOptions opts) const
PipelineRef GetSourceInBlendPipeline(ContentContextOptions opts) const
void ClearCachedRuntimeEffectPipeline(const std::string &unique_entrypoint_name) const
PipelineRef GetLinearGradientFillPipeline(ContentContextOptions opts) const
PipelineRef GetFramebufferBlendOverlayPipeline(ContentContextOptions opts) const
PipelineRef GetBlendColorDodgePipeline(ContentContextOptions opts) const
PipelineRef GetFramebufferBlendColorBurnPipeline(ContentContextOptions opts) const
PipelineRef GetPorterDuffPipeline(BlendMode mode, ContentContextOptions opts) const
std::shared_ptr< Texture > GetEmptyTexture() const
PipelineRef GetSourceOutBlendPipeline(ContentContextOptions opts) const
PipelineRef GetScreenBlendPipeline(ContentContextOptions opts) const
PipelineRef GetBlendColorPipeline(ContentContextOptions opts) const
PipelineRef GetLinePipeline(ContentContextOptions opts) const
PipelineRef GetFramebufferBlendLuminosityPipeline(ContentContextOptions opts) const
PipelineRef GetPlusBlendPipeline(ContentContextOptions opts) const
PipelineRef GetFastGradientPipeline(ContentContextOptions opts) const
ContentContext(std::shared_ptr< Context > context, std::shared_ptr< TypographerContext > typographer_context, std::shared_ptr< RenderTargetAllocator > render_target_allocator=nullptr)
PipelineRef GetSolidFillPipeline(ContentContextOptions opts) const
fml::StatusOr< RenderTarget > MakeSubpass(std::string_view label, ISize texture_size, const std::shared_ptr< CommandBuffer > &command_buffer, const SubpassCallback &subpass_callback, bool msaa_enabled=true, bool depth_stencil_enabled=false, int32_t mip_count=1) const
Creates a new texture of size texture_size and calls subpass_callback with a RenderPass for drawing t...
const Capabilities & GetDeviceCapabilities() const
PipelineRef GetModulateBlendPipeline(ContentContextOptions opts) const
PipelineRef GetFramebufferBlendHardLightPipeline(ContentContextOptions opts) const
PipelineRef GetFramebufferBlendColorDodgePipeline(ContentContextOptions opts) const
PipelineRef GetSweepGradientUniformFillPipeline(ContentContextOptions opts) const
PipelineRef GetBlendSoftLightPipeline(ContentContextOptions opts) const
PipelineRef GetDestinationATopBlendPipeline(ContentContextOptions opts) const
PipelineRef GetTextureStrictSrcPipeline(ContentContextOptions opts) const
PipelineRef GetCachedRuntimeEffectPipeline(const std::string &unique_entrypoint_name, const ContentContextOptions &options, const std::function< std::shared_ptr< Pipeline< PipelineDescriptor >>()> &create_callback) const
PipelineRef GetRadialGradientSSBOFillPipeline(ContentContextOptions opts) const
PipelineRef GetBlendColorBurnPipeline(ContentContextOptions opts) const
PipelineRef GetSweepGradientSSBOFillPipeline(ContentContextOptions opts) const
PipelineRef GetLinearGradientUniformFillPipeline(ContentContextOptions opts) const
PipelineRef GetFramebufferBlendScreenPipeline(ContentContextOptions opts) const
PipelineRef GetLinearGradientSSBOFillPipeline(ContentContextOptions opts) const
PipelineRef GetRadialGradientFillPipeline(ContentContextOptions opts) const
PipelineRef GetTexturePipeline(ContentContextOptions opts) const
PipelineRef GetBlendHardLightPipeline(ContentContextOptions opts) const
PipelineRef GetClearBlendPipeline(ContentContextOptions opts) const
PipelineRef GetConicalGradientUniformFillPipeline(ContentContextOptions opts, ConicalKind kind) const
PipelineRef GetRadialGradientUniformFillPipeline(ContentContextOptions opts) const
PipelineRef GetSweepGradientFillPipeline(ContentContextOptions opts) const
PipelineRef GetFramebufferBlendExclusionPipeline(ContentContextOptions opts) const
PipelineRef GetFramebufferBlendDarkenPipeline(ContentContextOptions opts) const
PipelineRef GetBlendSaturationPipeline(ContentContextOptions opts) const
PipelineRef GetFramebufferBlendSoftLightPipeline(ContentContextOptions opts) const
PipelineRef GetFramebufferBlendLightenPipeline(ContentContextOptions opts) const
PipelineRef GetMorphologyFilterPipeline(ContentContextOptions opts) const
PipelineRef GetFramebufferBlendSaturationPipeline(ContentContextOptions opts) const
PipelineRef GetBlendDifferencePipeline(ContentContextOptions opts) const
PipelineRef GetGaussianBlurPipeline(ContentContextOptions opts) const
PipelineRef GetBlendHuePipeline(ContentContextOptions opts) const
PipelineRef GetSrgbToLinearFilterPipeline(ContentContextOptions opts) const
PipelineRef GetDestinationOutBlendPipeline(ContentContextOptions opts) const
PipelineRef GetYUVToRGBFilterPipeline(ContentContextOptions opts) const
PipelineRef GetFramebufferBlendDifferencePipeline(ContentContextOptions opts) const
PipelineRef GetFramebufferBlendHuePipeline(ContentContextOptions opts) const
PipelineRef GetSourceATopBlendPipeline(ContentContextOptions opts) const
PipelineRef GetXorBlendPipeline(ContentContextOptions opts) const
PipelineRef GetGlyphAtlasPipeline(ContentContextOptions opts) const
PipelineRef GetClipPipeline(ContentContextOptions opts) const
const std::shared_ptr< RenderTargetAllocator > & GetRenderTargetCache() const
PipelineRef GetRRectBlurPipeline(ContentContextOptions opts) const
PipelineRef GetBlendScreenPipeline(ContentContextOptions opts) const
std::function< bool(const ContentContext &, RenderPass &)> SubpassCallback
PipelineRef GetBlendDarkenPipeline(ContentContextOptions opts) const
PipelineRef GetSourceBlendPipeline(ContentContextOptions opts) const
PipelineRef GetLinearToSrgbFilterPipeline(ContentContextOptions opts) const
PipelineRef GetBlendOverlayPipeline(ContentContextOptions opts) const
PipelineRef GetDestinationBlendPipeline(ContentContextOptions opts) const
PipelineRef GetDestinationOverBlendPipeline(ContentContextOptions opts) const
PipelineRef GetFramebufferBlendMultiplyPipeline(ContentContextOptions opts) const
PipelineRef GetConicalGradientSSBOFillPipeline(ContentContextOptions opts, ConicalKind kind) const
Tessellator & GetTessellator() const
PipelineRef GetBlendLightenPipeline(ContentContextOptions opts) const
PipelineRef GetBlendMultiplyPipeline(ContentContextOptions opts) const
PipelineRef GetSourceOverBlendPipeline(ContentContextOptions opts) const
PipelineRef GetBlendExclusionPipeline(ContentContextOptions opts) const
PipelineRef GetColorMatrixColorFilterPipeline(ContentContextOptions opts) const
PipelineRef GetConicalGradientFillPipeline(ContentContextOptions opts, ConicalKind kind) const
std::shared_ptr< Context > GetContext() const
PipelineRef GetDestinationInBlendPipeline(ContentContextOptions opts) const
PipelineRef GetBorderMaskBlurPipeline(ContentContextOptions opts) const
PipelineRef GetDrawVerticesUberPipeline(BlendMode blend_mode, ContentContextOptions opts) const
To do anything rendering related with Impeller, you need a context.
Definition: context.h:47
virtual const std::shared_ptr< const Capabilities > & GetCapabilities() const =0
Get the capabilities of Impeller context. All optionally supported feature of the platform,...
static constexpr BlendMode kLastPipelineBlendMode
Definition: entity.h:22
BufferView Emplace(const BufferType &buffer, size_t alignment=0)
Emplace non-uniform data (like contiguous vertices) onto the host buffer.
Definition: host_buffer.h:93
PipelineDescriptor & SetDepthStencilAttachmentDescriptor(std::optional< DepthAttachmentDescriptor > desc)
void SetPolygonMode(PolygonMode mode)
std::optional< DepthAttachmentDescriptor > GetDepthStencilAttachmentDescriptor() const
PipelineDescriptor & SetStencilAttachmentDescriptors(std::optional< StencilAttachmentDescriptor > front_and_back)
const ColorAttachmentDescriptor * GetColorAttachmentDescriptor(size_t index) const
PipelineDescriptor & SetColorAttachmentDescriptor(size_t index, ColorAttachmentDescriptor desc)
PipelineDescriptor & SetSampleCount(SampleCount samples)
void SetPrimitiveType(PrimitiveType type)
std::optional< StencilAttachmentDescriptor > GetFrontStencilAttachmentDescriptor() const
An implementation of the [RenderTargetAllocator] that caches all allocated texture data for one frame...
std::shared_ptr< Texture > GetRenderTargetTexture() const
static constexpr AttachmentConfig kDefaultColorAttachmentConfig
Definition: render_target.h:55
static constexpr AttachmentConfigMSAA kDefaultColorAttachmentConfigMSAA
Definition: render_target.h:61
static constexpr AttachmentConfig kDefaultStencilAttachmentConfig
Definition: render_target.h:68
A utility that generates triangles of the specified fill type given a polyline. This happens on the C...
Definition: tessellator.h:34
A cache for blurred text that re-uses these across frames.
int32_t x
ScopedObject< Object > Create(CtorArgs &&... args)
Definition: object.h:161
float Scalar
Definition: scalar.h:18
static std::unique_ptr< PipelineT > CreateDefaultPipeline(const Context &context)
raw_ptr< Pipeline< PipelineDescriptor > > PipelineRef
A raw ptr to a pipeline object.
Definition: pipeline.h:88
const char * BlendModeToString(BlendMode blend_mode)
Definition: color.cc:47
@ kEqual
Comparison test passes if new_value == current_value.
@ kAlways
Comparison test passes always passes.
@ kLess
Comparison test passes if new_value < current_value.
@ kNotEqual
Comparison test passes if new_value != current_value.
fml::Status AddMipmapGeneration(const std::shared_ptr< CommandBuffer > &command_buffer, const std::shared_ptr< Context > &context, const std::shared_ptr< Texture > &texture)
Adds a blit command to the render pass.
Definition: texture_util.cc:37
@ kDecrementWrap
Decrement the current stencil value by 1. If at zero, set to maximum.
@ kSetToReferenceValue
Reset the stencil value to the reference value.
@ kIncrementClamp
Increment the current stencil value by 1. Clamp it to the maximum.
@ kIncrementWrap
Increment the current stencil value by 1. If at maximum, set to zero.
@ kKeep
Don't modify the current stencil value.
BlendMode
Definition: color.h:58
std::array< std::vector< Scalar >, 15 > GetPorterDuffSpecConstants(bool supports_decal)
Definition: comparable.h:95
Describe the color attachment that will be used with this pipeline.
Definition: formats.h:518
constexpr std::array< uint8_t, 4 > ToR8G8B8A8() const
Convert to R8G8B8A8 representation.
Definition: color.h:246
static constexpr Color BlackTransparent()
Definition: color.h:270
Variants< SolidFillPipeline > solid_fill
Variants< PorterDuffBlendPipeline > destination_blend
Variants< SweepGradientSSBOFillPipeline > sweep_gradient_ssbo_fill
Variants< BlendScreenPipeline > blend_screen
Variants< PorterDuffBlendPipeline > modulate_blend
Variants< FramebufferBlendOverlayPipeline > framebuffer_blend_overlay
Variants< BlendSaturationPipeline > blend_saturation
Variants< TiledTexturePipeline > tiled_texture
Variants< PorterDuffBlendPipeline > destination_in_blend
Variants< BlendSoftLightPipeline > blend_softlight
Variants< BlendColorDodgePipeline > blend_colordodge
Variants< BlendMultiplyPipeline > blend_multiply
Variants< BlendColorPipeline > blend_color
Variants< BlendDifferencePipeline > blend_difference
Variants< BlendOverlayPipeline > blend_overlay
Variants< ConicalGradientFillStripPipeline > conical_gradient_fill_strip
Variants< FramebufferBlendExclusionPipeline > framebuffer_blend_exclusion
Variants< MorphologyFilterPipeline > morphology_filter
Variants< PorterDuffBlendPipeline > screen_blend
Variants< FramebufferBlendSaturationPipeline > framebuffer_blend_saturation
Variants< PorterDuffBlendPipeline > source_over_blend
Variants< LinearGradientFillPipeline > linear_gradient_fill
Variants< PorterDuffBlendPipeline > plus_blend
Variants< VerticesUber2Shader > vertices_uber_2_
Variants< FramebufferBlendHardLightPipeline > framebuffer_blend_hardlight
Variants< RadialGradientSSBOFillPipeline > radial_gradient_ssbo_fill
Variants< PorterDuffBlendPipeline > clear_blend
Variants< ConicalGradientUniformFillConicalPipeline > conical_gradient_uniform_fill
Variants< FramebufferBlendMultiplyPipeline > framebuffer_blend_multiply
Variants< ConicalGradientSSBOFillPipeline > conical_gradient_ssbo_fill
Variants< TextureDownsamplePipeline > texture_downsample
Variants< FramebufferBlendLuminosityPipeline > framebuffer_blend_luminosity
Variants< FramebufferBlendSoftLightPipeline > framebuffer_blend_softlight
Variants< SweepGradientUniformFillPipeline > sweep_gradient_uniform_fill
Variants< BlendColorBurnPipeline > blend_colorburn
Variants< ConicalGradientUniformFillStripRadialPipeline > conical_gradient_uniform_fill_strip_and_radial
Variants< PorterDuffBlendPipeline > source_in_blend
Variants< ConicalGradientFillConicalPipeline > conical_gradient_fill
Variants< SweepGradientFillPipeline > sweep_gradient_fill
Variants< FramebufferBlendLightenPipeline > framebuffer_blend_lighten
Variants< PorterDuffBlendPipeline > source_a_top_blend
Variants< PorterDuffBlendPipeline > destination_a_top_blend
Variants< RadialGradientUniformFillPipeline > radial_gradient_uniform_fill
Variants< BlendLightenPipeline > blend_lighten
Variants< LinearGradientUniformFillPipeline > linear_gradient_uniform_fill
Variants< FramebufferBlendColorBurnPipeline > framebuffer_blend_colorburn
Variants< ConicalGradientFillRadialPipeline > conical_gradient_fill_radial
Variants< PorterDuffBlendPipeline > destination_over_blend
Variants< BlendExclusionPipeline > blend_exclusion
Variants< SrgbToLinearFilterPipeline > srgb_to_linear_filter
Variants< ColorMatrixColorFilterPipeline > color_matrix_color_filter
Variants< LinearToSrgbFilterPipeline > linear_to_srgb_filter
Variants< ConicalGradientUniformFillRadialPipeline > conical_gradient_uniform_fill_radial
Variants< ConicalGradientSSBOFillPipeline > conical_gradient_ssbo_fill_strip
Variants< RRectBlurPipeline > rrect_blur
Variants< BlendDarkenPipeline > blend_darken
Variants< TexturePipeline > texture
Variants< PorterDuffBlendPipeline > source_out_blend
Variants< FramebufferBlendHuePipeline > framebuffer_blend_hue
Variants< TextureStrictSrcPipeline > texture_strict_src
Variants< FramebufferBlendColorPipeline > framebuffer_blend_color
Variants< BlendHuePipeline > blend_hue
Variants< FramebufferBlendDarkenPipeline > framebuffer_blend_darken
Variants< FastGradientPipeline > fast_gradient
Variants< ConicalGradientUniformFillStripPipeline > conical_gradient_uniform_fill_strip
Variants< PorterDuffBlendPipeline > xor_blend
Variants< GaussianBlurPipeline > gaussian_blur
Variants< LinearGradientSSBOFillPipeline > linear_gradient_ssbo_fill
Variants< ConicalGradientSSBOFillPipeline > conical_gradient_ssbo_fill_strip_and_radial
Variants< GlyphAtlasPipeline > glyph_atlas
Variants< PorterDuffBlendPipeline > source_blend
Variants< BlendLuminosityPipeline > blend_luminosity
Variants< BorderMaskBlurPipeline > border_mask_blur
Variants< FramebufferBlendScreenPipeline > framebuffer_blend_screen
Variants< FramebufferBlendDifferencePipeline > framebuffer_blend_difference
Variants< YUVToRGBFilterPipeline > yuv_to_rgb_filter
Variants< RadialGradientFillPipeline > radial_gradient_fill
Variants< ConicalGradientSSBOFillPipeline > conical_gradient_ssbo_fill_radial
Variants< ConicalGradientFillStripRadialPipeline > conical_gradient_fill_strip_and_radial
Variants< BlendHardLightPipeline > blend_hardlight
Variants< FramebufferBlendColorDodgePipeline > framebuffer_blend_colordodge
Variants< PorterDuffBlendPipeline > destination_out_blend
Variants< VerticesUber1Shader > vertices_uber_1_
void ApplyToPipelineDescriptor(PipelineDescriptor &desc) const
static std::optional< PipelineDescriptor > MakeDefaultPipelineDescriptor(const Context &context, const std::vector< Scalar > &constants={})
Create a default pipeline descriptor using the combination reflected shader information....
StencilOperation depth_stencil_pass
Definition: formats.h:629
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:67
#define VALIDATION_LOG
Definition: validation.h:91