| 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
5 #include "impeller/entity/contents/content_context.h"
6
7 #include <memory>
8 #include <utility>
9
10 #include "fml/trace_event.h"
11 #include "impeller/base/strings.h"
12 #include "impeller/base/validation.h"
13 #include "impeller/core/formats.h"
14 #include "impeller/entity/contents/framebuffer_blend_contents.h"
15 #include "impeller/entity/entity.h"
16 #include "impeller/entity/render_target_cache.h"
17 #include "impeller/renderer/command_buffer.h"
18 #include "impeller/renderer/pipeline_descriptor.h"
19 #include "impeller/renderer/pipeline_library.h"
20 #include "impeller/renderer/render_target.h"
21 #include "impeller/renderer/texture_mipmap.h"
22 #include "impeller/tessellator/tessellator.h"
23 #include "impeller/typographer/typographer_context.h"
24
25 namespace impeller {
26
27 void ContentContextOptions::ApplyToPipelineDescriptor(
28 PipelineDescriptor& desc) const {
29 auto pipeline_blend = blend_mode;
30 if (blend_mode > Entity::kLastPipelineBlendMode) {
31 VALIDATION_LOG << "Cannot use blend mode " << static_cast<int>(blend_mode)
32 << " as a pipeline blend.";
33 pipeline_blend = BlendMode::kSourceOver;
34 }
35
36 desc.SetSampleCount(sample_count);
37
38 ColorAttachmentDescriptor color0 = *desc.GetColorAttachmentDescriptor(0u);
39 color0.format = color_attachment_pixel_format;
40 color0.alpha_blend_op = BlendOperation::kAdd;
41 color0.color_blend_op = BlendOperation::kAdd;
42
43 switch (pipeline_blend) {
44 case BlendMode::kClear:
45 if (is_for_rrect_blur_clear) {
46 color0.alpha_blend_op = BlendOperation::kReverseSubtract;
47 color0.color_blend_op = BlendOperation::kReverseSubtract;
48 color0.dst_alpha_blend_factor = BlendFactor::kOne;
49 color0.dst_color_blend_factor = BlendFactor::kOne;
50 color0.src_alpha_blend_factor = BlendFactor::kDestinationColor;
51 color0.src_color_blend_factor = BlendFactor::kDestinationColor;
52 } else {
53 color0.dst_alpha_blend_factor = BlendFactor::kZero;
54 color0.dst_color_blend_factor = BlendFactor::kZero;
55 color0.src_alpha_blend_factor = BlendFactor::kZero;
56 color0.src_color_blend_factor = BlendFactor::kZero;
57 }
58 break;
59 case BlendMode::kSource:
60 color0.blending_enabled = false;
61 color0.dst_alpha_blend_factor = BlendFactor::kZero;
62 color0.dst_color_blend_factor = BlendFactor::kZero;
63 color0.src_alpha_blend_factor = BlendFactor::kOne;
64 color0.src_color_blend_factor = BlendFactor::kOne;
65 break;
66 case BlendMode::kDestination:
67 color0.dst_alpha_blend_factor = BlendFactor::kOne;
68 color0.dst_color_blend_factor = BlendFactor::kOne;
69 color0.src_alpha_blend_factor = BlendFactor::kZero;
70 color0.src_color_blend_factor = BlendFactor::kZero;
71 break;
72 case BlendMode::kSourceOver:
73 color0.dst_alpha_blend_factor = BlendFactor::kOneMinusSourceAlpha;
74 color0.dst_color_blend_factor = BlendFactor::kOneMinusSourceAlpha;
75 color0.src_alpha_blend_factor = BlendFactor::kOne;
76 color0.src_color_blend_factor = BlendFactor::kOne;
77 break;
78 case BlendMode::kDestinationOver:
79 color0.dst_alpha_blend_factor = BlendFactor::kOne;
80 color0.dst_color_blend_factor = BlendFactor::kOne;
81 color0.src_alpha_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
82 color0.src_color_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
83 break;
84 case BlendMode::kSourceIn:
85 color0.dst_alpha_blend_factor = BlendFactor::kZero;
86 color0.dst_color_blend_factor = BlendFactor::kZero;
87 color0.src_alpha_blend_factor = BlendFactor::kDestinationAlpha;
88 color0.src_color_blend_factor = BlendFactor::kDestinationAlpha;
89 break;
90 case BlendMode::kDestinationIn:
91 color0.dst_alpha_blend_factor = BlendFactor::kSourceAlpha;
92 color0.dst_color_blend_factor = BlendFactor::kSourceAlpha;
93 color0.src_alpha_blend_factor = BlendFactor::kZero;
94 color0.src_color_blend_factor = BlendFactor::kZero;
95 break;
96 case BlendMode::kSourceOut:
97 color0.dst_alpha_blend_factor = BlendFactor::kZero;
98 color0.dst_color_blend_factor = BlendFactor::kZero;
99 color0.src_alpha_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
100 color0.src_color_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
101 break;
102 case BlendMode::kDestinationOut:
103 color0.dst_alpha_blend_factor = BlendFactor::kOneMinusSourceAlpha;
104 color0.dst_color_blend_factor = BlendFactor::kOneMinusSourceAlpha;
105 color0.src_alpha_blend_factor = BlendFactor::kZero;
106 color0.src_color_blend_factor = BlendFactor::kZero;
107 break;
108 case BlendMode::kSourceATop:
109 color0.dst_alpha_blend_factor = BlendFactor::kOneMinusSourceAlpha;
110 color0.dst_color_blend_factor = BlendFactor::kOneMinusSourceAlpha;
111 color0.src_alpha_blend_factor = BlendFactor::kDestinationAlpha;
112 color0.src_color_blend_factor = BlendFactor::kDestinationAlpha;
113 break;
114 case BlendMode::kDestinationATop:
115 color0.dst_alpha_blend_factor = BlendFactor::kSourceAlpha;
116 color0.dst_color_blend_factor = BlendFactor::kSourceAlpha;
117 color0.src_alpha_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
118 color0.src_color_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
119 break;
120 case BlendMode::kXor:
121 color0.dst_alpha_blend_factor = BlendFactor::kOneMinusSourceAlpha;
122 color0.dst_color_blend_factor = BlendFactor::kOneMinusSourceAlpha;
123 color0.src_alpha_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
124 color0.src_color_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
125 break;
126 case BlendMode::kPlus:
127 color0.dst_alpha_blend_factor = BlendFactor::kOne;
128 color0.dst_color_blend_factor = BlendFactor::kOne;
129 color0.src_alpha_blend_factor = BlendFactor::kOne;
130 color0.src_color_blend_factor = BlendFactor::kOne;
131 break;
132 case BlendMode::kModulate:
133 color0.dst_alpha_blend_factor = BlendFactor::kSourceAlpha;
134 color0.dst_color_blend_factor = BlendFactor::kSourceColor;
135 color0.src_alpha_blend_factor = BlendFactor::kZero;
136 color0.src_color_blend_factor = BlendFactor::kZero;
137 break;
138 default:
139 FML_UNREACHABLE();
140 }
141 desc.SetColorAttachmentDescriptor(0u, color0);
142
143 if (!has_depth_stencil_attachments) {
144 desc.ClearDepthAttachment();
145 desc.ClearStencilAttachments();
146 }
147
148 auto maybe_stencil = desc.GetFrontStencilAttachmentDescriptor();
149 auto maybe_depth = desc.GetDepthStencilAttachmentDescriptor();
150 FML_DCHECK(has_depth_stencil_attachments == maybe_depth.has_value())
151 << "Depth attachment doesn't match expected pipeline state. "
152 "has_depth_stencil_attachments="
153 << has_depth_stencil_attachments;
154 FML_DCHECK(has_depth_stencil_attachments == maybe_stencil.has_value())
155 << "Stencil attachment doesn't match expected pipeline state. "
156 "has_depth_stencil_attachments="
157 << has_depth_stencil_attachments;
158 if (maybe_stencil.has_value()) {
159 StencilAttachmentDescriptor front_stencil = maybe_stencil.value();
160 StencilAttachmentDescriptor back_stencil = front_stencil;
161
162 switch (stencil_mode) {
163 case StencilMode::kIgnore:
164 front_stencil.stencil_compare = CompareFunction::kAlways;
165 front_stencil.depth_stencil_pass = StencilOperation::kKeep;
166 desc.SetStencilAttachmentDescriptors(front_stencil);
167 break;
168 case StencilMode::kStencilNonZeroFill:
169 // The stencil ref should be 0 on commands that use this mode.
170 front_stencil.stencil_compare = CompareFunction::kAlways;
171 front_stencil.depth_stencil_pass = StencilOperation::kIncrementWrap;
172 back_stencil.stencil_compare = CompareFunction::kAlways;
173 back_stencil.depth_stencil_pass = StencilOperation::kDecrementWrap;
174 desc.SetStencilAttachmentDescriptors(front_stencil, back_stencil);
175 break;
176 case StencilMode::kStencilEvenOddFill:
177 // The stencil ref should be 0 on commands that use this mode.
178 front_stencil.stencil_compare = CompareFunction::kEqual;
179 front_stencil.depth_stencil_pass = StencilOperation::kIncrementWrap;
180 front_stencil.stencil_failure = StencilOperation::kDecrementWrap;
181 desc.SetStencilAttachmentDescriptors(front_stencil);
182 break;
183 case StencilMode::kCoverCompare:
184 // The stencil ref should be 0 on commands that use this mode.
185 front_stencil.stencil_compare = CompareFunction::kNotEqual;
186 front_stencil.depth_stencil_pass =
187 StencilOperation::kSetToReferenceValue;
188 desc.SetStencilAttachmentDescriptors(front_stencil);
189 break;
190 case StencilMode::kCoverCompareInverted:
191 // The stencil ref should be 0 on commands that use this mode.
192 front_stencil.stencil_compare = CompareFunction::kEqual;
193 front_stencil.stencil_failure = StencilOperation::kSetToReferenceValue;
194 desc.SetStencilAttachmentDescriptors(front_stencil);
195 break;
196 case StencilMode::kLegacyClipRestore:
197 front_stencil.stencil_compare = CompareFunction::kLess;
198 front_stencil.depth_stencil_pass =
199 StencilOperation::kSetToReferenceValue;
200 desc.SetStencilAttachmentDescriptors(front_stencil);
201 break;
202 case StencilMode::kLegacyClipIncrement:
203 front_stencil.stencil_compare = CompareFunction::kEqual;
204 front_stencil.depth_stencil_pass = StencilOperation::kIncrementClamp;
205 desc.SetStencilAttachmentDescriptors(front_stencil);
206 break;
207 case StencilMode::kLegacyClipDecrement:
208 front_stencil.stencil_compare = CompareFunction::kEqual;
209 front_stencil.depth_stencil_pass = StencilOperation::kDecrementClamp;
210 desc.SetStencilAttachmentDescriptors(front_stencil);
211 break;
212 case StencilMode::kLegacyClipCompare:
213 front_stencil.stencil_compare = CompareFunction::kEqual;
214 front_stencil.depth_stencil_pass = StencilOperation::kKeep;
215 desc.SetStencilAttachmentDescriptors(front_stencil);
216 break;
217 }
218 }
219 if (maybe_depth.has_value()) {
220 DepthAttachmentDescriptor depth = maybe_depth.value();
221 depth.depth_write_enabled = depth_write_enabled;
222 depth.depth_compare = depth_compare;
223 desc.SetDepthStencilAttachmentDescriptor(depth);
224 }
225
226 desc.SetPrimitiveType(primitive_type);
227
228 desc.SetPolygonMode(wireframe ? PolygonMode::kLine : PolygonMode::kFill);
229 }
230
231 template <typename PipelineT>
232 static std::unique_ptr<PipelineT> CreateDefaultPipeline(
233 const Context& context) {
234 auto desc = PipelineT::Builder::MakeDefaultPipelineDescriptor(context);
235 if (!desc.has_value()) {
236 return nullptr;
237 }
238 // Apply default ContentContextOptions to the descriptor.
239 const auto default_color_format =
240 context.GetCapabilities()->GetDefaultColorFormat();
241 ContentContextOptions{.sample_count = SampleCount::kCount4,
242 .primitive_type = PrimitiveType::kTriangleStrip,
243 .color_attachment_pixel_format = default_color_format}
244 .ApplyToPipelineDescriptor(*desc);
245 return std::make_unique<PipelineT>(context, desc);
246 }
247
248 ContentContext::ContentContext(
249 std::shared_ptr<Context> context,
250 std::shared_ptr<TypographerContext> typographer_context,
251 std::shared_ptr<RenderTargetAllocator> render_target_allocator)
252 : context_(std::move(context)),
253 lazy_glyph_atlas_(
254 std::make_shared<LazyGlyphAtlas>(std::move(typographer_context))),
255 tessellator_(std::make_shared<Tessellator>()),
256 #if IMPELLER_ENABLE_3D
257 scene_context_(std::make_shared<scene::SceneContext>(context_)),
258 #endif // IMPELLER_ENABLE_3D
259 render_target_cache_(render_target_allocator == nullptr
260 ? std::make_shared<RenderTargetCache>(
261 context_->GetResourceAllocator())
262 : std::move(render_target_allocator)),
263 host_buffer_(HostBuffer::Create(context_->GetResourceAllocator())),
264 pending_command_buffers_(std::make_unique<PendingCommandBuffers>()) {
265 if (!context_ || !context_->IsValid()) {
266 return;
267 }
268
269 auto options = ContentContextOptions{
270 .sample_count = SampleCount::kCount4,
271 .color_attachment_pixel_format =
272 context_->GetCapabilities()->GetDefaultColorFormat()};
273 auto options_trianglestrip = ContentContextOptions{
274 .sample_count = SampleCount::kCount4,
275 .primitive_type = PrimitiveType::kTriangleStrip,
276 .color_attachment_pixel_format =
277 context_->GetCapabilities()->GetDefaultColorFormat()};
278 const auto supports_decal = static_cast<Scalar>(
279 context_->GetCapabilities()->SupportsDecalSamplerAddressMode());
280
281 #ifdef IMPELLER_DEBUG
282 checkerboard_pipelines_.CreateDefault(*context_, options);
283 #endif // IMPELLER_DEBUG
284
285 solid_fill_pipelines_.CreateDefault(*context_, options);
286
287 if (context_->GetCapabilities()->SupportsSSBO()) {
288 linear_gradient_ssbo_fill_pipelines_.CreateDefault(*context_, options);
289 radial_gradient_ssbo_fill_pipelines_.CreateDefault(*context_, options);
290 conical_gradient_ssbo_fill_pipelines_.CreateDefault(*context_, options);
291 sweep_gradient_ssbo_fill_pipelines_.CreateDefault(*context_, options);
292 } else {
293 linear_gradient_fill_pipelines_.CreateDefault(*context_, options);
294 radial_gradient_fill_pipelines_.CreateDefault(*context_, options);
295 conical_gradient_fill_pipelines_.CreateDefault(*context_, options);
296 sweep_gradient_fill_pipelines_.CreateDefault(*context_, options);
297 }
298
299 if (context_->GetCapabilities()->SupportsFramebufferFetch()) {
300 framebuffer_blend_color_pipelines_.CreateDefault(
301 *context_, options_trianglestrip,
302 {static_cast<Scalar>(BlendSelectValues::kColor), supports_decal});
303 framebuffer_blend_colorburn_pipelines_.CreateDefault(
304 *context_, options_trianglestrip,
305 {static_cast<Scalar>(BlendSelectValues::kColorBurn), supports_decal});
306 framebuffer_blend_colordodge_pipelines_.CreateDefault(
307 *context_, options_trianglestrip,
308 {static_cast<Scalar>(BlendSelectValues::kColorDodge), supports_decal});
309 framebuffer_blend_darken_pipelines_.CreateDefault(
310 *context_, options_trianglestrip,
311 {static_cast<Scalar>(BlendSelectValues::kDarken), supports_decal});
312 framebuffer_blend_difference_pipelines_.CreateDefault(
313 *context_, options_trianglestrip,
314 {static_cast<Scalar>(BlendSelectValues::kDifference), supports_decal});
315 framebuffer_blend_exclusion_pipelines_.CreateDefault(
316 *context_, options_trianglestrip,
317 {static_cast<Scalar>(BlendSelectValues::kExclusion), supports_decal});
318 framebuffer_blend_hardlight_pipelines_.CreateDefault(
319 *context_, options_trianglestrip,
320 {static_cast<Scalar>(BlendSelectValues::kHardLight), supports_decal});
321 framebuffer_blend_hue_pipelines_.CreateDefault(
322 *context_, options_trianglestrip,
323 {static_cast<Scalar>(BlendSelectValues::kHue), supports_decal});
324 framebuffer_blend_lighten_pipelines_.CreateDefault(
325 *context_, options_trianglestrip,
326 {static_cast<Scalar>(BlendSelectValues::kLighten), supports_decal});
327 framebuffer_blend_luminosity_pipelines_.CreateDefault(
328 *context_, options_trianglestrip,
329 {static_cast<Scalar>(BlendSelectValues::kLuminosity), supports_decal});
330 framebuffer_blend_multiply_pipelines_.CreateDefault(
331 *context_, options_trianglestrip,
332 {static_cast<Scalar>(BlendSelectValues::kMultiply), supports_decal});
333 framebuffer_blend_overlay_pipelines_.CreateDefault(
334 *context_, options_trianglestrip,
335 {static_cast<Scalar>(BlendSelectValues::kOverlay), supports_decal});
336 framebuffer_blend_saturation_pipelines_.CreateDefault(
337 *context_, options_trianglestrip,
338 {static_cast<Scalar>(BlendSelectValues::kSaturation), supports_decal});
339 framebuffer_blend_screen_pipelines_.CreateDefault(
340 *context_, options_trianglestrip,
341 {static_cast<Scalar>(BlendSelectValues::kScreen), supports_decal});
342 framebuffer_blend_softlight_pipelines_.CreateDefault(
343 *context_, options_trianglestrip,
344 {static_cast<Scalar>(BlendSelectValues::kSoftLight), supports_decal});
345 }
346
347 blend_color_pipelines_.CreateDefault(
348 *context_, options_trianglestrip,
349 {static_cast<Scalar>(BlendSelectValues::kColor), supports_decal});
350 blend_colorburn_pipelines_.CreateDefault(
351 *context_, options_trianglestrip,
352 {static_cast<Scalar>(BlendSelectValues::kColorBurn), supports_decal});
353 blend_colordodge_pipelines_.CreateDefault(
354 *context_, options_trianglestrip,
355 {static_cast<Scalar>(BlendSelectValues::kColorDodge), supports_decal});
356 blend_darken_pipelines_.CreateDefault(
357 *context_, options_trianglestrip,
358 {static_cast<Scalar>(BlendSelectValues::kDarken), supports_decal});
359 blend_difference_pipelines_.CreateDefault(
360 *context_, options_trianglestrip,
361 {static_cast<Scalar>(BlendSelectValues::kDifference), supports_decal});
362 blend_exclusion_pipelines_.CreateDefault(
363 *context_, options_trianglestrip,
364 {static_cast<Scalar>(BlendSelectValues::kExclusion), supports_decal});
365 blend_hardlight_pipelines_.CreateDefault(
366 *context_, options_trianglestrip,
367 {static_cast<Scalar>(BlendSelectValues::kHardLight), supports_decal});
368 blend_hue_pipelines_.CreateDefault(
369 *context_, options_trianglestrip,
370 {static_cast<Scalar>(BlendSelectValues::kHue), supports_decal});
371 blend_lighten_pipelines_.CreateDefault(
372 *context_, options_trianglestrip,
373 {static_cast<Scalar>(BlendSelectValues::kLighten), supports_decal});
374 blend_luminosity_pipelines_.CreateDefault(
375 *context_, options_trianglestrip,
376 {static_cast<Scalar>(BlendSelectValues::kLuminosity), supports_decal});
377 blend_multiply_pipelines_.CreateDefault(
378 *context_, options_trianglestrip,
379 {static_cast<Scalar>(BlendSelectValues::kMultiply), supports_decal});
380 blend_overlay_pipelines_.CreateDefault(
381 *context_, options_trianglestrip,
382 {static_cast<Scalar>(BlendSelectValues::kOverlay), supports_decal});
383 blend_saturation_pipelines_.CreateDefault(
384 *context_, options_trianglestrip,
385 {static_cast<Scalar>(BlendSelectValues::kSaturation), supports_decal});
386 blend_screen_pipelines_.CreateDefault(
387 *context_, options_trianglestrip,
388 {static_cast<Scalar>(BlendSelectValues::kScreen), supports_decal});
389 blend_softlight_pipelines_.CreateDefault(
390 *context_, options_trianglestrip,
391 {static_cast<Scalar>(BlendSelectValues::kSoftLight), supports_decal});
392
393 rrect_blur_pipelines_.CreateDefault(*context_, options_trianglestrip);
394 texture_blend_pipelines_.CreateDefault(*context_, options);
395 texture_pipelines_.CreateDefault(*context_, options);
396 texture_strict_src_pipelines_.CreateDefault(*context_, options);
397 position_uv_pipelines_.CreateDefault(*context_, options);
398 tiled_texture_pipelines_.CreateDefault(*context_, options);
399 gaussian_blur_noalpha_decal_pipelines_.CreateDefault(*context_,
400 options_trianglestrip);
401 gaussian_blur_noalpha_nodecal_pipelines_.CreateDefault(*context_,
402 options_trianglestrip);
403 kernel_decal_pipelines_.CreateDefault(*context_, options_trianglestrip);
404 kernel_nodecal_pipelines_.CreateDefault(*context_, options_trianglestrip);
405 border_mask_blur_pipelines_.CreateDefault(*context_, options_trianglestrip);
406 morphology_filter_pipelines_.CreateDefault(*context_, options_trianglestrip,
407 {supports_decal});
408 color_matrix_color_filter_pipelines_.CreateDefault(*context_,
409 options_trianglestrip);
410 linear_to_srgb_filter_pipelines_.CreateDefault(*context_,
411 options_trianglestrip);
412 srgb_to_linear_filter_pipelines_.CreateDefault(*context_,
413 options_trianglestrip);
414 glyph_atlas_pipelines_.CreateDefault(
415 *context_, options,
416 {static_cast<Scalar>(
417 GetContext()->GetCapabilities()->GetDefaultGlyphAtlasFormat() ==
418 PixelFormat::kA8UNormInt)});
419 glyph_atlas_color_pipelines_.CreateDefault(*context_, options);
420 geometry_color_pipelines_.CreateDefault(*context_, options);
421 yuv_to_rgb_filter_pipelines_.CreateDefault(*context_, options_trianglestrip);
422 porter_duff_blend_pipelines_.CreateDefault(*context_, options_trianglestrip,
423 {supports_decal});
424 // GLES only shader that is unsupported on macOS.
425 #if defined(IMPELLER_ENABLE_OPENGLES) && !defined(FML_OS_MACOSX)
426 if (GetContext()->GetBackendType() == Context::BackendType::kOpenGLES) {
427 texture_external_pipelines_.CreateDefault(*context_, options);
428 }
429 if (GetContext()->GetBackendType() == Context::BackendType::kOpenGLES) {
430 tiled_texture_external_pipelines_.CreateDefault(*context_, options);
431 }
432 #endif // IMPELLER_ENABLE_OPENGLES
433 if (context_->GetCapabilities()->SupportsCompute()) {
434 auto pipeline_desc =
435 PointsComputeShaderPipeline::MakeDefaultPipelineDescriptor(*context_);
436 point_field_compute_pipelines_ =
437 context_->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
438
439 auto uv_pipeline_desc =
440 UvComputeShaderPipeline::MakeDefaultPipelineDescriptor(*context_);
441 uv_compute_pipelines_ =
442 context_->GetPipelineLibrary()->GetPipeline(uv_pipeline_desc).Get();
443 }
444
445 /// Setup default clip pipeline.
446
447 auto clip_pipeline_descriptor =
448 ClipPipeline::Builder::MakeDefaultPipelineDescriptor(*context_);
449 if (!clip_pipeline_descriptor.has_value()) {
450 return;
451 }
452 ContentContextOptions{
453 .sample_count = SampleCount::kCount4,
454 .color_attachment_pixel_format =
455 context_->GetCapabilities()->GetDefaultColorFormat()}
456 .ApplyToPipelineDescriptor(*clip_pipeline_descriptor);
457 // Disable write to all color attachments.
458 auto clip_color_attachments =
459 clip_pipeline_descriptor->GetColorAttachmentDescriptors();
460 for (auto& color_attachment : clip_color_attachments) {
461 color_attachment.second.write_mask = ColorWriteMaskBits::kNone;
462 }
463 clip_pipeline_descriptor->SetColorAttachmentDescriptors(
464 std::move(clip_color_attachments));
465 clip_pipelines_.SetDefault(options, std::make_unique<ClipPipeline>(
466 *context_, clip_pipeline_descriptor));
467
468 is_valid_ = true;
469 InitializeCommonlyUsedShadersIfNeeded();
470 }
471
472 ContentContext::~ContentContext() = default;
473
474 bool ContentContext::IsValid() const {
475 return is_valid_;
476 }
477
478 fml::StatusOr<RenderTarget> ContentContext::MakeSubpass(
479 const std::string& label,
480 ISize texture_size,
481 const SubpassCallback& subpass_callback,
482 bool msaa_enabled,
483 bool depth_stencil_enabled,
484 int32_t mip_count) const {
485 const std::shared_ptr<Context>& context = GetContext();
486 RenderTarget subpass_target;
487
488 std::optional<RenderTarget::AttachmentConfig> depth_stencil_config =
489 depth_stencil_enabled ? RenderTarget::kDefaultStencilAttachmentConfig
490 : std::optional<RenderTarget::AttachmentConfig>();
491
492 if (context->GetCapabilities()->SupportsOffscreenMSAA() && msaa_enabled) {
493 subpass_target = GetRenderTargetCache()->CreateOffscreenMSAA(
494 *context, texture_size,
495 /*mip_count=*/mip_count, SPrintF("%s Offscreen", label.c_str()),
496 RenderTarget::kDefaultColorAttachmentConfigMSAA, depth_stencil_config);
497 } else {
498 subpass_target = GetRenderTargetCache()->CreateOffscreen(
499 *context, texture_size,
500 /*mip_count=*/mip_count, SPrintF("%s Offscreen", label.c_str()),
501 RenderTarget::kDefaultColorAttachmentConfig, depth_stencil_config);
502 }
503 return MakeSubpass(label, subpass_target, subpass_callback);
504 }
505
506 fml::StatusOr<RenderTarget> ContentContext::MakeSubpass(
507 const std::string& label,
508 const RenderTarget& subpass_target,
509 const SubpassCallback& subpass_callback) const {
510 const std::shared_ptr<Context>& context = GetContext();
511
512 auto subpass_texture = subpass_target.GetRenderTargetTexture();
513 if (!subpass_texture) {
514 return fml::Status(fml::StatusCode::kUnknown, "");
515 }
516
517 auto sub_command_buffer = context->CreateCommandBuffer();
518 sub_command_buffer->SetLabel(SPrintF("%s CommandBuffer", label.c_str()));
519 if (!sub_command_buffer) {
520 return fml::Status(fml::StatusCode::kUnknown, "");
521 }
522
523 auto sub_renderpass = sub_command_buffer->CreateRenderPass(subpass_target);
524 if (!sub_renderpass) {
525 return fml::Status(fml::StatusCode::kUnknown, "");
526 }
527 sub_renderpass->SetLabel(SPrintF("%s RenderPass", label.c_str()));
528
529 if (!subpass_callback(*this, *sub_renderpass)) {
530 return fml::Status(fml::StatusCode::kUnknown, "");
531 }
532
533 if (!sub_renderpass->EncodeCommands()) {
534 return fml::Status(fml::StatusCode::kUnknown, "");
535 }
536
537 const std::shared_ptr<Texture>& target_texture =
538 subpass_target.GetRenderTargetTexture();
539 if (target_texture->GetMipCount() > 1) {
540 fml::Status mipmap_status =
541 AddMipmapGeneration(sub_command_buffer, context, target_texture);
542 if (!mipmap_status.ok()) {
543 return mipmap_status;
544 }
545 }
546
547 if (!context->GetCommandQueue()->Submit({sub_command_buffer}).ok()) {
548 return fml::Status(fml::StatusCode::kUnknown, "");
549 }
550
551 return subpass_target;
552 }
553
554 #if IMPELLER_ENABLE_3D
555 std::shared_ptr<scene::SceneContext> ContentContext::GetSceneContext() const {
556 return scene_context_;
557 }
558 #endif // IMPELLER_ENABLE_3D
559
560 std::shared_ptr<Tessellator> ContentContext::GetTessellator() const {
561 return tessellator_;
562 }
563
564 std::shared_ptr<Context> ContentContext::GetContext() const {
565 return context_;
566 }
567
568 const Capabilities& ContentContext::GetDeviceCapabilities() const {
569 return *context_->GetCapabilities();
570 }
571
572 void ContentContext::SetWireframe(bool wireframe) {
573 wireframe_ = wireframe;
574 }
575
576 std::shared_ptr<Pipeline<PipelineDescriptor>>
577 ContentContext::GetCachedRuntimeEffectPipeline(
578 const std::string& unique_entrypoint_name,
579 const ContentContextOptions& options,
580 const std::function<std::shared_ptr<Pipeline<PipelineDescriptor>>()>&
581 create_callback) const {
582 RuntimeEffectPipelineKey key{unique_entrypoint_name, options};
583 auto it = runtime_effect_pipelines_.find(key);
584 if (it == runtime_effect_pipelines_.end()) {
585 it = runtime_effect_pipelines_.insert(it, {key, create_callback()});
586 }
587 return it->second;
588 }
589
590 void ContentContext::ClearCachedRuntimeEffectPipeline(
591 const std::string& unique_entrypoint_name) const {
592 for (auto it = runtime_effect_pipelines_.begin();
593 it != runtime_effect_pipelines_.end();) {
594 if (it->first.unique_entrypoint_name == unique_entrypoint_name) {
595 it = runtime_effect_pipelines_.erase(it);
596 } else {
597 it++;
598 }
599 }
600 }
601
602 void ContentContext::InitializeCommonlyUsedShadersIfNeeded() const {
603 TRACE_EVENT0("flutter", "InitializeCommonlyUsedShadersIfNeeded");
604 GetContext()->InitializeCommonlyUsedShadersIfNeeded();
605
606 if (GetContext()->GetBackendType() == Context::BackendType::kOpenGLES) {
607 // TODO(jonahwilliams): The OpenGL Embedder Unittests hang if this code
608 // runs.
609 return;
610 }
611
612 // Initialize commonly used shaders that aren't defaults. These settings were
613 // chosen based on the knowledge that we mix and match triangle and
614 // triangle-strip geometry, and also have fairly agressive srcOver to src
615 // blend mode conversions.
616 auto options = ContentContextOptions{
617 .sample_count = SampleCount::kCount4,
618 .color_attachment_pixel_format =
619 context_->GetCapabilities()->GetDefaultColorFormat()};
620
621 for (const auto mode : {BlendMode::kSource, BlendMode::kSourceOver}) {
622 for (const auto geometry :
623 {PrimitiveType::kTriangle, PrimitiveType::kTriangleStrip}) {
624 options.blend_mode = mode;
625 options.primitive_type = geometry;
626 CreateIfNeeded(solid_fill_pipelines_, options);
627 CreateIfNeeded(texture_pipelines_, options);
628 if (GetContext()->GetCapabilities()->SupportsSSBO()) {
629 CreateIfNeeded(linear_gradient_ssbo_fill_pipelines_, options);
630 CreateIfNeeded(radial_gradient_ssbo_fill_pipelines_, options);
631 CreateIfNeeded(sweep_gradient_ssbo_fill_pipelines_, options);
632 CreateIfNeeded(conical_gradient_ssbo_fill_pipelines_, options);
633 }
634 }
635 }
636
637 options.blend_mode = BlendMode::kDestination;
638 options.primitive_type = PrimitiveType::kTriangleStrip;
639 for (const auto stencil_mode :
640 {ContentContextOptions::StencilMode::kLegacyClipIncrement,
641 ContentContextOptions::StencilMode::kLegacyClipDecrement,
642 ContentContextOptions::StencilMode::kLegacyClipRestore}) {
643 options.stencil_mode = stencil_mode;
644 CreateIfNeeded(clip_pipelines_, options);
645 }
646
647 // On ARM devices, the initial usage of vkCmdCopyBufferToImage has been
648 // observed to take 10s of ms as an internal shader is compiled to perform
649 // the operation. Similarly, the initial render pass can also take 10s of ms
650 // for a similar reason. Because the context object is initialized far
651 // before the first frame, create a trivial texture and render pass to force
652 // the driver to compiler these shaders before the frame begins.
653 TextureDescriptor desc;
654 desc.size = {1, 1};
655 desc.storage_mode = StorageMode::kHostVisible;
656 desc.format = PixelFormat::kR8G8B8A8UNormInt;
657 auto texture = GetContext()->GetResourceAllocator()->CreateTexture(desc);
658 uint32_t color = 0;
659 if (!texture->SetContents(reinterpret_cast<uint8_t*>(&color), 4u)) {
660 VALIDATION_LOG << "Failed to set bootstrap texture.";
661 }
662 }
663
664 } // namespace impeller
impeller::PipelineDescriptor
Definition: pipeline_descriptor.h:24
impeller::Pipeline< PipelineDescriptor >
impeller::ContentContextOptions::StencilMode::kIgnore
@ kIgnore
Turn the stencil test off. Used when drawing without stencil-then-cover.
impeller::BlendSelectValues::kSaturation
@ kSaturation
impeller::ContentContext::ClearCachedRuntimeEffectPipeline
void ClearCachedRuntimeEffectPipeline(const std::string &unique_entrypoint_name) const
Definition: content_context.cc:590
impeller::ColorAttachmentDescriptor::src_color_blend_factor
BlendFactor src_color_blend_factor
Definition: formats.h:504
impeller::PipelineDescriptor::SetPolygonMode
void SetPolygonMode(PolygonMode mode)
Definition: pipeline_descriptor.cc:276
impeller::kColor
@ kColor
impeller::Entity::kLastPipelineBlendMode
static constexpr BlendMode kLastPipelineBlendMode
Definition: entity.h:23
impeller::BlendMode::kDestinationATop
@ kDestinationATop
impeller::StencilOperation::kDecrementClamp
@ kDecrementClamp
Decrement the current stencil value by 1. Clamp it to zero.
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::BlendSelectValues::kColorBurn
@ kColorBurn
impeller::RenderTarget::kDefaultColorAttachmentConfig
static constexpr AttachmentConfig kDefaultColorAttachmentConfig
Definition: render_target.h:55
impeller::StencilAttachmentDescriptor::stencil_compare
CompareFunction stencil_compare
Definition: formats.h:598
impeller::ContentContext::ContentContext
ContentContext(std::shared_ptr< Context > context, std::shared_ptr< TypographerContext > typographer_context, std::shared_ptr< RenderTargetAllocator > render_target_allocator=nullptr)
Definition: content_context.cc:248
impeller::BlendSelectValues::kMultiply
@ kMultiply
impeller::AddMipmapGeneration
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_mipmap.cc:11
impeller::ColorWriteMaskBits::kNone
@ kNone
impeller::PixelFormat::kA8UNormInt
@ kA8UNormInt
impeller::PipelineDescriptor::SetStencilAttachmentDescriptors
PipelineDescriptor & SetStencilAttachmentDescriptors(std::optional< StencilAttachmentDescriptor > front_and_back)
Definition: pipeline_descriptor.cc:157
entity.h
impeller::PipelineDescriptor::SetColorAttachmentDescriptor
PipelineDescriptor & SetColorAttachmentDescriptor(size_t index, ColorAttachmentDescriptor desc)
Definition: pipeline_descriptor.cc:110
impeller::Tessellator
A utility that generates triangles of the specified fill type given a polyline. This happens on the C...
Definition: tessellator.h:33
impeller::ContentContextOptions::StencilMode::kLegacyClipCompare
@ kLegacyClipCompare
Used for applying clips to all non-clip draw calls.
impeller::CompareFunction::kEqual
@ kEqual
Comparison test passes if new_value == current_value.
impeller::BlendFactor::kOneMinusSourceAlpha
@ kOneMinusSourceAlpha
impeller::Context::GetCapabilities
virtual const std::shared_ptr< const Capabilities > & GetCapabilities() const =0
Get the capabilities of Impeller context. All optionally supported feature of the platform,...
impeller::HostBuffer
Definition: host_buffer.h:28
impeller::StencilOperation::kKeep
@ kKeep
Don't modify the current stencil value.
impeller::PipelineDescriptor::GetColorAttachmentDescriptor
const ColorAttachmentDescriptor * GetColorAttachmentDescriptor(size_t index) const
Definition: pipeline_descriptor.cc:124
impeller::BlendMode::kSource
@ kSource
impeller::PipelineDescriptor::SetPrimitiveType
void SetPrimitiveType(PrimitiveType type)
Definition: pipeline_descriptor.cc:268
impeller::PixelFormat::kR8G8B8A8UNormInt
@ kR8G8B8A8UNormInt
impeller::BlendMode::kDestination
@ kDestination
impeller::RenderTarget::kDefaultColorAttachmentConfigMSAA
static constexpr AttachmentConfigMSAA kDefaultColorAttachmentConfigMSAA
Definition: render_target.h:61
formats.h
impeller::StencilOperation::kIncrementClamp
@ kIncrementClamp
Increment the current stencil value by 1. Clamp it to the maximum.
impeller::ColorAttachmentDescriptor::alpha_blend_op
BlendOperation alpha_blend_op
Definition: formats.h:509
impeller::ContentContextOptions::has_depth_stencil_attachments
bool has_depth_stencil_attachments
Definition: content_context.h:339
impeller::BlendMode::kDestinationOver
@ kDestinationOver
impeller::BlendMode::kPlus
@ kPlus
impeller::BlendSelectValues::kSoftLight
@ kSoftLight
impeller::ContentContextOptions::blend_mode
BlendMode blend_mode
Definition: content_context.h:333
typographer_context.h
impeller::BlendFactor::kDestinationAlpha
@ kDestinationAlpha
impeller::BlendSelectValues::kDifference
@ kDifference
impeller::ContentContextOptions::ApplyToPipelineDescriptor
void ApplyToPipelineDescriptor(PipelineDescriptor &desc) const
Definition: content_context.cc:27
impeller::StorageMode::kHostVisible
@ kHostVisible
framebuffer_blend_contents.h
impeller::ContentContextOptions::StencilMode::kStencilEvenOddFill
@ kStencilEvenOddFill
impeller::ContentContext::GetCachedRuntimeEffectPipeline
std::shared_ptr< Pipeline< PipelineDescriptor > > GetCachedRuntimeEffectPipeline(const std::string &unique_entrypoint_name, const ContentContextOptions &options, const std::function< std::shared_ptr< Pipeline< PipelineDescriptor >>()> &create_callback) const
Definition: content_context.cc:577
validation.h
impeller::ContentContextOptions::StencilMode::kLegacyClipDecrement
@ kLegacyClipDecrement
Decrement the stencil heightmap (used for difference clipping only).
impeller::BlendMode::kModulate
@ kModulate
impeller::PolygonMode::kFill
@ kFill
impeller::ContentContextOptions::wireframe
bool wireframe
Definition: content_context.h:341
impeller::StencilOperation::kSetToReferenceValue
@ kSetToReferenceValue
Reset the stencil value to the reference value.
impeller::BlendFactor::kSourceColor
@ kSourceColor
impeller::BlendMode::kSourceOut
@ kSourceOut
tessellator.h
impeller::BlendFactor::kDestinationColor
@ kDestinationColor
impeller::BlendSelectValues::kDarken
@ kDarken
impeller::PrimitiveType::kTriangle
@ kTriangle
impeller::BlendSelectValues::kExclusion
@ kExclusion
impeller::BlendFactor::kZero
@ kZero
impeller::Capabilities
Definition: capabilities.h:15
impeller::TSize< int64_t >
impeller::StencilOperation::kDecrementWrap
@ kDecrementWrap
Decrement the current stencil value by 1. If at zero, set to maximum.
impeller::DepthAttachmentDescriptor::depth_write_enabled
bool depth_write_enabled
Definition: formats.h:580
impeller::PrimitiveType::kTriangleStrip
@ kTriangleStrip
impeller::ContentContextOptions::StencilMode::kLegacyClipIncrement
@ kLegacyClipIncrement
Increment the stencil heightmap.
impeller::ComputePipelineBuilder::MakeDefaultPipelineDescriptor
static std::optional< ComputePipelineDescriptor > MakeDefaultPipelineDescriptor(const Context &context)
Create a default pipeline descriptor using the combination reflected shader information....
Definition: compute_pipeline_builder.h:40
impeller::ContentContextOptions::color_attachment_pixel_format
PixelFormat color_attachment_pixel_format
Definition: content_context.h:338
impeller::ContentContext::~ContentContext
~ContentContext()
impeller::RenderTarget::GetRenderTargetTexture
std::shared_ptr< Texture > GetRenderTargetTexture() const
Definition: render_target.cc:144
impeller::BlendOperation::kReverseSubtract
@ kReverseSubtract
impeller::Context::BackendType::kOpenGLES
@ kOpenGLES
impeller::SPrintF
std::string SPrintF(const char *format,...)
Definition: strings.cc:12
impeller::BlendMode::kClear
@ kClear
impeller::ContentContext::MakeSubpass
fml::StatusOr< RenderTarget > MakeSubpass(const std::string &label, ISize texture_size, 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...
Definition: content_context.cc:478
impeller::ContentContext::GetContext
std::shared_ptr< Context > GetContext() const
Definition: content_context.cc:564
impeller::BlendOperation::kAdd
@ kAdd
impeller::RenderTarget::kDefaultStencilAttachmentConfig
static constexpr AttachmentConfig kDefaultStencilAttachmentConfig
Definition: render_target.h:68
impeller::ContentContextOptions::StencilMode::kStencilNonZeroFill
@ kStencilNonZeroFill
impeller::PendingCommandBuffers
Definition: content_context.h:274
texture_mipmap.h
impeller::StencilAttachmentDescriptor::stencil_failure
StencilOperation stencil_failure
Definition: formats.h:602
impeller::ColorAttachmentDescriptor::format
PixelFormat format
Definition: formats.h:501
impeller::StencilOperation::kIncrementWrap
@ kIncrementWrap
Increment the current stencil value by 1. If at maximum, set to zero.
impeller::StencilAttachmentDescriptor::depth_stencil_pass
StencilOperation depth_stencil_pass
Definition: formats.h:611
impeller::RenderTarget
Definition: render_target.h:38
impeller::BlendFactor::kOne
@ kOne
impeller::ContentContextOptions::is_for_rrect_blur_clear
bool is_for_rrect_blur_clear
Definition: content_context.h:342
impeller::ContentContextOptions::stencil_mode
StencilMode stencil_mode
Definition: content_context.h:335
strings.h
impeller::ContentContextOptions::depth_write_enabled
bool depth_write_enabled
Definition: content_context.h:340
impeller::CompareFunction::kAlways
@ kAlways
Comparison test passes always passes.
impeller::ContentContext::GetTessellator
std::shared_ptr< Tessellator > GetTessellator() const
Definition: content_context.cc:560
impeller::ContentContextOptions::primitive_type
PrimitiveType primitive_type
Definition: content_context.h:337
pipeline_library.h
impeller::ContentContext::SubpassCallback
std::function< bool(const ContentContext &, RenderPass &)> SubpassCallback
Definition: content_context.h:783
impeller::PipelineDescriptor::SetSampleCount
PipelineDescriptor & SetSampleCount(SampleCount samples)
Definition: pipeline_descriptor.cc:76
impeller::ColorAttachmentDescriptor::src_alpha_blend_factor
BlendFactor src_alpha_blend_factor
Definition: formats.h:508
impeller::BlendMode::kDestinationIn
@ kDestinationIn
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:73
command_buffer.h
impeller::ColorAttachmentDescriptor::dst_color_blend_factor
BlendFactor dst_color_blend_factor
Definition: formats.h:506
content_context.h
impeller::BlendMode::kDestinationOut
@ kDestinationOut
impeller::ContentContext::GetRenderTargetCache
const std::shared_ptr< RenderTargetAllocator > & GetRenderTargetCache() const
Definition: content_context.h:805
impeller::PipelineDescriptor::GetFrontStencilAttachmentDescriptor
std::optional< StencilAttachmentDescriptor > GetFrontStencilAttachmentDescriptor() const
Definition: pipeline_descriptor.cc:202
impeller::ColorAttachmentDescriptor::dst_alpha_blend_factor
BlendFactor dst_alpha_blend_factor
Definition: formats.h:510
impeller::ContentContextOptions::depth_compare
CompareFunction depth_compare
Definition: content_context.h:334
impeller::PipelineDescriptor::ClearDepthAttachment
void ClearDepthAttachment()
Definition: pipeline_descriptor.cc:176
impeller::ContentContext::GetDeviceCapabilities
const Capabilities & GetDeviceCapabilities() const
Definition: content_context.cc:568
impeller::Context
To do anything rendering related with Impeller, you need a context.
Definition: context.h:46
std
Definition: comparable.h:95
impeller::BlendSelectValues::kHardLight
@ kHardLight
impeller::ContentContextOptions::sample_count
SampleCount sample_count
Definition: content_context.h:332
impeller::BlendSelectValues::kScreen
@ kScreen
impeller::DepthAttachmentDescriptor
Definition: formats.h:572
impeller::RenderTargetCache
An implementation of the [RenderTargetAllocator] that caches all allocated texture data for one frame...
Definition: render_target_cache.h:16
impeller::StencilAttachmentDescriptor
Definition: formats.h:592
impeller::BlendSelectValues::kLighten
@ kLighten
impeller::BlendMode::kSourceIn
@ kSourceIn
impeller::PipelineDescriptor::GetDepthStencilAttachmentDescriptor
std::optional< DepthAttachmentDescriptor > GetDepthStencilAttachmentDescriptor() const
Definition: pipeline_descriptor.cc:207
impeller::ContentContext::SetWireframe
void SetWireframe(bool wireframe)
Definition: content_context.cc:572
impeller::BlendSelectValues::kHue
@ kHue
impeller::SampleCount::kCount4
@ kCount4
impeller::PolygonMode::kLine
@ kLine
impeller::BlendSelectValues::kLuminosity
@ kLuminosity
impeller::PipelineDescriptor::SetDepthStencilAttachmentDescriptor
PipelineDescriptor & SetDepthStencilAttachmentDescriptor(std::optional< DepthAttachmentDescriptor > desc)
Definition: pipeline_descriptor.cc:151
impeller::ContentContextOptions::StencilMode::kCoverCompareInverted
@ kCoverCompareInverted
pipeline_descriptor.h
impeller::ContentContextOptions::StencilMode::kCoverCompare
@ kCoverCompare
impeller::ColorAttachmentDescriptor::color_blend_op
BlendOperation color_blend_op
Definition: formats.h:505
impeller::CompareFunction::kNotEqual
@ kNotEqual
Comparison test passes if new_value != current_value.
render_target.h
impeller::BlendMode::kXor
@ kXor
impeller::PipelineBuilder::MakeDefaultPipelineDescriptor
static std::optional< PipelineDescriptor > MakeDefaultPipelineDescriptor(const Context &context, const std::vector< Scalar > &constants={})
Create a default pipeline descriptor using the combination reflected shader information....
Definition: pipeline_builder.h:51
render_target_cache.h
impeller::BlendFactor::kSourceAlpha
@ kSourceAlpha
impeller::ContentContextOptions
Definition: content_context.h:288
impeller::LazyGlyphAtlas
Definition: lazy_glyph_atlas.h:18
impeller::PipelineDescriptor::ClearStencilAttachments
void ClearStencilAttachments()
Definition: pipeline_descriptor.cc:170
impeller::ContentContextOptions::StencilMode::kLegacyClipRestore
@ kLegacyClipRestore
Slice the clip heightmap to a new maximum height.
impeller::CompareFunction::kLess
@ kLess
Comparison test passes if new_value < current_value.
impeller
Definition: aiks_blur_unittests.cc:20
impeller::ContentContext::IsValid
bool IsValid() const
Definition: content_context.cc:474
impeller::BlendMode::kSourceATop
@ kSourceATop
impeller::ColorAttachmentDescriptor::blending_enabled
bool blending_enabled
Definition: formats.h:502
impeller::BlendSelectValues::kColorDodge
@ kColorDodge
impeller::CreateDefaultPipeline
static std::unique_ptr< PipelineT > CreateDefaultPipeline(const Context &context)
Definition: content_context.cc:232
impeller::BlendMode::kSourceOver
@ kSourceOver
impeller::BlendSelectValues::kOverlay
@ kOverlay
impeller::BlendFactor::kOneMinusDestinationAlpha
@ kOneMinusDestinationAlpha
impeller::DepthAttachmentDescriptor::depth_compare
CompareFunction depth_compare
Definition: formats.h:576
impeller::ColorAttachmentDescriptor
Describe the color attachment that will be used with this pipeline.
Definition: formats.h:500