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 #pragma once
6 
7 #include <memory>
8 
13 
14 namespace impeller {
15 namespace scene {
16 
20 
21  struct Hash {
22  constexpr std::size_t operator()(const SceneContextOptions& o) const {
23  return fml::HashCombine(o.sample_count, o.primitive_type);
24  }
25  };
26 
27  struct Equal {
28  constexpr bool operator()(const SceneContextOptions& lhs,
29  const SceneContextOptions& rhs) const {
30  return lhs.sample_count == rhs.sample_count &&
31  lhs.primitive_type == rhs.primitive_type;
32  }
33  };
34 
35  void ApplyToPipelineDescriptor(const Capabilities& capabilities,
36  PipelineDescriptor& desc) const;
37 };
38 
39 class SceneContext {
40  public:
41  explicit SceneContext(std::shared_ptr<Context> context);
42 
43  ~SceneContext();
44 
45  bool IsValid() const;
46 
47  std::shared_ptr<Pipeline<PipelineDescriptor>> GetPipeline(
48  PipelineKey key,
49  SceneContextOptions opts) const;
50 
51  std::shared_ptr<Context> GetContext() const;
52 
53  std::shared_ptr<Texture> GetPlaceholderTexture() const;
54 
55  private:
56  class PipelineVariants {
57  public:
58  virtual ~PipelineVariants() = default;
59 
60  virtual std::shared_ptr<Pipeline<PipelineDescriptor>> GetPipeline(
61  Context& context,
62  SceneContextOptions opts) = 0;
63  };
64 
65  template <class PipelineT>
66  class PipelineVariantsT final : public PipelineVariants {
67  public:
68  explicit PipelineVariantsT(Context& context) {
69  auto desc = PipelineT::Builder::MakeDefaultPipelineDescriptor(context);
70  // Apply default ContentContextOptions to the descriptor.
72  *context.GetCapabilities(), *desc);
73  variants_[{}] = std::make_unique<PipelineT>(context, desc);
74  };
75 
76  // |PipelineVariants|
77  std::shared_ptr<Pipeline<PipelineDescriptor>> GetPipeline(
78  Context& context,
79  SceneContextOptions opts) {
80  if (auto found = variants_.find(opts); found != variants_.end()) {
81  return found->second->WaitAndGet();
82  }
83 
84  auto prototype = variants_.find({});
85 
86  // The prototype must always be initialized in the constructor.
87  FML_CHECK(prototype != variants_.end());
88 
89  auto variant_future = prototype->second->WaitAndGet()->CreateVariant(
90  [&context, &opts,
91  variants_count = variants_.size()](PipelineDescriptor& desc) {
92  opts.ApplyToPipelineDescriptor(*context.GetCapabilities(), desc);
93  desc.SetLabel(
94  SPrintF("%s V#%zu", desc.GetLabel().c_str(), variants_count));
95  });
96  auto variant = std::make_unique<PipelineT>(std::move(variant_future));
97  auto variant_pipeline = variant->WaitAndGet();
98  variants_[opts] = std::move(variant);
99  return variant_pipeline;
100  }
101 
102  private:
103  std::unordered_map<SceneContextOptions,
104  std::unique_ptr<PipelineT>,
107  variants_;
108  };
109 
110  template <typename VertexShader, typename FragmentShader>
111  std::unique_ptr<PipelineVariants> MakePipelineVariants(Context& context) {
112  return std::make_unique<
113  PipelineVariantsT<RenderPipelineT<VertexShader, FragmentShader>>>(
114  context);
115  }
116 
117  std::unordered_map<PipelineKey,
118  std::unique_ptr<PipelineVariants>,
121  pipelines_;
122 
123  std::shared_ptr<Context> context_;
124 
125  bool is_valid_ = false;
126  // A 1x1 opaque white texture that can be used as a placeholder binding.
127  // Available for the lifetime of the scene context
128  std::shared_ptr<Texture> placeholder_texture_;
129 
130  FML_DISALLOW_COPY_AND_ASSIGN(SceneContext);
131 };
132 
133 } // namespace scene
134 } // namespace impeller
impeller::PipelineDescriptor
Definition: pipeline_descriptor.h:30
pipeline_key.h
pipeline.h
impeller::PrimitiveType
PrimitiveType
Definition: formats.h:328
impeller::scene::SceneContextOptions::sample_count
SampleCount sample_count
Definition: scene_context.h:18
impeller::SampleCount
SampleCount
Definition: formats.h:269
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:19
impeller::SampleCount::kCount1
@ kCount1
impeller::scene::SceneContext::GetPlaceholderTexture
std::shared_ptr< Texture > GetPlaceholderTexture() const
Definition: scene_context.cc:96
impeller::scene::PipelineKey::Hash
Definition: pipeline_key.h:26
impeller::scene::SceneContext
Definition: scene_context.h:39
impeller::scene::SceneContext::~SceneContext
~SceneContext()
impeller::scene::SceneContext::IsValid
bool IsValid() const
Definition: scene_context.cc:88
impeller::scene::SceneContextOptions
Definition: scene_context.h:17
impeller::Capabilities
Definition: capabilities.h:14
impeller::scene::PipelineKey
Definition: pipeline_key.h:22
impeller::scene::SceneContextOptions::Equal::operator()
constexpr bool operator()(const SceneContextOptions &lhs, const SceneContextOptions &rhs) const
Definition: scene_context.h:28
impeller::scene::SceneContextOptions::Equal
Definition: scene_context.h:27
impeller::scene::PipelineKey::Equal
Definition: pipeline_key.h:32
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:21
impeller::scene::SceneContext::GetContext
std::shared_ptr< Context > GetContext() const
Definition: scene_context.cc:92
impeller::scene::SceneContext::GetPipeline
std::shared_ptr< Pipeline< PipelineDescriptor > > GetPipeline(PipelineKey key, SceneContextOptions opts) const
Definition: scene_context.cc:76
context.h
impeller::PrimitiveType::kTriangle
@ kTriangle
pipeline_descriptor.h
impeller::scene::SceneContextOptions::Hash::operator()
constexpr std::size_t operator()(const SceneContextOptions &o) const
Definition: scene_context.h:22
impeller::scene::SceneContextOptions::ApplyToPipelineDescriptor
void ApplyToPipelineDescriptor(const Capabilities &capabilities, PipelineDescriptor &desc) const
Definition: scene_context.cc:15
impeller
Definition: aiks_context.cc:10