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 | |
111 | namespace impeller { |
112 | |
113 | #ifdef IMPELLER_DEBUG |
114 | using CheckerboardPipeline = |
115 | RenderPipelineT<CheckerboardVertexShader, CheckerboardFragmentShader>; |
116 | #endif // IMPELLER_DEBUG |
117 | |
118 | using LinearGradientFillPipeline = |
119 | RenderPipelineT<GradientFillVertexShader, LinearGradientFillFragmentShader>; |
120 | using SolidFillPipeline = |
121 | RenderPipelineT<SolidFillVertexShader, SolidFillFragmentShader>; |
122 | using RadialGradientFillPipeline = |
123 | RenderPipelineT<GradientFillVertexShader, RadialGradientFillFragmentShader>; |
124 | using ConicalGradientFillPipeline = |
125 | RenderPipelineT<GradientFillVertexShader, |
126 | ConicalGradientFillFragmentShader>; |
127 | using SweepGradientFillPipeline = |
128 | RenderPipelineT<GradientFillVertexShader, SweepGradientFillFragmentShader>; |
129 | using LinearGradientSSBOFillPipeline = |
130 | RenderPipelineT<GradientFillVertexShader, |
131 | LinearGradientSsboFillFragmentShader>; |
132 | using ConicalGradientSSBOFillPipeline = |
133 | RenderPipelineT<GradientFillVertexShader, |
134 | ConicalGradientSsboFillFragmentShader>; |
135 | using RadialGradientSSBOFillPipeline = |
136 | RenderPipelineT<GradientFillVertexShader, |
137 | RadialGradientSsboFillFragmentShader>; |
138 | using SweepGradientSSBOFillPipeline = |
139 | RenderPipelineT<GradientFillVertexShader, |
140 | SweepGradientSsboFillFragmentShader>; |
141 | using RRectBlurPipeline = |
142 | RenderPipelineT<RrectBlurVertexShader, RrectBlurFragmentShader>; |
143 | using BlendPipeline = RenderPipelineT<BlendVertexShader, BlendFragmentShader>; |
144 | using TexturePipeline = |
145 | RenderPipelineT<TextureFillVertexShader, TextureFillFragmentShader>; |
146 | using PositionUVPipeline = |
147 | RenderPipelineT<TextureFillVertexShader, TiledTextureFillFragmentShader>; |
148 | using TiledTexturePipeline = |
149 | RenderPipelineT<TextureFillVertexShader, TiledTextureFillFragmentShader>; |
150 | using GaussianBlurAlphaDecalPipeline = |
151 | RenderPipelineT<GaussianBlurVertexShader, |
152 | GaussianBlurAlphaDecalFragmentShader>; |
153 | using GaussianBlurAlphaPipeline = |
154 | RenderPipelineT<GaussianBlurVertexShader, |
155 | GaussianBlurAlphaNodecalFragmentShader>; |
156 | using GaussianBlurDecalPipeline = |
157 | RenderPipelineT<GaussianBlurVertexShader, |
158 | GaussianBlurNoalphaDecalFragmentShader>; |
159 | using GaussianBlurPipeline = |
160 | RenderPipelineT<GaussianBlurVertexShader, |
161 | GaussianBlurNoalphaNodecalFragmentShader>; |
162 | using BorderMaskBlurPipeline = |
163 | RenderPipelineT<BorderMaskBlurVertexShader, BorderMaskBlurFragmentShader>; |
164 | using MorphologyFilterPipeline = |
165 | RenderPipelineT<MorphologyFilterVertexShader, |
166 | MorphologyFilterFragmentShader>; |
167 | using ColorMatrixColorFilterPipeline = |
168 | RenderPipelineT<ColorMatrixColorFilterVertexShader, |
169 | ColorMatrixColorFilterFragmentShader>; |
170 | using LinearToSrgbFilterPipeline = |
171 | RenderPipelineT<LinearToSrgbFilterVertexShader, |
172 | LinearToSrgbFilterFragmentShader>; |
173 | using SrgbToLinearFilterPipeline = |
174 | RenderPipelineT<SrgbToLinearFilterVertexShader, |
175 | SrgbToLinearFilterFragmentShader>; |
176 | using GlyphAtlasPipeline = |
177 | RenderPipelineT<GlyphAtlasVertexShader, GlyphAtlasFragmentShader>; |
178 | using GlyphAtlasColorPipeline = |
179 | RenderPipelineT<GlyphAtlasVertexShader, GlyphAtlasColorFragmentShader>; |
180 | using 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. |
184 | using ClipPipeline = RenderPipelineT<ClipVertexShader, ClipFragmentShader>; |
185 | |
186 | using GeometryColorPipeline = |
187 | RenderPipelineT<PositionColorVertexShader, VerticesFragmentShader>; |
188 | using YUVToRGBFilterPipeline = |
189 | RenderPipelineT<YuvToRgbFilterVertexShader, YuvToRgbFilterFragmentShader>; |
190 | |
191 | // Advanced blends |
192 | using BlendColorPipeline = RenderPipelineT<AdvancedBlendVertexShader, |
193 | AdvancedBlendColorFragmentShader>; |
194 | using BlendColorBurnPipeline = |
195 | RenderPipelineT<AdvancedBlendVertexShader, |
196 | AdvancedBlendColorburnFragmentShader>; |
197 | using BlendColorDodgePipeline = |
198 | RenderPipelineT<AdvancedBlendVertexShader, |
199 | AdvancedBlendColordodgeFragmentShader>; |
200 | using BlendDarkenPipeline = RenderPipelineT<AdvancedBlendVertexShader, |
201 | AdvancedBlendDarkenFragmentShader>; |
202 | using BlendDifferencePipeline = |
203 | RenderPipelineT<AdvancedBlendVertexShader, |
204 | AdvancedBlendDifferenceFragmentShader>; |
205 | using BlendExclusionPipeline = |
206 | RenderPipelineT<AdvancedBlendVertexShader, |
207 | AdvancedBlendExclusionFragmentShader>; |
208 | using BlendHardLightPipeline = |
209 | RenderPipelineT<AdvancedBlendVertexShader, |
210 | AdvancedBlendHardlightFragmentShader>; |
211 | using BlendHuePipeline = |
212 | RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendHueFragmentShader>; |
213 | using BlendLightenPipeline = |
214 | RenderPipelineT<AdvancedBlendVertexShader, |
215 | AdvancedBlendLightenFragmentShader>; |
216 | using BlendLuminosityPipeline = |
217 | RenderPipelineT<AdvancedBlendVertexShader, |
218 | AdvancedBlendLuminosityFragmentShader>; |
219 | using BlendMultiplyPipeline = |
220 | RenderPipelineT<AdvancedBlendVertexShader, |
221 | AdvancedBlendMultiplyFragmentShader>; |
222 | using BlendOverlayPipeline = |
223 | RenderPipelineT<AdvancedBlendVertexShader, |
224 | AdvancedBlendOverlayFragmentShader>; |
225 | using BlendSaturationPipeline = |
226 | RenderPipelineT<AdvancedBlendVertexShader, |
227 | AdvancedBlendSaturationFragmentShader>; |
228 | using BlendScreenPipeline = RenderPipelineT<AdvancedBlendVertexShader, |
229 | AdvancedBlendScreenFragmentShader>; |
230 | using BlendSoftLightPipeline = |
231 | RenderPipelineT<AdvancedBlendVertexShader, |
232 | AdvancedBlendSoftlightFragmentShader>; |
233 | // Framebuffer Advanced Blends |
234 | using FramebufferBlendColorPipeline = |
235 | RenderPipelineT<FramebufferBlendVertexShader, |
236 | FramebufferBlendColorFragmentShader>; |
237 | using FramebufferBlendColorBurnPipeline = |
238 | RenderPipelineT<FramebufferBlendVertexShader, |
239 | FramebufferBlendColorburnFragmentShader>; |
240 | using FramebufferBlendColorDodgePipeline = |
241 | RenderPipelineT<FramebufferBlendVertexShader, |
242 | FramebufferBlendColordodgeFragmentShader>; |
243 | using FramebufferBlendDarkenPipeline = |
244 | RenderPipelineT<FramebufferBlendVertexShader, |
245 | FramebufferBlendDarkenFragmentShader>; |
246 | using FramebufferBlendDifferencePipeline = |
247 | RenderPipelineT<FramebufferBlendVertexShader, |
248 | FramebufferBlendDifferenceFragmentShader>; |
249 | using FramebufferBlendExclusionPipeline = |
250 | RenderPipelineT<FramebufferBlendVertexShader, |
251 | FramebufferBlendExclusionFragmentShader>; |
252 | using FramebufferBlendHardLightPipeline = |
253 | RenderPipelineT<FramebufferBlendVertexShader, |
254 | FramebufferBlendHardlightFragmentShader>; |
255 | using FramebufferBlendHuePipeline = |
256 | RenderPipelineT<FramebufferBlendVertexShader, |
257 | FramebufferBlendHueFragmentShader>; |
258 | using FramebufferBlendLightenPipeline = |
259 | RenderPipelineT<FramebufferBlendVertexShader, |
260 | FramebufferBlendLightenFragmentShader>; |
261 | using FramebufferBlendLuminosityPipeline = |
262 | RenderPipelineT<FramebufferBlendVertexShader, |
263 | FramebufferBlendLuminosityFragmentShader>; |
264 | using FramebufferBlendMultiplyPipeline = |
265 | RenderPipelineT<FramebufferBlendVertexShader, |
266 | FramebufferBlendMultiplyFragmentShader>; |
267 | using FramebufferBlendOverlayPipeline = |
268 | RenderPipelineT<FramebufferBlendVertexShader, |
269 | FramebufferBlendOverlayFragmentShader>; |
270 | using FramebufferBlendSaturationPipeline = |
271 | RenderPipelineT<FramebufferBlendVertexShader, |
272 | FramebufferBlendSaturationFragmentShader>; |
273 | using FramebufferBlendScreenPipeline = |
274 | RenderPipelineT<FramebufferBlendVertexShader, |
275 | FramebufferBlendScreenFragmentShader>; |
276 | using FramebufferBlendSoftLightPipeline = |
277 | RenderPipelineT<FramebufferBlendVertexShader, |
278 | FramebufferBlendSoftlightFragmentShader>; |
279 | |
280 | /// Geometry Pipelines |
281 | using PointsComputeShaderPipeline = ComputePipelineBuilder<PointsComputeShader>; |
282 | using 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. |
294 | struct 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 | |
331 | class Tessellator; |
332 | |
333 | class 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 | |