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
5#pragma once
6
7#include <memory>
8#include <optional>
9#include <unordered_map>
10
11#include "flutter/fml/hash_combine.h"
12#include "flutter/fml/logging.h"
13#include "flutter/fml/macros.h"
14#include "impeller/base/validation.h"
15#include "impeller/core/formats.h"
16#include "impeller/entity/entity.h"
17#include "impeller/renderer/capabilities.h"
18#include "impeller/renderer/pipeline.h"
19#include "impeller/scene/scene_context.h"
20
21#ifdef IMPELLER_DEBUG
22#include "impeller/entity/checkerboard.frag.h"
23#include "impeller/entity/checkerboard.vert.h"
24#endif // IMPELLER_DEBUG
25
26#include "impeller/entity/blend.frag.h"
27#include "impeller/entity/blend.vert.h"
28#include "impeller/entity/border_mask_blur.frag.h"
29#include "impeller/entity/border_mask_blur.vert.h"
30#include "impeller/entity/clip.frag.h"
31#include "impeller/entity/clip.vert.h"
32#include "impeller/entity/color_matrix_color_filter.frag.h"
33#include "impeller/entity/color_matrix_color_filter.vert.h"
34#include "impeller/entity/conical_gradient_fill.frag.h"
35#include "impeller/entity/glyph_atlas.frag.h"
36#include "impeller/entity/glyph_atlas.vert.h"
37#include "impeller/entity/glyph_atlas_color.frag.h"
38#include "impeller/entity/gradient_fill.vert.h"
39#include "impeller/entity/linear_gradient_fill.frag.h"
40#include "impeller/entity/linear_to_srgb_filter.frag.h"
41#include "impeller/entity/linear_to_srgb_filter.vert.h"
42#include "impeller/entity/morphology_filter.frag.h"
43#include "impeller/entity/morphology_filter.vert.h"
44#include "impeller/entity/points.comp.h"
45#include "impeller/entity/porter_duff_blend.frag.h"
46#include "impeller/entity/radial_gradient_fill.frag.h"
47#include "impeller/entity/rrect_blur.frag.h"
48#include "impeller/entity/rrect_blur.vert.h"
49#include "impeller/entity/solid_fill.frag.h"
50#include "impeller/entity/solid_fill.vert.h"
51#include "impeller/entity/srgb_to_linear_filter.frag.h"
52#include "impeller/entity/srgb_to_linear_filter.vert.h"
53#include "impeller/entity/sweep_gradient_fill.frag.h"
54#include "impeller/entity/texture_fill.frag.h"
55#include "impeller/entity/texture_fill.vert.h"
56#include "impeller/entity/tiled_texture_fill.frag.h"
57#include "impeller/entity/uv.comp.h"
58#include "impeller/entity/vertices.frag.h"
59#include "impeller/entity/yuv_to_rgb_filter.frag.h"
60#include "impeller/entity/yuv_to_rgb_filter.vert.h"
61
62#include "impeller/entity/gaussian_blur.vert.h"
63#include "impeller/entity/gaussian_blur_alpha_decal.frag.h"
64#include "impeller/entity/gaussian_blur_alpha_nodecal.frag.h"
65#include "impeller/entity/gaussian_blur_noalpha_decal.frag.h"
66#include "impeller/entity/gaussian_blur_noalpha_nodecal.frag.h"
67
68#include "impeller/entity/position_color.vert.h"
69
70#include "impeller/typographer/glyph_atlas.h"
71
72#include "impeller/entity/conical_gradient_ssbo_fill.frag.h"
73#include "impeller/entity/linear_gradient_ssbo_fill.frag.h"
74#include "impeller/entity/radial_gradient_ssbo_fill.frag.h"
75#include "impeller/entity/sweep_gradient_ssbo_fill.frag.h"
76
77#include "impeller/entity/advanced_blend.vert.h"
78#include "impeller/entity/advanced_blend_color.frag.h"
79#include "impeller/entity/advanced_blend_colorburn.frag.h"
80#include "impeller/entity/advanced_blend_colordodge.frag.h"
81#include "impeller/entity/advanced_blend_darken.frag.h"
82#include "impeller/entity/advanced_blend_difference.frag.h"
83#include "impeller/entity/advanced_blend_exclusion.frag.h"
84#include "impeller/entity/advanced_blend_hardlight.frag.h"
85#include "impeller/entity/advanced_blend_hue.frag.h"
86#include "impeller/entity/advanced_blend_lighten.frag.h"
87#include "impeller/entity/advanced_blend_luminosity.frag.h"
88#include "impeller/entity/advanced_blend_multiply.frag.h"
89#include "impeller/entity/advanced_blend_overlay.frag.h"
90#include "impeller/entity/advanced_blend_saturation.frag.h"
91#include "impeller/entity/advanced_blend_screen.frag.h"
92#include "impeller/entity/advanced_blend_softlight.frag.h"
93
94#include "impeller/entity/framebuffer_blend.vert.h"
95#include "impeller/entity/framebuffer_blend_color.frag.h"
96#include "impeller/entity/framebuffer_blend_colorburn.frag.h"
97#include "impeller/entity/framebuffer_blend_colordodge.frag.h"
98#include "impeller/entity/framebuffer_blend_darken.frag.h"
99#include "impeller/entity/framebuffer_blend_difference.frag.h"
100#include "impeller/entity/framebuffer_blend_exclusion.frag.h"
101#include "impeller/entity/framebuffer_blend_hardlight.frag.h"
102#include "impeller/entity/framebuffer_blend_hue.frag.h"
103#include "impeller/entity/framebuffer_blend_lighten.frag.h"
104#include "impeller/entity/framebuffer_blend_luminosity.frag.h"
105#include "impeller/entity/framebuffer_blend_multiply.frag.h"
106#include "impeller/entity/framebuffer_blend_overlay.frag.h"
107#include "impeller/entity/framebuffer_blend_saturation.frag.h"
108#include "impeller/entity/framebuffer_blend_screen.frag.h"
109#include "impeller/entity/framebuffer_blend_softlight.frag.h"
110
111namespace impeller {
112
113#ifdef IMPELLER_DEBUG
114using CheckerboardPipeline =
115 RenderPipelineT<CheckerboardVertexShader, CheckerboardFragmentShader>;
116#endif // IMPELLER_DEBUG
117
118using LinearGradientFillPipeline =
119 RenderPipelineT<GradientFillVertexShader, LinearGradientFillFragmentShader>;
120using SolidFillPipeline =
121 RenderPipelineT<SolidFillVertexShader, SolidFillFragmentShader>;
122using RadialGradientFillPipeline =
123 RenderPipelineT<GradientFillVertexShader, RadialGradientFillFragmentShader>;
124using ConicalGradientFillPipeline =
125 RenderPipelineT<GradientFillVertexShader,
126 ConicalGradientFillFragmentShader>;
127using SweepGradientFillPipeline =
128 RenderPipelineT<GradientFillVertexShader, SweepGradientFillFragmentShader>;
129using LinearGradientSSBOFillPipeline =
130 RenderPipelineT<GradientFillVertexShader,
131 LinearGradientSsboFillFragmentShader>;
132using ConicalGradientSSBOFillPipeline =
133 RenderPipelineT<GradientFillVertexShader,
134 ConicalGradientSsboFillFragmentShader>;
135using RadialGradientSSBOFillPipeline =
136 RenderPipelineT<GradientFillVertexShader,
137 RadialGradientSsboFillFragmentShader>;
138using SweepGradientSSBOFillPipeline =
139 RenderPipelineT<GradientFillVertexShader,
140 SweepGradientSsboFillFragmentShader>;
141using RRectBlurPipeline =
142 RenderPipelineT<RrectBlurVertexShader, RrectBlurFragmentShader>;
143using BlendPipeline = RenderPipelineT<BlendVertexShader, BlendFragmentShader>;
144using TexturePipeline =
145 RenderPipelineT<TextureFillVertexShader, TextureFillFragmentShader>;
146using PositionUVPipeline =
147 RenderPipelineT<TextureFillVertexShader, TiledTextureFillFragmentShader>;
148using TiledTexturePipeline =
149 RenderPipelineT<TextureFillVertexShader, TiledTextureFillFragmentShader>;
150using GaussianBlurAlphaDecalPipeline =
151 RenderPipelineT<GaussianBlurVertexShader,
152 GaussianBlurAlphaDecalFragmentShader>;
153using GaussianBlurAlphaPipeline =
154 RenderPipelineT<GaussianBlurVertexShader,
155 GaussianBlurAlphaNodecalFragmentShader>;
156using GaussianBlurDecalPipeline =
157 RenderPipelineT<GaussianBlurVertexShader,
158 GaussianBlurNoalphaDecalFragmentShader>;
159using GaussianBlurPipeline =
160 RenderPipelineT<GaussianBlurVertexShader,
161 GaussianBlurNoalphaNodecalFragmentShader>;
162using BorderMaskBlurPipeline =
163 RenderPipelineT<BorderMaskBlurVertexShader, BorderMaskBlurFragmentShader>;
164using MorphologyFilterPipeline =
165 RenderPipelineT<MorphologyFilterVertexShader,
166 MorphologyFilterFragmentShader>;
167using ColorMatrixColorFilterPipeline =
168 RenderPipelineT<ColorMatrixColorFilterVertexShader,
169 ColorMatrixColorFilterFragmentShader>;
170using LinearToSrgbFilterPipeline =
171 RenderPipelineT<LinearToSrgbFilterVertexShader,
172 LinearToSrgbFilterFragmentShader>;
173using SrgbToLinearFilterPipeline =
174 RenderPipelineT<SrgbToLinearFilterVertexShader,
175 SrgbToLinearFilterFragmentShader>;
176using GlyphAtlasPipeline =
177 RenderPipelineT<GlyphAtlasVertexShader, GlyphAtlasFragmentShader>;
178using GlyphAtlasColorPipeline =
179 RenderPipelineT<GlyphAtlasVertexShader, GlyphAtlasColorFragmentShader>;
180using PorterDuffBlendPipeline =
181 RenderPipelineT<BlendVertexShader, PorterDuffBlendFragmentShader>;
182// Instead of requiring new shaders for clips, the solid fill stages are used
183// to redirect writing to the stencil instead of color attachments.
184using ClipPipeline = RenderPipelineT<ClipVertexShader, ClipFragmentShader>;
185
186using GeometryColorPipeline =
187 RenderPipelineT<PositionColorVertexShader, VerticesFragmentShader>;
188using YUVToRGBFilterPipeline =
189 RenderPipelineT<YuvToRgbFilterVertexShader, YuvToRgbFilterFragmentShader>;
190
191// Advanced blends
192using BlendColorPipeline = RenderPipelineT<AdvancedBlendVertexShader,
193 AdvancedBlendColorFragmentShader>;
194using BlendColorBurnPipeline =
195 RenderPipelineT<AdvancedBlendVertexShader,
196 AdvancedBlendColorburnFragmentShader>;
197using BlendColorDodgePipeline =
198 RenderPipelineT<AdvancedBlendVertexShader,
199 AdvancedBlendColordodgeFragmentShader>;
200using BlendDarkenPipeline = RenderPipelineT<AdvancedBlendVertexShader,
201 AdvancedBlendDarkenFragmentShader>;
202using BlendDifferencePipeline =
203 RenderPipelineT<AdvancedBlendVertexShader,
204 AdvancedBlendDifferenceFragmentShader>;
205using BlendExclusionPipeline =
206 RenderPipelineT<AdvancedBlendVertexShader,
207 AdvancedBlendExclusionFragmentShader>;
208using BlendHardLightPipeline =
209 RenderPipelineT<AdvancedBlendVertexShader,
210 AdvancedBlendHardlightFragmentShader>;
211using BlendHuePipeline =
212 RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendHueFragmentShader>;
213using BlendLightenPipeline =
214 RenderPipelineT<AdvancedBlendVertexShader,
215 AdvancedBlendLightenFragmentShader>;
216using BlendLuminosityPipeline =
217 RenderPipelineT<AdvancedBlendVertexShader,
218 AdvancedBlendLuminosityFragmentShader>;
219using BlendMultiplyPipeline =
220 RenderPipelineT<AdvancedBlendVertexShader,
221 AdvancedBlendMultiplyFragmentShader>;
222using BlendOverlayPipeline =
223 RenderPipelineT<AdvancedBlendVertexShader,
224 AdvancedBlendOverlayFragmentShader>;
225using BlendSaturationPipeline =
226 RenderPipelineT<AdvancedBlendVertexShader,
227 AdvancedBlendSaturationFragmentShader>;
228using BlendScreenPipeline = RenderPipelineT<AdvancedBlendVertexShader,
229 AdvancedBlendScreenFragmentShader>;
230using BlendSoftLightPipeline =
231 RenderPipelineT<AdvancedBlendVertexShader,
232 AdvancedBlendSoftlightFragmentShader>;
233// Framebuffer Advanced Blends
234using FramebufferBlendColorPipeline =
235 RenderPipelineT<FramebufferBlendVertexShader,
236 FramebufferBlendColorFragmentShader>;
237using FramebufferBlendColorBurnPipeline =
238 RenderPipelineT<FramebufferBlendVertexShader,
239 FramebufferBlendColorburnFragmentShader>;
240using FramebufferBlendColorDodgePipeline =
241 RenderPipelineT<FramebufferBlendVertexShader,
242 FramebufferBlendColordodgeFragmentShader>;
243using FramebufferBlendDarkenPipeline =
244 RenderPipelineT<FramebufferBlendVertexShader,
245 FramebufferBlendDarkenFragmentShader>;
246using FramebufferBlendDifferencePipeline =
247 RenderPipelineT<FramebufferBlendVertexShader,
248 FramebufferBlendDifferenceFragmentShader>;
249using FramebufferBlendExclusionPipeline =
250 RenderPipelineT<FramebufferBlendVertexShader,
251 FramebufferBlendExclusionFragmentShader>;
252using FramebufferBlendHardLightPipeline =
253 RenderPipelineT<FramebufferBlendVertexShader,
254 FramebufferBlendHardlightFragmentShader>;
255using FramebufferBlendHuePipeline =
256 RenderPipelineT<FramebufferBlendVertexShader,
257 FramebufferBlendHueFragmentShader>;
258using FramebufferBlendLightenPipeline =
259 RenderPipelineT<FramebufferBlendVertexShader,
260 FramebufferBlendLightenFragmentShader>;
261using FramebufferBlendLuminosityPipeline =
262 RenderPipelineT<FramebufferBlendVertexShader,
263 FramebufferBlendLuminosityFragmentShader>;
264using FramebufferBlendMultiplyPipeline =
265 RenderPipelineT<FramebufferBlendVertexShader,
266 FramebufferBlendMultiplyFragmentShader>;
267using FramebufferBlendOverlayPipeline =
268 RenderPipelineT<FramebufferBlendVertexShader,
269 FramebufferBlendOverlayFragmentShader>;
270using FramebufferBlendSaturationPipeline =
271 RenderPipelineT<FramebufferBlendVertexShader,
272 FramebufferBlendSaturationFragmentShader>;
273using FramebufferBlendScreenPipeline =
274 RenderPipelineT<FramebufferBlendVertexShader,
275 FramebufferBlendScreenFragmentShader>;
276using FramebufferBlendSoftLightPipeline =
277 RenderPipelineT<FramebufferBlendVertexShader,
278 FramebufferBlendSoftlightFragmentShader>;
279
280/// Geometry Pipelines
281using PointsComputeShaderPipeline = ComputePipelineBuilder<PointsComputeShader>;
282using UvComputeShaderPipeline = ComputePipelineBuilder<UvComputeShader>;
283
284/// Pipeline state configuration.
285///
286/// Each unique combination of these options requires a different pipeline state
287/// object to be built. This struct is used as a key for the per-pipeline
288/// variant cache.
289///
290/// When adding fields to this key, reliant features should take care to limit
291/// the combinatorical explosion of variations. A sufficiently complicated
292/// Flutter application may easily require building hundreds of PSOs in total,
293/// but they shouldn't require e.g. 10s of thousands.
294struct ContentContextOptions {
295 SampleCount sample_count = SampleCount::kCount1;
296 BlendMode blend_mode = BlendMode::kSourceOver;
297 CompareFunction stencil_compare = CompareFunction::kEqual;
298 StencilOperation stencil_operation = StencilOperation::kKeep;
299 PrimitiveType primitive_type = PrimitiveType::kTriangle;
300 PixelFormat color_attachment_pixel_format = PixelFormat::kUnknown;
301 bool has_stencil_attachment = true;
302 bool wireframe = false;
303
304 struct Hash {
305 constexpr std::size_t operator()(const ContentContextOptions& o) const {
306 return fml::HashCombine(args: o.sample_count, args: o.blend_mode, args: o.stencil_compare,
307 args: o.stencil_operation, args: o.primitive_type,
308 args: o.color_attachment_pixel_format,
309 args: o.has_stencil_attachment, args: o.wireframe);
310 }
311 };
312
313 struct Equal {
314 constexpr bool operator()(const ContentContextOptions& lhs,
315 const ContentContextOptions& rhs) const {
316 return lhs.sample_count == rhs.sample_count &&
317 lhs.blend_mode == rhs.blend_mode &&
318 lhs.stencil_compare == rhs.stencil_compare &&
319 lhs.stencil_operation == rhs.stencil_operation &&
320 lhs.primitive_type == rhs.primitive_type &&
321 lhs.color_attachment_pixel_format ==
322 rhs.color_attachment_pixel_format &&
323 lhs.has_stencil_attachment == rhs.has_stencil_attachment &&
324 lhs.wireframe == rhs.wireframe;
325 }
326 };
327
328 void ApplyToPipelineDescriptor(PipelineDescriptor& desc) const;
329};
330
331class Tessellator;
332
333class ContentContext {
334 public:
335 explicit ContentContext(std::shared_ptr<Context> context);
336
337 ~ContentContext();
338
339 bool IsValid() const;
340
341 std::shared_ptr<scene::SceneContext> GetSceneContext() const;
342
343 std::shared_ptr<Tessellator> GetTessellator() const;
344
345#ifdef IMPELLER_DEBUG
346 std::shared_ptr<Pipeline<PipelineDescriptor>> GetCheckerboardPipeline(
347 ContentContextOptions opts) const {
348 return GetPipeline(checkerboard_pipelines_, opts);
349 }
350#endif // IMPELLER_DEBUG
351
352 std::shared_ptr<Pipeline<PipelineDescriptor>> GetLinearGradientFillPipeline(
353 ContentContextOptions opts) const {
354 return GetPipeline(linear_gradient_fill_pipelines_, opts);
355 }
356
357 std::shared_ptr<Pipeline<PipelineDescriptor>>
358 GetLinearGradientSSBOFillPipeline(ContentContextOptions opts) const {
359 FML_DCHECK(GetDeviceCapabilities().SupportsSSBO());
360 return GetPipeline(linear_gradient_ssbo_fill_pipelines_, opts);
361 }
362
363 std::shared_ptr<Pipeline<PipelineDescriptor>>
364 GetRadialGradientSSBOFillPipeline(ContentContextOptions opts) const {
365 FML_DCHECK(GetDeviceCapabilities().SupportsSSBO());
366 return GetPipeline(radial_gradient_ssbo_fill_pipelines_, opts);
367 }
368
369 std::shared_ptr<Pipeline<PipelineDescriptor>>
370 GetConicalGradientSSBOFillPipeline(ContentContextOptions opts) const {
371 FML_DCHECK(GetDeviceCapabilities().SupportsSSBO());
372 return GetPipeline(conical_gradient_ssbo_fill_pipelines_, opts);
373 }
374
375 std::shared_ptr<Pipeline<PipelineDescriptor>>
376 GetSweepGradientSSBOFillPipeline(ContentContextOptions opts) const {
377 FML_DCHECK(GetDeviceCapabilities().SupportsSSBO());
378 return GetPipeline(sweep_gradient_ssbo_fill_pipelines_, opts);
379 }
380
381 std::shared_ptr<Pipeline<PipelineDescriptor>> GetRadialGradientFillPipeline(
382 ContentContextOptions opts) const {
383 return GetPipeline(radial_gradient_fill_pipelines_, opts);
384 }
385
386 std::shared_ptr<Pipeline<PipelineDescriptor>> GetConicalGradientFillPipeline(
387 ContentContextOptions opts) const {
388 return GetPipeline(conical_gradient_fill_pipelines_, opts);
389 }
390
391 std::shared_ptr<Pipeline<PipelineDescriptor>> GetRRectBlurPipeline(
392 ContentContextOptions opts) const {
393 return GetPipeline(rrect_blur_pipelines_, opts);
394 }
395
396 std::shared_ptr<Pipeline<PipelineDescriptor>> GetSweepGradientFillPipeline(
397 ContentContextOptions opts) const {
398 return GetPipeline(sweep_gradient_fill_pipelines_, opts);
399 }
400
401 std::shared_ptr<Pipeline<PipelineDescriptor>> GetSolidFillPipeline(
402 ContentContextOptions opts) const {
403 return GetPipeline(solid_fill_pipelines_, opts);
404 }
405
406 std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendPipeline(
407 ContentContextOptions opts) const {
408 return GetPipeline(texture_blend_pipelines_, opts);
409 }
410
411 std::shared_ptr<Pipeline<PipelineDescriptor>> GetTexturePipeline(
412 ContentContextOptions opts) const {
413 return GetPipeline(texture_pipelines_, opts);
414 }
415
416 std::shared_ptr<Pipeline<PipelineDescriptor>> GetPositionUVPipeline(
417 ContentContextOptions opts) const {
418 return GetPipeline(position_uv_pipelines_, opts);
419 }
420
421 std::shared_ptr<Pipeline<PipelineDescriptor>> GetTiledTexturePipeline(
422 ContentContextOptions opts) const {
423 return GetPipeline(tiled_texture_pipelines_, opts);
424 }
425
426 std::shared_ptr<Pipeline<PipelineDescriptor>>
427 GetGaussianBlurAlphaDecalPipeline(ContentContextOptions opts) const {
428 return GetPipeline(gaussian_blur_alpha_decal_pipelines_, opts);
429 }
430
431 std::shared_ptr<Pipeline<PipelineDescriptor>> GetGaussianBlurAlphaPipeline(
432 ContentContextOptions opts) const {
433 return GetPipeline(gaussian_blur_alpha_nodecal_pipelines_, opts);
434 }
435
436 std::shared_ptr<Pipeline<PipelineDescriptor>> GetGaussianBlurDecalPipeline(
437 ContentContextOptions opts) const {
438 return GetPipeline(gaussian_blur_noalpha_decal_pipelines_, opts);
439 }
440
441 std::shared_ptr<Pipeline<PipelineDescriptor>> GetGaussianBlurPipeline(
442 ContentContextOptions opts) const {
443 return GetPipeline(gaussian_blur_noalpha_nodecal_pipelines_, opts);
444 }
445
446 std::shared_ptr<Pipeline<PipelineDescriptor>> GetBorderMaskBlurPipeline(
447 ContentContextOptions opts) const {
448 return GetPipeline(border_mask_blur_pipelines_, opts);
449 }
450
451 std::shared_ptr<Pipeline<PipelineDescriptor>> GetMorphologyFilterPipeline(
452 ContentContextOptions opts) const {
453 return GetPipeline(morphology_filter_pipelines_, opts);
454 }
455
456 std::shared_ptr<Pipeline<PipelineDescriptor>>
457 GetColorMatrixColorFilterPipeline(ContentContextOptions opts) const {
458 return GetPipeline(color_matrix_color_filter_pipelines_, opts);
459 }
460
461 std::shared_ptr<Pipeline<PipelineDescriptor>> GetLinearToSrgbFilterPipeline(
462 ContentContextOptions opts) const {
463 return GetPipeline(linear_to_srgb_filter_pipelines_, opts);
464 }
465
466 std::shared_ptr<Pipeline<PipelineDescriptor>> GetSrgbToLinearFilterPipeline(
467 ContentContextOptions opts) const {
468 return GetPipeline(srgb_to_linear_filter_pipelines_, opts);
469 }
470
471 std::shared_ptr<Pipeline<PipelineDescriptor>> GetClipPipeline(
472 ContentContextOptions opts) const {
473 return GetPipeline(clip_pipelines_, opts);
474 }
475
476 std::shared_ptr<Pipeline<PipelineDescriptor>> GetGlyphAtlasPipeline(
477 ContentContextOptions opts) const {
478 return GetPipeline(glyph_atlas_pipelines_, opts);
479 }
480
481 std::shared_ptr<Pipeline<PipelineDescriptor>> GetGlyphAtlasColorPipeline(
482 ContentContextOptions opts) const {
483 return GetPipeline(glyph_atlas_color_pipelines_, opts);
484 }
485
486 std::shared_ptr<Pipeline<PipelineDescriptor>> GetGeometryColorPipeline(
487 ContentContextOptions opts) const {
488 return GetPipeline(geometry_color_pipelines_, opts);
489 }
490
491 std::shared_ptr<Pipeline<PipelineDescriptor>> GetYUVToRGBFilterPipeline(
492 ContentContextOptions opts) const {
493 return GetPipeline(yuv_to_rgb_filter_pipelines_, opts);
494 }
495
496 std::shared_ptr<Pipeline<PipelineDescriptor>> GetPorterDuffBlendPipeline(
497 ContentContextOptions opts) const {
498 return GetPipeline(porter_duff_blend_pipelines_, opts);
499 }
500
501 // Advanced blends.
502
503 std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendColorPipeline(
504 ContentContextOptions opts) const {
505 return GetPipeline(blend_color_pipelines_, opts);
506 }
507
508 std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendColorBurnPipeline(
509 ContentContextOptions opts) const {
510 return GetPipeline(blend_colorburn_pipelines_, opts);
511 }
512
513 std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendColorDodgePipeline(
514 ContentContextOptions opts) const {
515 return GetPipeline(blend_colordodge_pipelines_, opts);
516 }
517
518 std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendDarkenPipeline(
519 ContentContextOptions opts) const {
520 return GetPipeline(blend_darken_pipelines_, opts);
521 }
522
523 std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendDifferencePipeline(
524 ContentContextOptions opts) const {
525 return GetPipeline(blend_difference_pipelines_, opts);
526 }
527
528 std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendExclusionPipeline(
529 ContentContextOptions opts) const {
530 return GetPipeline(blend_exclusion_pipelines_, opts);
531 }
532
533 std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendHardLightPipeline(
534 ContentContextOptions opts) const {
535 return GetPipeline(blend_hardlight_pipelines_, opts);
536 }
537
538 std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendHuePipeline(
539 ContentContextOptions opts) const {
540 return GetPipeline(blend_hue_pipelines_, opts);
541 }
542
543 std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendLightenPipeline(
544 ContentContextOptions opts) const {
545 return GetPipeline(blend_lighten_pipelines_, opts);
546 }
547
548 std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendLuminosityPipeline(
549 ContentContextOptions opts) const {
550 return GetPipeline(blend_luminosity_pipelines_, opts);
551 }
552
553 std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendMultiplyPipeline(
554 ContentContextOptions opts) const {
555 return GetPipeline(blend_multiply_pipelines_, opts);
556 }
557
558 std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendOverlayPipeline(
559 ContentContextOptions opts) const {
560 return GetPipeline(blend_overlay_pipelines_, opts);
561 }
562
563 std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendSaturationPipeline(
564 ContentContextOptions opts) const {
565 return GetPipeline(blend_saturation_pipelines_, opts);
566 }
567
568 std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendScreenPipeline(
569 ContentContextOptions opts) const {
570 return GetPipeline(blend_screen_pipelines_, opts);
571 }
572
573 std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendSoftLightPipeline(
574 ContentContextOptions opts) const {
575 return GetPipeline(blend_softlight_pipelines_, opts);
576 }
577
578 // Framebuffer Advanced Blends
579 std::shared_ptr<Pipeline<PipelineDescriptor>>
580 GetFramebufferBlendColorPipeline(ContentContextOptions opts) const {
581 FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
582 return GetPipeline(framebuffer_blend_color_pipelines_, opts);
583 }
584
585 std::shared_ptr<Pipeline<PipelineDescriptor>>
586 GetFramebufferBlendColorBurnPipeline(ContentContextOptions opts) const {
587 FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
588 return GetPipeline(framebuffer_blend_colorburn_pipelines_, opts);
589 }
590
591 std::shared_ptr<Pipeline<PipelineDescriptor>>
592 GetFramebufferBlendColorDodgePipeline(ContentContextOptions opts) const {
593 FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
594 return GetPipeline(framebuffer_blend_colordodge_pipelines_, opts);
595 }
596
597 std::shared_ptr<Pipeline<PipelineDescriptor>>
598 GetFramebufferBlendDarkenPipeline(ContentContextOptions opts) const {
599 FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
600 return GetPipeline(framebuffer_blend_darken_pipelines_, opts);
601 }
602
603 std::shared_ptr<Pipeline<PipelineDescriptor>>
604 GetFramebufferBlendDifferencePipeline(ContentContextOptions opts) const {
605 FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
606 return GetPipeline(framebuffer_blend_difference_pipelines_, opts);
607 }
608
609 std::shared_ptr<Pipeline<PipelineDescriptor>>
610 GetFramebufferBlendExclusionPipeline(ContentContextOptions opts) const {
611 FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
612 return GetPipeline(framebuffer_blend_exclusion_pipelines_, opts);
613 }
614
615 std::shared_ptr<Pipeline<PipelineDescriptor>>
616 GetFramebufferBlendHardLightPipeline(ContentContextOptions opts) const {
617 FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
618 return GetPipeline(framebuffer_blend_hardlight_pipelines_, opts);
619 }
620
621 std::shared_ptr<Pipeline<PipelineDescriptor>> GetFramebufferBlendHuePipeline(
622 ContentContextOptions opts) const {
623 FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
624 return GetPipeline(framebuffer_blend_hue_pipelines_, opts);
625 }
626
627 std::shared_ptr<Pipeline<PipelineDescriptor>>
628 GetFramebufferBlendLightenPipeline(ContentContextOptions opts) const {
629 FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
630 return GetPipeline(framebuffer_blend_lighten_pipelines_, opts);
631 }
632
633 std::shared_ptr<Pipeline<PipelineDescriptor>>
634 GetFramebufferBlendLuminosityPipeline(ContentContextOptions opts) const {
635 FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
636 return GetPipeline(framebuffer_blend_luminosity_pipelines_, opts);
637 }
638
639 std::shared_ptr<Pipeline<PipelineDescriptor>>
640 GetFramebufferBlendMultiplyPipeline(ContentContextOptions opts) const {
641 FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
642 return GetPipeline(framebuffer_blend_multiply_pipelines_, opts);
643 }
644
645 std::shared_ptr<Pipeline<PipelineDescriptor>>
646 GetFramebufferBlendOverlayPipeline(ContentContextOptions opts) const {
647 FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
648 return GetPipeline(framebuffer_blend_overlay_pipelines_, opts);
649 }
650
651 std::shared_ptr<Pipeline<PipelineDescriptor>>
652 GetFramebufferBlendSaturationPipeline(ContentContextOptions opts) const {
653 FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
654 return GetPipeline(framebuffer_blend_saturation_pipelines_, opts);
655 }
656
657 std::shared_ptr<Pipeline<PipelineDescriptor>>
658 GetFramebufferBlendScreenPipeline(ContentContextOptions opts) const {
659 FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
660 return GetPipeline(framebuffer_blend_screen_pipelines_, opts);
661 }
662
663 std::shared_ptr<Pipeline<PipelineDescriptor>>
664 GetFramebufferBlendSoftLightPipeline(ContentContextOptions opts) const {
665 FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
666 return GetPipeline(framebuffer_blend_softlight_pipelines_, opts);
667 }
668
669 std::shared_ptr<Pipeline<ComputePipelineDescriptor>> GetPointComputePipeline()
670 const {
671 FML_DCHECK(GetDeviceCapabilities().SupportsCompute());
672 return point_field_compute_pipelines_;
673 }
674
675 std::shared_ptr<Pipeline<ComputePipelineDescriptor>> GetUvComputePipeline()
676 const {
677 FML_DCHECK(GetDeviceCapabilities().SupportsCompute());
678 return uv_compute_pipelines_;
679 }
680
681 std::shared_ptr<Context> GetContext() const;
682
683 const Capabilities& GetDeviceCapabilities() const;
684
685 void SetWireframe(bool wireframe);
686
687 using SubpassCallback =
688 std::function<bool(const ContentContext&, RenderPass&)>;
689
690 /// @brief Creates a new texture of size `texture_size` and calls
691 /// `subpass_callback` with a `RenderPass` for drawing to the texture.
692 std::shared_ptr<Texture> MakeSubpass(const std::string& label,
693 ISize texture_size,
694 const SubpassCallback& subpass_callback,
695 bool msaa_enabled = true) const;
696
697 std::shared_ptr<LazyGlyphAtlas> GetLazyGlyphAtlas() const {
698 return lazy_glyph_atlas_;
699 }
700
701 private:
702 std::shared_ptr<Context> context_;
703 std::shared_ptr<LazyGlyphAtlas> lazy_glyph_atlas_;
704
705 template <class T>
706 using Variants = std::unordered_map<ContentContextOptions,
707 std::unique_ptr<T>,
708 ContentContextOptions::Hash,
709 ContentContextOptions::Equal>;
710
711 // These are mutable because while the prototypes are created eagerly, any
712 // variants requested from that are lazily created and cached in the variants
713 // map.
714
715#ifdef IMPELLER_DEBUG
716 mutable Variants<CheckerboardPipeline> checkerboard_pipelines_;
717#endif // IMPELLER_DEBUG
718
719 mutable Variants<SolidFillPipeline> solid_fill_pipelines_;
720 mutable Variants<LinearGradientFillPipeline> linear_gradient_fill_pipelines_;
721 mutable Variants<RadialGradientFillPipeline> radial_gradient_fill_pipelines_;
722 mutable Variants<ConicalGradientFillPipeline>
723 conical_gradient_fill_pipelines_;
724 mutable Variants<SweepGradientFillPipeline> sweep_gradient_fill_pipelines_;
725 mutable Variants<LinearGradientSSBOFillPipeline>
726 linear_gradient_ssbo_fill_pipelines_;
727 mutable Variants<RadialGradientSSBOFillPipeline>
728 radial_gradient_ssbo_fill_pipelines_;
729 mutable Variants<ConicalGradientSSBOFillPipeline>
730 conical_gradient_ssbo_fill_pipelines_;
731 mutable Variants<SweepGradientSSBOFillPipeline>
732 sweep_gradient_ssbo_fill_pipelines_;
733 mutable Variants<RRectBlurPipeline> rrect_blur_pipelines_;
734 mutable Variants<BlendPipeline> texture_blend_pipelines_;
735 mutable Variants<TexturePipeline> texture_pipelines_;
736 mutable Variants<PositionUVPipeline> position_uv_pipelines_;
737 mutable Variants<TiledTexturePipeline> tiled_texture_pipelines_;
738 mutable Variants<GaussianBlurAlphaDecalPipeline>
739 gaussian_blur_alpha_decal_pipelines_;
740 mutable Variants<GaussianBlurAlphaPipeline>
741 gaussian_blur_alpha_nodecal_pipelines_;
742 mutable Variants<GaussianBlurDecalPipeline>
743 gaussian_blur_noalpha_decal_pipelines_;
744 mutable Variants<GaussianBlurPipeline>
745 gaussian_blur_noalpha_nodecal_pipelines_;
746 mutable Variants<BorderMaskBlurPipeline> border_mask_blur_pipelines_;
747 mutable Variants<MorphologyFilterPipeline> morphology_filter_pipelines_;
748 mutable Variants<ColorMatrixColorFilterPipeline>
749 color_matrix_color_filter_pipelines_;
750 mutable Variants<LinearToSrgbFilterPipeline> linear_to_srgb_filter_pipelines_;
751 mutable Variants<SrgbToLinearFilterPipeline> srgb_to_linear_filter_pipelines_;
752 mutable Variants<ClipPipeline> clip_pipelines_;
753 mutable Variants<GlyphAtlasPipeline> glyph_atlas_pipelines_;
754 mutable Variants<GlyphAtlasColorPipeline> glyph_atlas_color_pipelines_;
755 mutable Variants<GeometryColorPipeline> geometry_color_pipelines_;
756 mutable Variants<YUVToRGBFilterPipeline> yuv_to_rgb_filter_pipelines_;
757 mutable Variants<PorterDuffBlendPipeline> porter_duff_blend_pipelines_;
758 // Advanced blends.
759 mutable Variants<BlendColorPipeline> blend_color_pipelines_;
760 mutable Variants<BlendColorBurnPipeline> blend_colorburn_pipelines_;
761 mutable Variants<BlendColorDodgePipeline> blend_colordodge_pipelines_;
762 mutable Variants<BlendDarkenPipeline> blend_darken_pipelines_;
763 mutable Variants<BlendDifferencePipeline> blend_difference_pipelines_;
764 mutable Variants<BlendExclusionPipeline> blend_exclusion_pipelines_;
765 mutable Variants<BlendHardLightPipeline> blend_hardlight_pipelines_;
766 mutable Variants<BlendHuePipeline> blend_hue_pipelines_;
767 mutable Variants<BlendLightenPipeline> blend_lighten_pipelines_;
768 mutable Variants<BlendLuminosityPipeline> blend_luminosity_pipelines_;
769 mutable Variants<BlendMultiplyPipeline> blend_multiply_pipelines_;
770 mutable Variants<BlendOverlayPipeline> blend_overlay_pipelines_;
771 mutable Variants<BlendSaturationPipeline> blend_saturation_pipelines_;
772 mutable Variants<BlendScreenPipeline> blend_screen_pipelines_;
773 mutable Variants<BlendSoftLightPipeline> blend_softlight_pipelines_;
774 // Framebuffer Advanced blends.
775 mutable Variants<FramebufferBlendColorPipeline>
776 framebuffer_blend_color_pipelines_;
777 mutable Variants<FramebufferBlendColorBurnPipeline>
778 framebuffer_blend_colorburn_pipelines_;
779 mutable Variants<FramebufferBlendColorDodgePipeline>
780 framebuffer_blend_colordodge_pipelines_;
781 mutable Variants<FramebufferBlendDarkenPipeline>
782 framebuffer_blend_darken_pipelines_;
783 mutable Variants<FramebufferBlendDifferencePipeline>
784 framebuffer_blend_difference_pipelines_;
785 mutable Variants<FramebufferBlendExclusionPipeline>
786 framebuffer_blend_exclusion_pipelines_;
787 mutable Variants<FramebufferBlendHardLightPipeline>
788 framebuffer_blend_hardlight_pipelines_;
789 mutable Variants<FramebufferBlendHuePipeline>
790 framebuffer_blend_hue_pipelines_;
791 mutable Variants<FramebufferBlendLightenPipeline>
792 framebuffer_blend_lighten_pipelines_;
793 mutable Variants<FramebufferBlendLuminosityPipeline>
794 framebuffer_blend_luminosity_pipelines_;
795 mutable Variants<FramebufferBlendMultiplyPipeline>
796 framebuffer_blend_multiply_pipelines_;
797 mutable Variants<FramebufferBlendOverlayPipeline>
798 framebuffer_blend_overlay_pipelines_;
799 mutable Variants<FramebufferBlendSaturationPipeline>
800 framebuffer_blend_saturation_pipelines_;
801 mutable Variants<FramebufferBlendScreenPipeline>
802 framebuffer_blend_screen_pipelines_;
803 mutable Variants<FramebufferBlendSoftLightPipeline>
804 framebuffer_blend_softlight_pipelines_;
805 mutable std::shared_ptr<Pipeline<ComputePipelineDescriptor>>
806 point_field_compute_pipelines_;
807 mutable std::shared_ptr<Pipeline<ComputePipelineDescriptor>>
808 uv_compute_pipelines_;
809 // The values for the default context options must be cached on
810 // initial creation. In the presence of wide gamut and platform views,
811 // it is possible that secondary surfaces will have a different default
812 // pixel format, which would cause the prototype check in GetPipeline
813 // below to fail.
814 ContentContextOptions default_options_;
815
816 template <class TypedPipeline>
817 std::shared_ptr<Pipeline<PipelineDescriptor>> GetPipeline(
818 Variants<TypedPipeline>& container,
819 ContentContextOptions opts) const {
820 if (!IsValid()) {
821 return nullptr;
822 }
823
824 if (wireframe_) {
825 opts.wireframe = true;
826 }
827
828 if (auto found = container.find(opts); found != container.end()) {
829 return found->second->WaitAndGet();
830 }
831
832 auto prototype = container.find(default_options_);
833
834 // The prototype must always be initialized in the constructor.
835 FML_CHECK(prototype != container.end());
836
837 auto pipeline = prototype->second->WaitAndGet();
838 if (!pipeline) {
839 return nullptr;
840 }
841
842 auto variant_future = pipeline->CreateVariant(
843 [&opts, variants_count = container.size()](PipelineDescriptor& desc) {
844 opts.ApplyToPipelineDescriptor(desc);
845 desc.SetLabel(
846 SPrintF("%s V#%zu", desc.GetLabel().c_str(), variants_count));
847 });
848 auto variant = std::make_unique<TypedPipeline>(std::move(variant_future));
849 auto variant_pipeline = variant->WaitAndGet();
850 container[opts] = std::move(variant);
851 return variant_pipeline;
852 }
853
854 bool is_valid_ = false;
855 std::shared_ptr<Tessellator> tessellator_;
856 std::shared_ptr<scene::SceneContext> scene_context_;
857 bool wireframe_ = false;
858
859 FML_DISALLOW_COPY_AND_ASSIGN(ContentContext);
860};
861
862} // namespace impeller
863

source code of flutter_engine/flutter/impeller/entity/contents/content_context.h