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 
15 
16 namespace impeller {
17 namespace scene {
18 
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  [&context, &opts,
100  variants_count = variants_.size()](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<RenderPipelineT<VertexShader, FragmentShader>>(
129  context);
130  if (!pipeline.IsValid()) {
131  return nullptr;
132  }
133  return std::make_unique<
134  PipelineVariantsT<RenderPipelineT<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: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:30
impeller::PrimitiveType
PrimitiveType
Decides how backend draws pixels based on input vertices.
Definition: formats.h:353
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:46
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:296
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_blur_unittests.cc:20