| Flutter Impeller |

scene_context.h
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 #ifndef FLUTTER_IMPELLER_SCENE_SCENE_CONTEXT_H_
6 #define FLUTTER_IMPELLER_SCENE_SCENE_CONTEXT_H_
7
8 #include <memory>
9
10 #include "impeller/renderer/context.h"
11 #include "impeller/renderer/pipeline.h"
12 #include "impeller/renderer/pipeline_descriptor.h"
13 #include "impeller/scene/pipeline_key.h"
14
15 namespace impeller {
16 namespace scene {
17
18 struct SceneContextOptions {
19 SampleCount sample_count = SampleCount::kCount1;
20 PrimitiveType primitive_type = PrimitiveType::kTriangle;
21
22 struct Hash {
23 constexpr std::size_t operator()(const SceneContextOptions& o) const {
24 return fml::HashCombine(o.sample_count, o.primitive_type);
25 }
26 };
27
28 struct Equal {
29 constexpr bool operator()(const SceneContextOptions& lhs,
30 const SceneContextOptions& rhs) const {
31 return lhs.sample_count == rhs.sample_count &&
32 lhs.primitive_type == rhs.primitive_type;
33 }
34 };
35
36 void ApplyToPipelineDescriptor(const Capabilities& capabilities,
37 PipelineDescriptor& desc) const;
38 };
39
40 class SceneContext {
41 public:
42 explicit SceneContext(std::shared_ptr<Context> context);
43
44 ~SceneContext();
45
46 bool IsValid() const;
47
48 std::shared_ptr<Pipeline<PipelineDescriptor>> GetPipeline(
49 PipelineKey key,
50 SceneContextOptions opts) const;
51
52 std::shared_ptr<Context> GetContext() const;
53
54 std::shared_ptr<Texture> GetPlaceholderTexture() const;
55
56 private:
57 class PipelineVariants {
58 public:
59 virtual ~PipelineVariants() = default;
60
61 virtual std::shared_ptr<Pipeline<PipelineDescriptor>> GetPipeline(
62 Context& context,
63 SceneContextOptions opts) = 0;
64 };
65
66 template <class PipelineT>
67 class PipelineVariantsT final : public PipelineVariants {
68 public:
69 explicit PipelineVariantsT(Context& context) {
70 auto desc = PipelineT::Builder::MakeDefaultPipelineDescriptor(context);
71 if (!desc.has_value()) {
72 is_valid_ = false;
73 return;
74 }
75 // Apply default ContentContextOptions to the descriptor.
76 SceneContextOptions{}.ApplyToPipelineDescriptor(
77 /*capabilities=*/*context.GetCapabilities(),
78 /*desc=*/desc.value());
79 variants_[{}] = std::make_unique<PipelineT>(context, desc);
80 };
81
82 // |PipelineVariants|
83 std::shared_ptr<Pipeline<PipelineDescriptor>> GetPipeline(
84 Context& context,
85 SceneContextOptions opts) {
86 if (auto found = variants_.find(opts); found != variants_.end()) {
87 return found->second->WaitAndGet();
88 }
89
90 auto prototype = variants_.find({});
91
92 // The prototype must always be initialized in the constructor.
93 FML_CHECK(prototype != variants_.end());
94
95 auto variant_future = prototype->second->WaitAndGet()->CreateVariant(
96 [&context, &opts,
97 variants_count = variants_.size()](PipelineDescriptor& desc) {
98 opts.ApplyToPipelineDescriptor(*context.GetCapabilities(), desc);
99 desc.SetLabel(
100 SPrintF("%s V#%zu", desc.GetLabel().c_str(), variants_count));
101 });
102 auto variant = std::make_unique<PipelineT>(std::move(variant_future));
103 auto variant_pipeline = variant->WaitAndGet();
104 variants_[opts] = std::move(variant);
105 return variant_pipeline;
106 }
107
108 bool IsValid() const { return is_valid_; }
109
110 private:
111 bool is_valid_ = true;
112 std::unordered_map<SceneContextOptions,
113 std::unique_ptr<PipelineT>,
114 SceneContextOptions::Hash,
115 SceneContextOptions::Equal>
116 variants_;
117 };
118
119 template <typename VertexShader, typename FragmentShader>
120 /// Creates a PipelineVariantsT for the given vertex and fragment shaders.
121 ///
122 /// If a pipeline could not be created, returns nullptr.
123 std::unique_ptr<PipelineVariants> MakePipelineVariants(Context& context) {
124 auto pipeline =
125 PipelineVariantsT<RenderPipelineT<VertexShader, FragmentShader>>(
126 context);
127 if (!pipeline.IsValid()) {
128 return nullptr;
129 }
130 return std::make_unique<
131 PipelineVariantsT<RenderPipelineT<VertexShader, FragmentShader>>>(
132 std::move(pipeline));
133 }
134
135 std::unordered_map<PipelineKey,
136 std::unique_ptr<PipelineVariants>,
137 PipelineKey::Hash,
138 PipelineKey::Equal>
139 pipelines_;
140
141 std::shared_ptr<Context> context_;
142
143 bool is_valid_ = false;
144 // A 1x1 opaque white texture that can be used as a placeholder binding.
145 // Available for the lifetime of the scene context
146 std::shared_ptr<Texture> placeholder_texture_;
147
148 SceneContext(const SceneContext&) = delete;
149
150 SceneContext& operator=(const SceneContext&) = delete;
151 };
152
153 } // namespace scene
154 } // namespace impeller
155
156 #endif // FLUTTER_IMPELLER_SCENE_SCENE_CONTEXT_H_
impeller::PipelineDescriptor
Definition: pipeline_descriptor.h:29
pipeline_key.h
pipeline.h
impeller::scene::SceneContextOptions::sample_count
SampleCount sample_count
Definition: scene_context.h:19
impeller::scene::SceneContext::SceneContext
SceneContext(std::shared_ptr< Context > context)
Definition: scene_context.cc:37
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::scene::SceneContextOptions::primitive_type
PrimitiveType primitive_type
Definition: scene_context.h:20
impeller::scene::SceneContext::GetPlaceholderTexture
std::shared_ptr< Texture > GetPlaceholderTexture() const
Definition: scene_context.cc:109
impeller::scene::PipelineKey::Hash
Definition: pipeline_key.h:27
impeller::scene::SceneContext
Definition: scene_context.h:40
impeller::scene::SceneContext::~SceneContext
~SceneContext()
impeller::scene::SceneContext::IsValid
bool IsValid() const
Definition: scene_context.cc:101
impeller::scene::SceneContextOptions
Definition: scene_context.h:18
impeller::PrimitiveType::kTriangle
@ kTriangle
impeller::Capabilities
Definition: capabilities.h:15
impeller::scene::PipelineKey
Definition: pipeline_key.h:23
impeller::scene::SceneContextOptions::Equal::operator()
constexpr bool operator()(const SceneContextOptions &lhs, const SceneContextOptions &rhs) const
Definition: scene_context.h:29
impeller::PrimitiveType
PrimitiveType
Decides how backend draws pixels based on input vertices.
Definition: formats.h:350
impeller::scene::SceneContextOptions::Equal
Definition: scene_context.h:28
impeller::scene::PipelineKey::Equal
Definition: pipeline_key.h:33
impeller::Context
To do anything rendering related with Impeller, you need a context.
Definition: context.h:47
impeller::scene::SceneContextOptions::Hash
Definition: scene_context.h:22
impeller::scene::SceneContext::GetContext
std::shared_ptr< Context > GetContext() const
Definition: scene_context.cc:105
impeller::SampleCount
SampleCount
Definition: formats.h:290
impeller::scene::SceneContext::GetPipeline
std::shared_ptr< Pipeline< PipelineDescriptor > > GetPipeline(PipelineKey key, SceneContextOptions opts) const
Definition: scene_context.cc:89
context.h
impeller::SampleCount::kCount1
@ kCount1
pipeline_descriptor.h
impeller::scene::SceneContextOptions::Hash::operator()
constexpr std::size_t operator()(const SceneContextOptions &o) const
Definition: scene_context.h:23
impeller::scene::SceneContextOptions::ApplyToPipelineDescriptor
void ApplyToPipelineDescriptor(const Capabilities &capabilities, PipelineDescriptor &desc) const
Definition: scene_context.cc:15
impeller
Definition: aiks_context.cc:10