Flutter Impeller
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_RENDERER_CONTEXT_H_
6 #define FLUTTER_IMPELLER_RENDERER_CONTEXT_H_
7 
8 #include <memory>
9 #include <string>
10 
12 #include "impeller/core/capture.h"
13 #include "impeller/core/formats.h"
16 #include "impeller/renderer/pool.h"
18 
19 namespace impeller {
20 
21 class ShaderLibrary;
22 class CommandBuffer;
23 class PipelineLibrary;
24 
25 //------------------------------------------------------------------------------
26 /// @brief To do anything rendering related with Impeller, you need a
27 /// context.
28 ///
29 /// Contexts are expensive to construct and typically you only need
30 /// one in the process. The context represents a connection to a
31 /// graphics or compute accelerator on the device.
32 ///
33 /// If there are multiple context in a process, it would typically
34 /// be for separation of concerns (say, use with multiple engines in
35 /// Flutter), talking to multiple accelerators, or talking to the
36 /// same accelerator using different client APIs (Metal, Vulkan,
37 /// OpenGL ES, etc..).
38 ///
39 /// Contexts are thread-safe. They may be created, used, and
40 /// collected (though not from a thread used by an internal pool) on
41 /// any thread. They may also be accessed simultaneously from
42 /// multiple threads.
43 ///
44 /// Contexts are abstract and a concrete instance must be created
45 /// using one of the subclasses of `Context` in
46 /// `//impeller/renderer/backend`.
47 class Context {
48  public:
49  enum class BackendType {
50  kMetal,
51  kOpenGLES,
52  kVulkan,
53  };
54 
55  /// The maximum number of tasks that should ever be stored for
56  /// `StoreTaskForGPU`.
57  ///
58  /// This number was arbitrarily chosen. The idea is that this is a somewhat
59  /// rare situation where tasks happen to get executed in that tiny amount of
60  /// time while an app is being backgrounded but still executing.
61  static constexpr int32_t kMaxTasksAwaitingGPU = 10;
62 
63  //----------------------------------------------------------------------------
64  /// @brief Destroys an Impeller context.
65  ///
66  virtual ~Context();
67 
68  //----------------------------------------------------------------------------
69  /// @brief Get the graphics backend of an Impeller context.
70  ///
71  /// This is useful for cases where a renderer needs to track and
72  /// lookup backend-specific resources, like shaders or uniform
73  /// layout information.
74  ///
75  /// It's not recommended to use this as a substitute for
76  /// per-backend capability checking. Instead, check for specific
77  /// capabilities via `GetCapabilities()`.
78  ///
79  /// @return The graphics backend of the `Context`.
80  ///
81  virtual BackendType GetBackendType() const = 0;
82 
83  // TODO(129920): Refactor and move to capabilities.
84  virtual std::string DescribeGpuModel() const = 0;
85 
86  //----------------------------------------------------------------------------
87  /// @brief Determines if a context is valid. If the caller ever receives
88  /// an invalid context, they must discard it and construct a new
89  /// context. There is no recovery mechanism to repair a bad
90  /// context.
91  ///
92  /// It is convention in Impeller to never return an invalid
93  /// context from a call that returns an pointer to a context. The
94  /// call implementation performs validity checks itself and return
95  /// a null context instead of a pointer to an invalid context.
96  ///
97  /// How a context goes invalid is backend specific. It could
98  /// happen due to device loss, or any other unrecoverable error.
99  ///
100  /// @return If the context is valid.
101  ///
102  virtual bool IsValid() const = 0;
103 
104  //----------------------------------------------------------------------------
105  /// @brief Get the capabilities of Impeller context. All optionally
106  /// supported feature of the platform, client-rendering API, and
107  /// device can be queried using the `Capabilities`.
108  ///
109  /// @return The capabilities. Can never be `nullptr` for a valid context.
110  ///
111  virtual const std::shared_ptr<const Capabilities>& GetCapabilities()
112  const = 0;
113 
114  // TODO(129920): Refactor and move to capabilities.
115  virtual bool UpdateOffscreenLayerPixelFormat(PixelFormat format);
116 
117  //----------------------------------------------------------------------------
118  /// @brief Returns the allocator used to create textures and buffers on
119  /// the device.
120  ///
121  /// @return The resource allocator. Can never be `nullptr` for a valid
122  /// context.
123  ///
124  virtual std::shared_ptr<Allocator> GetResourceAllocator() const = 0;
125 
126  //----------------------------------------------------------------------------
127  /// @brief Returns the library of shaders used to specify the
128  /// programmable stages of a pipeline.
129  ///
130  /// @return The shader library. Can never be `nullptr` for a valid
131  /// context.
132  ///
133  virtual std::shared_ptr<ShaderLibrary> GetShaderLibrary() const = 0;
134 
135  //----------------------------------------------------------------------------
136  /// @brief Returns the library of combined image samplers used in
137  /// shaders.
138  ///
139  /// @return The sampler library. Can never be `nullptr` for a valid
140  /// context.
141  ///
142  virtual std::shared_ptr<SamplerLibrary> GetSamplerLibrary() const = 0;
143 
144  //----------------------------------------------------------------------------
145  /// @brief Returns the library of pipelines used by render or compute
146  /// commands.
147  ///
148  /// @return The pipeline library. Can never be `nullptr` for a valid
149  /// context.
150  ///
151  virtual std::shared_ptr<PipelineLibrary> GetPipelineLibrary() const = 0;
152 
153  //----------------------------------------------------------------------------
154  /// @brief Create a new command buffer. Command buffers can be used to
155  /// encode graphics, blit, or compute commands to be submitted to
156  /// the device.
157  ///
158  /// A command buffer can only be used on a single thread.
159  /// Multi-threaded render, blit, or compute passes must create a
160  /// new command buffer on each thread.
161  ///
162  /// @return A new command buffer.
163  ///
164  virtual std::shared_ptr<CommandBuffer> CreateCommandBuffer() const = 0;
165 
166  //----------------------------------------------------------------------------
167  /// @brief Force all pending asynchronous work to finish. This is
168  /// achieved by deleting all owned concurrent message loops.
169  ///
170  virtual void Shutdown() = 0;
171 
172  //----------------------------------------------------------------------------
173  /// @brief Force the Vulkan presentation (submitKHR) to be performed on
174  /// the raster task runner.
175  ///
176  /// This is required for correct rendering on Android when using
177  /// the hybrid composition mode. This has no effect on other
178  /// backends. This is analogous to the check for isMainThread in
179  /// surface_mtl.mm to block presentation on scheduling of all
180  /// pending work.
181  virtual void SetSyncPresentation(bool value) {}
182 
183  //----------------------------------------------------------------------------
184  /// @brief Accessor for a pool of HostBuffers.
185  Pool<HostBuffer>& GetHostBufferPool() const { return host_buffer_pool_; }
186 
188 
189  /// Stores a task on the `ContextMTL` that is awaiting access for the GPU.
190  ///
191  /// The task will be executed in the event that the GPU access has changed to
192  /// being available or that the task has been canceled. The task should
193  /// operate with the `SyncSwitch` to make sure the GPU is accessible.
194  ///
195  /// Threadsafe.
196  ///
197  /// `task` will be executed on the platform thread.
198  virtual void StoreTaskForGPU(const std::function<void()>& task) {
199  FML_CHECK(false && "not supported in this context");
200  }
201 
202  protected:
203  Context();
204 
205  private:
206  mutable Pool<HostBuffer> host_buffer_pool_ = Pool<HostBuffer>(1'000'000);
207 
208  Context(const Context&) = delete;
209 
210  Context& operator=(const Context&) = delete;
211 };
212 
213 } // namespace impeller
214 
215 #endif // FLUTTER_IMPELLER_RENDERER_CONTEXT_H_
impeller::Context::GetPipelineLibrary
virtual std::shared_ptr< PipelineLibrary > GetPipelineLibrary() const =0
Returns the library of pipelines used by render or compute commands.
impeller::Context::capture
CaptureContext capture
Definition: context.h:187
host_buffer.h
capture.h
impeller::Context::~Context
virtual ~Context()
Destroys an Impeller context.
impeller::Context::BackendType
BackendType
Definition: context.h:49
sampler_library.h
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::Context::GetShaderLibrary
virtual std::shared_ptr< ShaderLibrary > GetShaderLibrary() const =0
Returns the library of shaders used to specify the programmable stages of a pipeline.
formats.h
impeller::PixelFormat
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:94
impeller::Context::GetBackendType
virtual BackendType GetBackendType() const =0
Get the graphics backend of an Impeller context.
impeller::CaptureContext
Definition: capture.h:269
impeller::Context::BackendType::kOpenGLES
@ kOpenGLES
pool.h
impeller::Pool
A thread-safe pool with a limited byte size.
Definition: pool.h:17
impeller::Context::Context
Context()
Definition: context.cc:13
capabilities.h
impeller::Context::GetSamplerLibrary
virtual std::shared_ptr< SamplerLibrary > GetSamplerLibrary() const =0
Returns the library of combined image samplers used in shaders.
impeller::Context::StoreTaskForGPU
virtual void StoreTaskForGPU(const std::function< void()> &task)
Definition: context.h:198
impeller::Context::CreateCommandBuffer
virtual std::shared_ptr< CommandBuffer > CreateCommandBuffer() const =0
Create a new command buffer. Command buffers can be used to encode graphics, blit,...
impeller::Context::GetHostBufferPool
Pool< HostBuffer > & GetHostBufferPool() const
Accessor for a pool of HostBuffers.
Definition: context.h:185
impeller::Context::IsValid
virtual bool IsValid() const =0
Determines if a context is valid. If the caller ever receives an invalid context, they must discard i...
allocator.h
impeller::Context::BackendType::kVulkan
@ kVulkan
impeller::Context::BackendType::kMetal
@ kMetal
impeller::Context
To do anything rendering related with Impeller, you need a context.
Definition: context.h:47
impeller::Context::SetSyncPresentation
virtual void SetSyncPresentation(bool value)
Force the Vulkan presentation (submitKHR) to be performed on the raster task runner.
Definition: context.h:181
impeller::Context::Shutdown
virtual void Shutdown()=0
Force all pending asynchronous work to finish. This is achieved by deleting all owned concurrent mess...
impeller::Context::DescribeGpuModel
virtual std::string DescribeGpuModel() const =0
impeller
Definition: aiks_context.cc:10
impeller::Context::GetResourceAllocator
virtual std::shared_ptr< Allocator > GetResourceAllocator() const =0
Returns the allocator used to create textures and buffers on the device.
impeller::Context::UpdateOffscreenLayerPixelFormat
virtual bool UpdateOffscreenLayerPixelFormat(PixelFormat format)
Definition: context.cc:15
impeller::Context::kMaxTasksAwaitingGPU
static constexpr int32_t kMaxTasksAwaitingGPU
Definition: context.h:61