| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef FLUTTER_IMPELLER_ENTITY_CONTENTS_CONTENT_CONTEXT_H_ |
| #define FLUTTER_IMPELLER_ENTITY_CONTENTS_CONTENT_CONTEXT_H_ |
| |
| #include <initializer_list> |
| #include <memory> |
| #include <optional> |
| #include <unordered_map> |
| |
| #include "flutter/fml/build_config.h" |
| #include "flutter/fml/logging.h" |
| #include "flutter/fml/status_or.h" |
| #include "impeller/base/validation.h" |
| #include "impeller/core/formats.h" |
| #include "impeller/core/host_buffer.h" |
| #include "impeller/entity/entity.h" |
| #include "impeller/renderer/capabilities.h" |
| #include "impeller/renderer/pipeline.h" |
| #include "impeller/renderer/pipeline_descriptor.h" |
| #include "impeller/renderer/render_target.h" |
| #include "impeller/typographer/typographer_context.h" |
| |
| #ifdef IMPELLER_DEBUG |
| #include "impeller/entity/checkerboard.frag.h" |
| #include "impeller/entity/checkerboard.vert.h" |
| #endif // IMPELLER_DEBUG |
| |
| #include "impeller/entity/blend.frag.h" |
| #include "impeller/entity/blend.vert.h" |
| #include "impeller/entity/border_mask_blur.frag.h" |
| #include "impeller/entity/border_mask_blur.vert.h" |
| #include "impeller/entity/clip.frag.h" |
| #include "impeller/entity/clip.vert.h" |
| #include "impeller/entity/color_matrix_color_filter.frag.h" |
| #include "impeller/entity/color_matrix_color_filter.vert.h" |
| #include "impeller/entity/conical_gradient_fill.frag.h" |
| #include "impeller/entity/glyph_atlas.frag.h" |
| #include "impeller/entity/glyph_atlas.vert.h" |
| #include "impeller/entity/glyph_atlas_color.frag.h" |
| #include "impeller/entity/gradient_fill.vert.h" |
| #include "impeller/entity/linear_gradient_fill.frag.h" |
| #include "impeller/entity/linear_to_srgb_filter.frag.h" |
| #include "impeller/entity/linear_to_srgb_filter.vert.h" |
| #include "impeller/entity/morphology_filter.frag.h" |
| #include "impeller/entity/morphology_filter.vert.h" |
| #include "impeller/entity/points.comp.h" |
| #include "impeller/entity/porter_duff_blend.frag.h" |
| #include "impeller/entity/porter_duff_blend.vert.h" |
| #include "impeller/entity/radial_gradient_fill.frag.h" |
| #include "impeller/entity/rrect_blur.frag.h" |
| #include "impeller/entity/rrect_blur.vert.h" |
| #include "impeller/entity/solid_fill.frag.h" |
| #include "impeller/entity/solid_fill.vert.h" |
| #include "impeller/entity/srgb_to_linear_filter.frag.h" |
| #include "impeller/entity/srgb_to_linear_filter.vert.h" |
| #include "impeller/entity/sweep_gradient_fill.frag.h" |
| #include "impeller/entity/texture_fill.frag.h" |
| #include "impeller/entity/texture_fill.vert.h" |
| #include "impeller/entity/tiled_texture_fill.frag.h" |
| #include "impeller/entity/uv.comp.h" |
| #include "impeller/entity/vertices.frag.h" |
| #include "impeller/entity/yuv_to_rgb_filter.frag.h" |
| #include "impeller/entity/yuv_to_rgb_filter.vert.h" |
| |
| #include "impeller/entity/gaussian_blur.vert.h" |
| #include "impeller/entity/gaussian_blur_noalpha_decal.frag.h" |
| #include "impeller/entity/gaussian_blur_noalpha_nodecal.frag.h" |
| #include "impeller/entity/kernel_decal.frag.h" |
| #include "impeller/entity/kernel_nodecal.frag.h" |
| |
| #include "impeller/entity/position_color.vert.h" |
| |
| #include "impeller/typographer/glyph_atlas.h" |
| |
| #include "impeller/entity/conical_gradient_ssbo_fill.frag.h" |
| #include "impeller/entity/linear_gradient_ssbo_fill.frag.h" |
| #include "impeller/entity/radial_gradient_ssbo_fill.frag.h" |
| #include "impeller/entity/sweep_gradient_ssbo_fill.frag.h" |
| |
| #include "impeller/entity/advanced_blend.frag.h" |
| #include "impeller/entity/advanced_blend.vert.h" |
| |
| #include "impeller/entity/framebuffer_blend.frag.h" |
| #include "impeller/entity/framebuffer_blend.vert.h" |
| |
| #ifdef IMPELLER_ENABLE_OPENGLES |
| #include "impeller/entity/texture_fill_external.frag.h" |
| #include "impeller/entity/tiled_texture_fill_external.frag.h" |
| #endif // IMPELLER_ENABLE_OPENGLES |
| |
| #if IMPELLER_ENABLE_3D |
| #include "impeller/scene/scene_context.h" // nogncheck |
| #endif |
| |
| namespace impeller { |
| |
| #ifdef IMPELLER_DEBUG |
| using CheckerboardPipeline = |
| RenderPipelineT<CheckerboardVertexShader, CheckerboardFragmentShader>; |
| #endif // IMPELLER_DEBUG |
| |
| using LinearGradientFillPipeline = |
| RenderPipelineT<GradientFillVertexShader, LinearGradientFillFragmentShader>; |
| using SolidFillPipeline = |
| RenderPipelineT<SolidFillVertexShader, SolidFillFragmentShader>; |
| using RadialGradientFillPipeline = |
| RenderPipelineT<GradientFillVertexShader, RadialGradientFillFragmentShader>; |
| using ConicalGradientFillPipeline = |
| RenderPipelineT<GradientFillVertexShader, |
| ConicalGradientFillFragmentShader>; |
| using SweepGradientFillPipeline = |
| RenderPipelineT<GradientFillVertexShader, SweepGradientFillFragmentShader>; |
| using LinearGradientSSBOFillPipeline = |
| RenderPipelineT<GradientFillVertexShader, |
| LinearGradientSsboFillFragmentShader>; |
| using ConicalGradientSSBOFillPipeline = |
| RenderPipelineT<GradientFillVertexShader, |
| ConicalGradientSsboFillFragmentShader>; |
| using RadialGradientSSBOFillPipeline = |
| RenderPipelineT<GradientFillVertexShader, |
| RadialGradientSsboFillFragmentShader>; |
| using SweepGradientSSBOFillPipeline = |
| RenderPipelineT<GradientFillVertexShader, |
| SweepGradientSsboFillFragmentShader>; |
| using RRectBlurPipeline = |
| RenderPipelineT<RrectBlurVertexShader, RrectBlurFragmentShader>; |
| using BlendPipeline = RenderPipelineT<BlendVertexShader, BlendFragmentShader>; |
| using TexturePipeline = |
| RenderPipelineT<TextureFillVertexShader, TextureFillFragmentShader>; |
| using PositionUVPipeline = |
| RenderPipelineT<TextureFillVertexShader, TiledTextureFillFragmentShader>; |
| using TiledTexturePipeline = |
| RenderPipelineT<TextureFillVertexShader, TiledTextureFillFragmentShader>; |
| using GaussianBlurDecalPipeline = |
| RenderPipelineT<GaussianBlurVertexShader, |
| GaussianBlurNoalphaDecalFragmentShader>; |
| using GaussianBlurPipeline = |
| RenderPipelineT<GaussianBlurVertexShader, |
| GaussianBlurNoalphaNodecalFragmentShader>; |
| using KernelDecalPipeline = |
| RenderPipelineT<GaussianBlurVertexShader, KernelDecalFragmentShader>; |
| using KernelPipeline = |
| RenderPipelineT<GaussianBlurVertexShader, KernelNodecalFragmentShader>; |
| using BorderMaskBlurPipeline = |
| RenderPipelineT<BorderMaskBlurVertexShader, BorderMaskBlurFragmentShader>; |
| using MorphologyFilterPipeline = |
| RenderPipelineT<MorphologyFilterVertexShader, |
| MorphologyFilterFragmentShader>; |
| using ColorMatrixColorFilterPipeline = |
| RenderPipelineT<ColorMatrixColorFilterVertexShader, |
| ColorMatrixColorFilterFragmentShader>; |
| using LinearToSrgbFilterPipeline = |
| RenderPipelineT<LinearToSrgbFilterVertexShader, |
| LinearToSrgbFilterFragmentShader>; |
| using SrgbToLinearFilterPipeline = |
| RenderPipelineT<SrgbToLinearFilterVertexShader, |
| SrgbToLinearFilterFragmentShader>; |
| using GlyphAtlasPipeline = |
| RenderPipelineT<GlyphAtlasVertexShader, GlyphAtlasFragmentShader>; |
| using GlyphAtlasColorPipeline = |
| RenderPipelineT<GlyphAtlasVertexShader, GlyphAtlasColorFragmentShader>; |
| using PorterDuffBlendPipeline = |
| RenderPipelineT<PorterDuffBlendVertexShader, PorterDuffBlendFragmentShader>; |
| // Instead of requiring new shaders for clips, the solid fill stages are used |
| // to redirect writing to the stencil instead of color attachments. |
| using ClipPipeline = RenderPipelineT<ClipVertexShader, ClipFragmentShader>; |
| |
| using GeometryColorPipeline = |
| RenderPipelineT<PositionColorVertexShader, VerticesFragmentShader>; |
| using YUVToRGBFilterPipeline = |
| RenderPipelineT<YuvToRgbFilterVertexShader, YuvToRgbFilterFragmentShader>; |
| |
| // Advanced blends |
| using BlendColorPipeline = |
| RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>; |
| using BlendColorBurnPipeline = |
| RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>; |
| using BlendColorDodgePipeline = |
| RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>; |
| using BlendDarkenPipeline = |
| RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>; |
| using BlendDifferencePipeline = |
| RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>; |
| using BlendExclusionPipeline = |
| RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>; |
| using BlendHardLightPipeline = |
| RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>; |
| using BlendHuePipeline = |
| RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>; |
| using BlendLightenPipeline = |
| RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>; |
| using BlendLuminosityPipeline = |
| RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>; |
| using BlendMultiplyPipeline = |
| RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>; |
| using BlendOverlayPipeline = |
| RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>; |
| using BlendSaturationPipeline = |
| RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>; |
| using BlendScreenPipeline = |
| RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>; |
| using BlendSoftLightPipeline = |
| RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>; |
| // Framebuffer Advanced Blends |
| using FramebufferBlendColorPipeline = |
| RenderPipelineT<FramebufferBlendVertexShader, |
| FramebufferBlendFragmentShader>; |
| using FramebufferBlendColorBurnPipeline = |
| RenderPipelineT<FramebufferBlendVertexShader, |
| FramebufferBlendFragmentShader>; |
| using FramebufferBlendColorDodgePipeline = |
| RenderPipelineT<FramebufferBlendVertexShader, |
| FramebufferBlendFragmentShader>; |
| using FramebufferBlendDarkenPipeline = |
| RenderPipelineT<FramebufferBlendVertexShader, |
| FramebufferBlendFragmentShader>; |
| using FramebufferBlendDifferencePipeline = |
| RenderPipelineT<FramebufferBlendVertexShader, |
| FramebufferBlendFragmentShader>; |
| using FramebufferBlendExclusionPipeline = |
| RenderPipelineT<FramebufferBlendVertexShader, |
| FramebufferBlendFragmentShader>; |
| using FramebufferBlendHardLightPipeline = |
| RenderPipelineT<FramebufferBlendVertexShader, |
| FramebufferBlendFragmentShader>; |
| using FramebufferBlendHuePipeline = |
| RenderPipelineT<FramebufferBlendVertexShader, |
| FramebufferBlendFragmentShader>; |
| using FramebufferBlendLightenPipeline = |
| RenderPipelineT<FramebufferBlendVertexShader, |
| FramebufferBlendFragmentShader>; |
| using FramebufferBlendLuminosityPipeline = |
| RenderPipelineT<FramebufferBlendVertexShader, |
| FramebufferBlendFragmentShader>; |
| using FramebufferBlendMultiplyPipeline = |
| RenderPipelineT<FramebufferBlendVertexShader, |
| FramebufferBlendFragmentShader>; |
| using FramebufferBlendOverlayPipeline = |
| RenderPipelineT<FramebufferBlendVertexShader, |
| FramebufferBlendFragmentShader>; |
| using FramebufferBlendSaturationPipeline = |
| RenderPipelineT<FramebufferBlendVertexShader, |
| FramebufferBlendFragmentShader>; |
| using FramebufferBlendScreenPipeline = |
| RenderPipelineT<FramebufferBlendVertexShader, |
| FramebufferBlendFragmentShader>; |
| using FramebufferBlendSoftLightPipeline = |
| RenderPipelineT<FramebufferBlendVertexShader, |
| FramebufferBlendFragmentShader>; |
| |
| /// Geometry Pipelines |
| using PointsComputeShaderPipeline = ComputePipelineBuilder<PointsComputeShader>; |
| using UvComputeShaderPipeline = ComputePipelineBuilder<UvComputeShader>; |
| |
| #ifdef IMPELLER_ENABLE_OPENGLES |
| using TextureExternalPipeline = |
| RenderPipelineT<TextureFillVertexShader, TextureFillExternalFragmentShader>; |
| |
| using TiledTextureExternalPipeline = |
| RenderPipelineT<TextureFillVertexShader, |
| TiledTextureFillExternalFragmentShader>; |
| #endif // IMPELLER_ENABLE_OPENGLES |
| |
| /// Pipeline state configuration. |
| /// |
| /// Each unique combination of these options requires a different pipeline state |
| /// object to be built. This struct is used as a key for the per-pipeline |
| /// variant cache. |
| /// |
| /// When adding fields to this key, reliant features should take care to limit |
| /// the combinatorical explosion of variations. A sufficiently complicated |
| /// Flutter application may easily require building hundreds of PSOs in total, |
| /// but they shouldn't require e.g. 10s of thousands. |
| struct ContentContextOptions { |
| SampleCount sample_count = SampleCount::kCount1; |
| BlendMode blend_mode = BlendMode::kSourceOver; |
| CompareFunction stencil_compare = CompareFunction::kEqual; |
| StencilOperation stencil_operation = StencilOperation::kKeep; |
| PrimitiveType primitive_type = PrimitiveType::kTriangle; |
| PixelFormat color_attachment_pixel_format = PixelFormat::kUnknown; |
| bool has_stencil_attachment = true; |
| bool wireframe = false; |
| bool is_for_rrect_blur_clear = false; |
| |
| struct Hash { |
| constexpr uint64_t operator()(const ContentContextOptions& o) const { |
| static_assert(sizeof(o.sample_count) == 1); |
| static_assert(sizeof(o.blend_mode) == 1); |
| static_assert(sizeof(o.sample_count) == 1); |
| static_assert(sizeof(o.stencil_compare) == 1); |
| static_assert(sizeof(o.stencil_operation) == 1); |
| static_assert(sizeof(o.primitive_type) == 1); |
| static_assert(sizeof(o.color_attachment_pixel_format) == 1); |
| |
| return (o.is_for_rrect_blur_clear ? 1llu : 0llu) << 0 | |
| (o.wireframe ? 1llu : 0llu) << 1 | |
| (o.has_stencil_attachment ? 1llu : 0llu) << 2 | |
| // enums |
| static_cast<uint64_t>(o.color_attachment_pixel_format) << 16 | |
| static_cast<uint64_t>(o.primitive_type) << 24 | |
| static_cast<uint64_t>(o.stencil_operation) << 32 | |
| static_cast<uint64_t>(o.stencil_compare) << 40 | |
| static_cast<uint64_t>(o.blend_mode) << 48 | |
| static_cast<uint64_t>(o.sample_count) << 56; |
| } |
| }; |
| |
| struct Equal { |
| constexpr bool operator()(const ContentContextOptions& lhs, |
| const ContentContextOptions& rhs) const { |
| return lhs.sample_count == rhs.sample_count && |
| lhs.blend_mode == rhs.blend_mode && |
| lhs.stencil_compare == rhs.stencil_compare && |
| lhs.stencil_operation == rhs.stencil_operation && |
| lhs.primitive_type == rhs.primitive_type && |
| lhs.color_attachment_pixel_format == |
| rhs.color_attachment_pixel_format && |
| lhs.has_stencil_attachment == rhs.has_stencil_attachment && |
| lhs.wireframe == rhs.wireframe && |
| lhs.is_for_rrect_blur_clear == rhs.is_for_rrect_blur_clear; |
| } |
| }; |
| |
| void ApplyToPipelineDescriptor(PipelineDescriptor& desc) const; |
| }; |
| |
| class Tessellator; |
| class RenderTargetCache; |
| |
| class ContentContext { |
| public: |
| explicit ContentContext( |
| std::shared_ptr<Context> context, |
| std::shared_ptr<TypographerContext> typographer_context, |
| std::shared_ptr<RenderTargetAllocator> render_target_allocator = nullptr); |
| |
| ~ContentContext(); |
| |
| bool IsValid() const; |
| |
| #if IMPELLER_ENABLE_3D |
| std::shared_ptr<scene::SceneContext> GetSceneContext() const; |
| #endif // IMPELLER_ENABLE_3D |
| |
| std::shared_ptr<Tessellator> GetTessellator() const; |
| |
| #ifdef IMPELLER_DEBUG |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetCheckerboardPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(checkerboard_pipelines_, opts); |
| } |
| #endif // IMPELLER_DEBUG |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetLinearGradientFillPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(linear_gradient_fill_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> |
| GetLinearGradientSSBOFillPipeline(ContentContextOptions opts) const { |
| FML_DCHECK(GetDeviceCapabilities().SupportsSSBO()); |
| return GetPipeline(linear_gradient_ssbo_fill_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> |
| GetRadialGradientSSBOFillPipeline(ContentContextOptions opts) const { |
| FML_DCHECK(GetDeviceCapabilities().SupportsSSBO()); |
| return GetPipeline(radial_gradient_ssbo_fill_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> |
| GetConicalGradientSSBOFillPipeline(ContentContextOptions opts) const { |
| FML_DCHECK(GetDeviceCapabilities().SupportsSSBO()); |
| return GetPipeline(conical_gradient_ssbo_fill_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> |
| GetSweepGradientSSBOFillPipeline(ContentContextOptions opts) const { |
| FML_DCHECK(GetDeviceCapabilities().SupportsSSBO()); |
| return GetPipeline(sweep_gradient_ssbo_fill_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetRadialGradientFillPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(radial_gradient_fill_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetConicalGradientFillPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(conical_gradient_fill_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetRRectBlurPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(rrect_blur_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetSweepGradientFillPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(sweep_gradient_fill_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetSolidFillPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(solid_fill_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(texture_blend_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetTexturePipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(texture_pipelines_, opts); |
| } |
| |
| #ifdef IMPELLER_ENABLE_OPENGLES |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetTextureExternalPipeline( |
| ContentContextOptions opts) const { |
| FML_DCHECK(GetContext()->GetBackendType() == |
| Context::BackendType::kOpenGLES); |
| return GetPipeline(texture_external_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetTiledTextureExternalPipeline( |
| ContentContextOptions opts) const { |
| FML_DCHECK(GetContext()->GetBackendType() == |
| Context::BackendType::kOpenGLES); |
| return GetPipeline(tiled_texture_external_pipelines_, opts); |
| } |
| #endif // IMPELLER_ENABLE_OPENGLES |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetPositionUVPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(position_uv_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetTiledTexturePipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(tiled_texture_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetGaussianBlurDecalPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(gaussian_blur_noalpha_decal_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetGaussianBlurPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(gaussian_blur_noalpha_nodecal_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetKernelDecalPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(kernel_decal_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetKernelPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(kernel_nodecal_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetBorderMaskBlurPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(border_mask_blur_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetMorphologyFilterPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(morphology_filter_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> |
| GetColorMatrixColorFilterPipeline(ContentContextOptions opts) const { |
| return GetPipeline(color_matrix_color_filter_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetLinearToSrgbFilterPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(linear_to_srgb_filter_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetSrgbToLinearFilterPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(srgb_to_linear_filter_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetClipPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(clip_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetGlyphAtlasPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(glyph_atlas_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetGlyphAtlasColorPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(glyph_atlas_color_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetGeometryColorPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(geometry_color_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetYUVToRGBFilterPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(yuv_to_rgb_filter_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetPorterDuffBlendPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(porter_duff_blend_pipelines_, opts); |
| } |
| |
| // Advanced blends. |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendColorPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(blend_color_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendColorBurnPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(blend_colorburn_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendColorDodgePipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(blend_colordodge_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendDarkenPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(blend_darken_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendDifferencePipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(blend_difference_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendExclusionPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(blend_exclusion_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendHardLightPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(blend_hardlight_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendHuePipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(blend_hue_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendLightenPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(blend_lighten_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendLuminosityPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(blend_luminosity_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendMultiplyPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(blend_multiply_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendOverlayPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(blend_overlay_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendSaturationPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(blend_saturation_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendScreenPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(blend_screen_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendSoftLightPipeline( |
| ContentContextOptions opts) const { |
| return GetPipeline(blend_softlight_pipelines_, opts); |
| } |
| |
| // Framebuffer Advanced Blends |
| std::shared_ptr<Pipeline<PipelineDescriptor>> |
| GetFramebufferBlendColorPipeline(ContentContextOptions opts) const { |
| FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); |
| return GetPipeline(framebuffer_blend_color_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> |
| GetFramebufferBlendColorBurnPipeline(ContentContextOptions opts) const { |
| FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); |
| return GetPipeline(framebuffer_blend_colorburn_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> |
| GetFramebufferBlendColorDodgePipeline(ContentContextOptions opts) const { |
| FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); |
| return GetPipeline(framebuffer_blend_colordodge_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> |
| GetFramebufferBlendDarkenPipeline(ContentContextOptions opts) const { |
| FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); |
| return GetPipeline(framebuffer_blend_darken_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> |
| GetFramebufferBlendDifferencePipeline(ContentContextOptions opts) const { |
| FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); |
| return GetPipeline(framebuffer_blend_difference_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> |
| GetFramebufferBlendExclusionPipeline(ContentContextOptions opts) const { |
| FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); |
| return GetPipeline(framebuffer_blend_exclusion_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> |
| GetFramebufferBlendHardLightPipeline(ContentContextOptions opts) const { |
| FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); |
| return GetPipeline(framebuffer_blend_hardlight_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetFramebufferBlendHuePipeline( |
| ContentContextOptions opts) const { |
| FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); |
| return GetPipeline(framebuffer_blend_hue_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> |
| GetFramebufferBlendLightenPipeline(ContentContextOptions opts) const { |
| FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); |
| return GetPipeline(framebuffer_blend_lighten_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> |
| GetFramebufferBlendLuminosityPipeline(ContentContextOptions opts) const { |
| FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); |
| return GetPipeline(framebuffer_blend_luminosity_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> |
| GetFramebufferBlendMultiplyPipeline(ContentContextOptions opts) const { |
| FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); |
| return GetPipeline(framebuffer_blend_multiply_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> |
| GetFramebufferBlendOverlayPipeline(ContentContextOptions opts) const { |
| FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); |
| return GetPipeline(framebuffer_blend_overlay_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> |
| GetFramebufferBlendSaturationPipeline(ContentContextOptions opts) const { |
| FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); |
| return GetPipeline(framebuffer_blend_saturation_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> |
| GetFramebufferBlendScreenPipeline(ContentContextOptions opts) const { |
| FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); |
| return GetPipeline(framebuffer_blend_screen_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<PipelineDescriptor>> |
| GetFramebufferBlendSoftLightPipeline(ContentContextOptions opts) const { |
| FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); |
| return GetPipeline(framebuffer_blend_softlight_pipelines_, opts); |
| } |
| |
| std::shared_ptr<Pipeline<ComputePipelineDescriptor>> GetPointComputePipeline() |
| const { |
| FML_DCHECK(GetDeviceCapabilities().SupportsCompute()); |
| return point_field_compute_pipelines_; |
| } |
| |
| std::shared_ptr<Pipeline<ComputePipelineDescriptor>> GetUvComputePipeline() |
| const { |
| FML_DCHECK(GetDeviceCapabilities().SupportsCompute()); |
| return uv_compute_pipelines_; |
| } |
| |
| std::shared_ptr<Context> GetContext() const; |
| |
| const Capabilities& GetDeviceCapabilities() const; |
| |
| void SetWireframe(bool wireframe); |
| |
| using SubpassCallback = |
| std::function<bool(const ContentContext&, RenderPass&)>; |
| |
| /// @brief Creates a new texture of size `texture_size` and calls |
| /// `subpass_callback` with a `RenderPass` for drawing to the texture. |
| fml::StatusOr<RenderTarget> MakeSubpass( |
| const std::string& label, |
| ISize texture_size, |
| const SubpassCallback& subpass_callback, |
| bool msaa_enabled = true) const; |
| |
| /// Makes a subpass that will render to `subpass_target`. |
| fml::StatusOr<RenderTarget> MakeSubpass( |
| const std::string& label, |
| const RenderTarget& subpass_target, |
| const SubpassCallback& subpass_callback) const; |
| |
| std::shared_ptr<LazyGlyphAtlas> GetLazyGlyphAtlas() const { |
| return lazy_glyph_atlas_; |
| } |
| |
| std::shared_ptr<RenderTargetAllocator> GetRenderTargetCache() const { |
| return render_target_cache_; |
| } |
| |
| /// RuntimeEffect pipelines must be obtained via this method to avoid |
| /// re-creating them every frame. |
| /// |
| /// The unique_entrypoint_name comes from RuntimeEffect::GetEntrypoint. |
| /// Impellerc generates a unique entrypoint name for runtime effect shaders |
| /// based on the input file name and shader stage. |
| /// |
| /// The create_callback is synchronously invoked exactly once if a cached |
| /// pipeline is not found. |
| 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; |
| |
| /// @brief Retrieve the currnent host buffer for transient storage. |
| /// |
| /// This is only safe to use from the raster threads. Other threads should |
| /// allocate their own device buffers. |
| HostBuffer& GetTransientsBuffer() const { return *host_buffer_; } |
| |
| private: |
| std::shared_ptr<Context> context_; |
| std::shared_ptr<LazyGlyphAtlas> lazy_glyph_atlas_; |
| |
| struct RuntimeEffectPipelineKey { |
| std::string unique_entrypoint_name; |
| ContentContextOptions options; |
| |
| struct Hash { |
| std::size_t operator()(const RuntimeEffectPipelineKey& key) const { |
| return fml::HashCombine(key.unique_entrypoint_name, |
| ContentContextOptions::Hash{}(key.options)); |
| } |
| }; |
| |
| struct Equal { |
| constexpr bool operator()(const RuntimeEffectPipelineKey& lhs, |
| const RuntimeEffectPipelineKey& rhs) const { |
| return lhs.unique_entrypoint_name == rhs.unique_entrypoint_name && |
| ContentContextOptions::Equal{}(lhs.options, rhs.options); |
| } |
| }; |
| }; |
| |
| mutable std::unordered_map<RuntimeEffectPipelineKey, |
| std::shared_ptr<Pipeline<PipelineDescriptor>>, |
| RuntimeEffectPipelineKey::Hash, |
| RuntimeEffectPipelineKey::Equal> |
| runtime_effect_pipelines_; |
| |
| template <class PipelineT> |
| class Variants { |
| public: |
| Variants() = default; |
| |
| void Set(const ContentContextOptions& options, |
| std::unique_ptr<PipelineT> pipeline) { |
| pipelines_[options] = std::move(pipeline); |
| } |
| |
| void SetDefault(const ContentContextOptions& options, |
| std::unique_ptr<PipelineT> pipeline) { |
| default_options_ = options; |
| Set(options, std::move(pipeline)); |
| } |
| |
| void CreateDefault(const Context& context, |
| const ContentContextOptions& options, |
| const std::initializer_list<Scalar>& constants = {}, |
| UseSubpassInput subpass_input = UseSubpassInput::kNo) { |
| auto desc = |
| PipelineT::Builder::MakeDefaultPipelineDescriptor(context, constants); |
| if (!desc.has_value()) { |
| VALIDATION_LOG << "Failed to create default pipeline."; |
| return; |
| } |
| desc->SetUseSubpassInput(subpass_input); |
| options.ApplyToPipelineDescriptor(*desc); |
| SetDefault(options, std::make_unique<PipelineT>(context, desc)); |
| } |
| |
| PipelineT* Get(const ContentContextOptions& options) const { |
| if (auto found = pipelines_.find(options); found != pipelines_.end()) { |
| return found->second.get(); |
| } |
| return nullptr; |
| } |
| |
| PipelineT* GetDefault() const { |
| if (!default_options_.has_value()) { |
| return nullptr; |
| } |
| return Get(default_options_.value()); |
| } |
| |
| size_t GetPipelineCount() const { return pipelines_.size(); } |
| |
| private: |
| std::optional<ContentContextOptions> default_options_; |
| std::unordered_map<ContentContextOptions, |
| std::unique_ptr<PipelineT>, |
| ContentContextOptions::Hash, |
| ContentContextOptions::Equal> |
| pipelines_; |
| |
| Variants(const Variants&) = delete; |
| |
| Variants& operator=(const Variants&) = delete; |
| }; |
| |
| // These are mutable because while the prototypes are created eagerly, any |
| // variants requested from that are lazily created and cached in the variants |
| // map. |
| |
| #ifdef IMPELLER_DEBUG |
| mutable Variants<CheckerboardPipeline> checkerboard_pipelines_; |
| #endif // IMPELLER_DEBUG |
| |
| mutable Variants<SolidFillPipeline> solid_fill_pipelines_; |
| mutable Variants<LinearGradientFillPipeline> linear_gradient_fill_pipelines_; |
| mutable Variants<RadialGradientFillPipeline> radial_gradient_fill_pipelines_; |
| mutable Variants<ConicalGradientFillPipeline> |
| conical_gradient_fill_pipelines_; |
| mutable Variants<SweepGradientFillPipeline> sweep_gradient_fill_pipelines_; |
| mutable Variants<LinearGradientSSBOFillPipeline> |
| linear_gradient_ssbo_fill_pipelines_; |
| mutable Variants<RadialGradientSSBOFillPipeline> |
| radial_gradient_ssbo_fill_pipelines_; |
| mutable Variants<ConicalGradientSSBOFillPipeline> |
| conical_gradient_ssbo_fill_pipelines_; |
| mutable Variants<SweepGradientSSBOFillPipeline> |
| sweep_gradient_ssbo_fill_pipelines_; |
| mutable Variants<RRectBlurPipeline> rrect_blur_pipelines_; |
| mutable Variants<BlendPipeline> texture_blend_pipelines_; |
| mutable Variants<TexturePipeline> texture_pipelines_; |
| #ifdef IMPELLER_ENABLE_OPENGLES |
| mutable Variants<TextureExternalPipeline> texture_external_pipelines_; |
| mutable Variants<TiledTextureExternalPipeline> |
| tiled_texture_external_pipelines_; |
| #endif // IMPELLER_ENABLE_OPENGLES |
| mutable Variants<PositionUVPipeline> position_uv_pipelines_; |
| mutable Variants<TiledTexturePipeline> tiled_texture_pipelines_; |
| mutable Variants<GaussianBlurDecalPipeline> |
| gaussian_blur_noalpha_decal_pipelines_; |
| mutable Variants<GaussianBlurPipeline> |
| gaussian_blur_noalpha_nodecal_pipelines_; |
| mutable Variants<KernelDecalPipeline> kernel_decal_pipelines_; |
| mutable Variants<KernelPipeline> kernel_nodecal_pipelines_; |
| mutable Variants<BorderMaskBlurPipeline> border_mask_blur_pipelines_; |
| mutable Variants<MorphologyFilterPipeline> morphology_filter_pipelines_; |
| mutable Variants<ColorMatrixColorFilterPipeline> |
| color_matrix_color_filter_pipelines_; |
| mutable Variants<LinearToSrgbFilterPipeline> linear_to_srgb_filter_pipelines_; |
| mutable Variants<SrgbToLinearFilterPipeline> srgb_to_linear_filter_pipelines_; |
| mutable Variants<ClipPipeline> clip_pipelines_; |
| mutable Variants<GlyphAtlasPipeline> glyph_atlas_pipelines_; |
| mutable Variants<GlyphAtlasColorPipeline> glyph_atlas_color_pipelines_; |
| mutable Variants<GeometryColorPipeline> geometry_color_pipelines_; |
| mutable Variants<YUVToRGBFilterPipeline> yuv_to_rgb_filter_pipelines_; |
| mutable Variants<PorterDuffBlendPipeline> porter_duff_blend_pipelines_; |
| // Advanced blends. |
| mutable Variants<BlendColorPipeline> blend_color_pipelines_; |
| mutable Variants<BlendColorBurnPipeline> blend_colorburn_pipelines_; |
| mutable Variants<BlendColorDodgePipeline> blend_colordodge_pipelines_; |
| mutable Variants<BlendDarkenPipeline> blend_darken_pipelines_; |
| mutable Variants<BlendDifferencePipeline> blend_difference_pipelines_; |
| mutable Variants<BlendExclusionPipeline> blend_exclusion_pipelines_; |
| mutable Variants<BlendHardLightPipeline> blend_hardlight_pipelines_; |
| mutable Variants<BlendHuePipeline> blend_hue_pipelines_; |
| mutable Variants<BlendLightenPipeline> blend_lighten_pipelines_; |
| mutable Variants<BlendLuminosityPipeline> blend_luminosity_pipelines_; |
| mutable Variants<BlendMultiplyPipeline> blend_multiply_pipelines_; |
| mutable Variants<BlendOverlayPipeline> blend_overlay_pipelines_; |
| mutable Variants<BlendSaturationPipeline> blend_saturation_pipelines_; |
| mutable Variants<BlendScreenPipeline> blend_screen_pipelines_; |
| mutable Variants<BlendSoftLightPipeline> blend_softlight_pipelines_; |
| // Framebuffer Advanced blends. |
| mutable Variants<FramebufferBlendColorPipeline> |
| framebuffer_blend_color_pipelines_; |
| mutable Variants<FramebufferBlendColorBurnPipeline> |
| framebuffer_blend_colorburn_pipelines_; |
| mutable Variants<FramebufferBlendColorDodgePipeline> |
| framebuffer_blend_colordodge_pipelines_; |
| mutable Variants<FramebufferBlendDarkenPipeline> |
| framebuffer_blend_darken_pipelines_; |
| mutable Variants<FramebufferBlendDifferencePipeline> |
| framebuffer_blend_difference_pipelines_; |
| mutable Variants<FramebufferBlendExclusionPipeline> |
| framebuffer_blend_exclusion_pipelines_; |
| mutable Variants<FramebufferBlendHardLightPipeline> |
| framebuffer_blend_hardlight_pipelines_; |
| mutable Variants<FramebufferBlendHuePipeline> |
| framebuffer_blend_hue_pipelines_; |
| mutable Variants<FramebufferBlendLightenPipeline> |
| framebuffer_blend_lighten_pipelines_; |
| mutable Variants<FramebufferBlendLuminosityPipeline> |
| framebuffer_blend_luminosity_pipelines_; |
| mutable Variants<FramebufferBlendMultiplyPipeline> |
| framebuffer_blend_multiply_pipelines_; |
| mutable Variants<FramebufferBlendOverlayPipeline> |
| framebuffer_blend_overlay_pipelines_; |
| mutable Variants<FramebufferBlendSaturationPipeline> |
| framebuffer_blend_saturation_pipelines_; |
| mutable Variants<FramebufferBlendScreenPipeline> |
| framebuffer_blend_screen_pipelines_; |
| mutable Variants<FramebufferBlendSoftLightPipeline> |
| framebuffer_blend_softlight_pipelines_; |
| mutable std::shared_ptr<Pipeline<ComputePipelineDescriptor>> |
| point_field_compute_pipelines_; |
| mutable std::shared_ptr<Pipeline<ComputePipelineDescriptor>> |
| uv_compute_pipelines_; |
| |
| template <class TypedPipeline> |
| std::shared_ptr<Pipeline<PipelineDescriptor>> GetPipeline( |
| Variants<TypedPipeline>& container, |
| ContentContextOptions opts) const { |
| if (!IsValid()) { |
| return nullptr; |
| } |
| |
| if (wireframe_) { |
| opts.wireframe = true; |
| } |
| |
| if (auto found = container.Get(opts)) { |
| return found->WaitAndGet(); |
| } |
| |
| auto prototype = container.GetDefault(); |
| |
| // The prototype must always be initialized in the constructor. |
| FML_CHECK(prototype != nullptr); |
| |
| auto pipeline = prototype->WaitAndGet(); |
| if (!pipeline) { |
| return nullptr; |
| } |
| |
| auto variant_future = pipeline->CreateVariant( |
| [&opts, variants_count = |
| container.GetPipelineCount()](PipelineDescriptor& desc) { |
| opts.ApplyToPipelineDescriptor(desc); |
| desc.SetLabel( |
| SPrintF("%s V#%zu", desc.GetLabel().c_str(), variants_count)); |
| }); |
| auto variant = std::make_unique<TypedPipeline>(std::move(variant_future)); |
| auto variant_pipeline = variant->WaitAndGet(); |
| container.Set(opts, std::move(variant)); |
| return variant_pipeline; |
| } |
| |
| bool is_valid_ = false; |
| std::shared_ptr<Tessellator> tessellator_; |
| #if IMPELLER_ENABLE_3D |
| std::shared_ptr<scene::SceneContext> scene_context_; |
| #endif // IMPELLER_ENABLE_3D |
| std::shared_ptr<RenderTargetAllocator> render_target_cache_; |
| std::shared_ptr<HostBuffer> host_buffer_; |
| bool wireframe_ = false; |
| |
| ContentContext(const ContentContext&) = delete; |
| |
| ContentContext& operator=(const ContentContext&) = delete; |
| }; |
| |
| } // namespace impeller |
| |
| #endif // FLUTTER_IMPELLER_ENTITY_CONTENTS_CONTENT_CONTEXT_H_ |