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