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 
14 
15 namespace impeller {
16 namespace scene {
17 
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.
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>,
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>,
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