Flutter Engine
The Flutter Engine
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
15
16namespace impeller {
17namespace scene {
18
22
23 struct Hash {
24 constexpr std::size_t operator()(const SceneContextOptions& o) const {
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 &&
34 }
35 };
36
37 void ApplyToPipelineDescriptor(const Capabilities& capabilities,
39};
40
42 public:
43 explicit SceneContext(std::shared_ptr<Context> context);
44
46
47 bool IsValid() const;
48
49 std::shared_ptr<Pipeline<PipelineDescriptor>> GetPipeline(
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>,
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>,
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_
To do anything rendering related with Impeller, you need a context.
Definition: context.h:45
virtual const std::shared_ptr< const Capabilities > & GetCapabilities() const =0
Get the capabilities of Impeller context. All optionally supported feature of the platform,...
std::shared_ptr< Context > GetContext() const
SceneContext(std::shared_ptr< Context > context)
std::shared_ptr< Pipeline< PipelineDescriptor > > GetPipeline(PipelineKey key, SceneContextOptions opts) const
std::shared_ptr< Texture > GetPlaceholderTexture() const
HostBuffer & GetTransientsBuffer() const
Definition: scene_context.h:57
#define FML_CHECK(condition)
Definition: logging.h:85
static uint32_t Hash(uint32_t key)
Definition: hashmap_test.cc:65
constexpr std::size_t HashCombine()
Definition: hash_combine.h:25
PrimitiveType
Decides how backend draws pixels based on input vertices.
Definition: formats.h:352
SampleCount
Definition: formats.h:295
constexpr bool operator()(const SceneContextOptions &lhs, const SceneContextOptions &rhs) const
Definition: scene_context.h:30
constexpr std::size_t operator()(const SceneContextOptions &o) const
Definition: scene_context.h:24
void ApplyToPipelineDescriptor(const Capabilities &capabilities, PipelineDescriptor &desc) const