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