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