Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
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 <future>
9#include <memory>
10#include <string>
11
12#include "fml/closure.h"
13#include "impeller/base/flags.h"
20
21namespace flutter::testing {
22class DlSurfaceInstanceImpeller;
23}
24
25namespace impeller {
26
27class ShaderLibrary;
28class CommandBuffer;
29class PipelineLibrary;
30
31/// A wrapper for provided a deferred initialization of impeller to various
32/// engine subsystems.
34 public:
35 explicit ImpellerContextFuture(
36 std::future<std::shared_ptr<impeller::Context>> context);
37
38 std::shared_ptr<impeller::Context> GetContext();
39
40 private:
41 std::mutex mutex_;
42 std::future<std::shared_ptr<impeller::Context>> future_;
43 std::shared_ptr<impeller::Context> context_;
44 bool did_wait_ = false;
45};
46
47//------------------------------------------------------------------------------
48/// @brief To do anything rendering related with Impeller, you need a
49/// context.
50///
51/// Contexts are expensive to construct and typically you only need
52/// one in the process. The context represents a connection to a
53/// graphics or compute accelerator on the device.
54///
55/// If there are multiple context in a process, it would typically
56/// be for separation of concerns (say, use with multiple engines in
57/// Flutter), talking to multiple accelerators, or talking to the
58/// same accelerator using different client APIs (Metal, Vulkan,
59/// OpenGL ES, etc..).
60///
61/// Contexts are thread-safe. They may be created, used, and
62/// collected (though not from a thread used by an internal pool) on
63/// any thread. They may also be accessed simultaneously from
64/// multiple threads.
65///
66/// Contexts are abstract and a concrete instance must be created
67/// using one of the subclasses of `Context` in
68/// `//impeller/renderer/backend`.
69class Context {
70 public:
71 enum class BackendType {
72 kMetal,
74 kVulkan,
75 };
76
77 /// The maximum number of tasks that should ever be stored for
78 /// `StoreTaskForGPU`.
79 ///
80 /// This number was arbitrarily chosen. The idea is that this is a somewhat
81 /// rare situation where tasks happen to get executed in that tiny amount of
82 /// time while an app is being backgrounded but still executing.
83 static constexpr int32_t kMaxTasksAwaitingGPU = 1024;
84
85 //----------------------------------------------------------------------------
86 /// @brief Destroys an Impeller context.
87 ///
88 virtual ~Context();
89
90 //----------------------------------------------------------------------------
91 /// @brief Get the graphics backend of an Impeller context.
92 ///
93 /// This is useful for cases where a renderer needs to track and
94 /// lookup backend-specific resources, like shaders or uniform
95 /// layout information.
96 ///
97 /// It's not recommended to use this as a substitute for
98 /// per-backend capability checking. Instead, check for specific
99 /// capabilities via `GetCapabilities()`.
100 ///
101 /// @return The graphics backend of the `Context`.
102 ///
103 virtual BackendType GetBackendType() const = 0;
104
105 // TODO(129920): Refactor and move to capabilities.
106 virtual std::string DescribeGpuModel() const = 0;
107
108 //----------------------------------------------------------------------------
109 /// @brief Determines if a context is valid. If the caller ever receives
110 /// an invalid context, they must discard it and construct a new
111 /// context. There is no recovery mechanism to repair a bad
112 /// context.
113 ///
114 /// It is convention in Impeller to never return an invalid
115 /// context from a call that returns an pointer to a context. The
116 /// call implementation performs validity checks itself and return
117 /// a null context instead of a pointer to an invalid context.
118 ///
119 /// How a context goes invalid is backend specific. It could
120 /// happen due to device loss, or any other unrecoverable error.
121 ///
122 /// @return If the context is valid.
123 ///
124 virtual bool IsValid() const = 0;
125
126 //----------------------------------------------------------------------------
127 /// @brief Get the capabilities of Impeller context. All optionally
128 /// supported feature of the platform, client-rendering API, and
129 /// device can be queried using the `Capabilities`.
130 ///
131 /// @return The capabilities. Can never be `nullptr` for a valid context.
132 ///
133 virtual const std::shared_ptr<const Capabilities>& GetCapabilities()
134 const = 0;
135
136 // TODO(129920): Refactor and move to capabilities.
137 virtual bool UpdateOffscreenLayerPixelFormat(PixelFormat format);
138
139 //----------------------------------------------------------------------------
140 /// @brief Returns the allocator used to create textures and buffers on
141 /// the device.
142 ///
143 /// @return The resource allocator. Can never be `nullptr` for a valid
144 /// context.
145 ///
146 virtual std::shared_ptr<Allocator> GetResourceAllocator() const = 0;
147
148 //----------------------------------------------------------------------------
149 /// @brief Returns the library of shaders used to specify the
150 /// programmable stages of a pipeline.
151 ///
152 /// @return The shader library. Can never be `nullptr` for a valid
153 /// context.
154 ///
155 virtual std::shared_ptr<ShaderLibrary> GetShaderLibrary() const = 0;
156
157 //----------------------------------------------------------------------------
158 /// @brief Returns the library of combined image samplers used in
159 /// shaders.
160 ///
161 /// @return The sampler library. Can never be `nullptr` for a valid
162 /// context.
163 ///
164 virtual std::shared_ptr<SamplerLibrary> GetSamplerLibrary() const = 0;
165
166 //----------------------------------------------------------------------------
167 /// @brief Returns the library of pipelines used by render or compute
168 /// commands.
169 ///
170 /// @return The pipeline library. Can never be `nullptr` for a valid
171 /// context.
172 ///
173 virtual std::shared_ptr<PipelineLibrary> GetPipelineLibrary() const = 0;
174
175 //----------------------------------------------------------------------------
176 /// @brief Create a new command buffer. Command buffers can be used to
177 /// encode graphics, blit, or compute commands to be submitted to
178 /// the device.
179 ///
180 /// A command buffer can only be used on a single thread.
181 /// Multi-threaded render, blit, or compute passes must create a
182 /// new command buffer on each thread.
183 ///
184 /// @return A new command buffer.
185 ///
186 virtual std::shared_ptr<CommandBuffer> CreateCommandBuffer() const = 0;
187
188 /// @brief Return the graphics queue for submitting command buffers.
189 virtual std::shared_ptr<CommandQueue> GetCommandQueue() const = 0;
190
191 //----------------------------------------------------------------------------
192 /// @brief Force all pending asynchronous work to finish. This is
193 /// achieved by deleting all owned concurrent message loops.
194 ///
195 virtual void Shutdown() = 0;
196
197 /// Stores a task on the `ContextMTL` that is awaiting access for the GPU.
198 ///
199 /// The task will be executed in the event that the GPU access has changed to
200 /// being available or that the task has been canceled. The task should
201 /// operate with the `SyncSwitch` to make sure the GPU is accessible.
202 ///
203 /// If the queue of pending tasks is cleared without GPU access, then the
204 /// failure callback will be invoked and the primary task function will not
205 ///
206 /// Threadsafe.
207 ///
208 /// `task` will be executed on the platform thread.
209 virtual void StoreTaskForGPU(const fml::closure& task,
210 const fml::closure& failure) {
211 FML_CHECK(false && "not supported in this context");
212 }
213
214 /// Run backend specific additional setup and create common shader variants.
215 ///
216 /// This bootstrap is intended to improve the performance of several
217 /// first frame benchmarks that are tracked in the flutter device lab.
218 /// The workload includes initializing commonly used but not default
219 /// shader variants, as well as forcing driver initialization.
221
222 /// Dispose resources that are cached on behalf of the current thread.
223 ///
224 /// Some backends such as Vulkan may cache resources that can be reused while
225 /// executing a rendering operation. This API can be called after the
226 /// operation completes in order to clear the cache.
228
229 /// @brief Enqueue command_buffer for submission by the end of the frame.
230 ///
231 /// Certain backends may immediately flush the command buffer if batch
232 /// submission is not supported. This functionality is not thread safe
233 /// and should only be used via the ContentContext for rendering a
234 /// 2D workload.
235 ///
236 /// Returns true if submission has succeeded. If the buffer is enqueued
237 /// then no error may be returned until FlushCommandBuffers is called.
238 [[nodiscard]] virtual bool EnqueueCommandBuffer(
239 std::shared_ptr<CommandBuffer> command_buffer);
240
241 /// @brief Flush all pending command buffers.
242 ///
243 /// Returns whether or not submission was successful. This functionality
244 /// is not threadsafe and should only be used via the ContentContext for
245 /// rendering a 2D workload.
246 [[nodiscard]] virtual bool FlushCommandBuffers();
247
248 virtual bool AddTrackingFence(const std::shared_ptr<Texture>& texture) const;
249
250 virtual std::shared_ptr<const IdleWaiter> GetIdleWaiter() const;
251
252 //----------------------------------------------------------------------------
253 /// Resets any thread local state that may interfere with embedders.
254 ///
255 /// Today, only the OpenGL backend can trample on thread local state that the
256 /// embedder can access. This call puts the GL state in a sane "clean" state.
257 ///
258 /// Impeller itself is resilient to a dirty thread local state table.
259 ///
260 virtual void ResetThreadLocalState() const;
261
262 /// @brief Retrieve the runtime stage for this context type.
263 ///
264 /// This is used by the engine shell and other subsystems for loading the
265 /// correct shader types.
267
268 /// @brief Submit the command buffer that renders to the onscreen surface.
269 virtual bool SubmitOnscreen(std::shared_ptr<CommandBuffer> cmd_buffer);
270
271 const Flags& GetFlags() const { return flags_; }
272
273 protected:
274 explicit Context(const Flags& flags);
275
277 std::vector<std::function<void()>> per_frame_task_;
278
279 private:
280 Context(const Context&) = delete;
281
282 Context& operator=(const Context&) = delete;
283
284 /// @brief Wait until all previously submitted command buffers are
285 /// processed and displayed by the GPU.
286 ///
287 /// WARNING: This method call is unnecessary for nearly all use cases
288 /// since asynchronous workloads are the expected norm and calling
289 /// this method can negatively affect application performance.
290 /// Its only use is for cases like benchmarking where proper
291 /// performance metrics can only be collected by including
292 /// all background processing of the GPU.
293 ///
294 /// Outstanding unflushed command buffers are not committed, submitted,
295 /// or enqueued by this method and such buffers should have already been
296 /// flushed before this method is called. The method will only wait for
297 /// work to be done that has already been submitted to the GPU.
298 ///
299 /// @return True if the queue was successfully processed, otherwise
300 /// false if there was an error or if the backend does not
301 /// support synchronous reporting of completion. Implementations
302 /// intended entirely for testing might simply return false,
303 /// but they would not be used for benchmarking or other
304 /// situations where we might measure GPU performance.
305 virtual bool FinishQueue() = 0;
306
308};
309
310} // namespace impeller
311
312#endif // FLUTTER_IMPELLER_RENDERER_CONTEXT_H_
To do anything rendering related with Impeller, you need a context.
Definition context.h:69
virtual std::shared_ptr< const IdleWaiter > GetIdleWaiter() const
Definition context.cc:42
virtual bool AddTrackingFence(const std::shared_ptr< Texture > &texture) const
Definition context.cc:50
virtual std::shared_ptr< CommandQueue > GetCommandQueue() const =0
Return the graphics queue for submitting command buffers.
virtual bool SubmitOnscreen(std::shared_ptr< CommandBuffer > cmd_buffer)
Submit the command buffer that renders to the onscreen surface.
Definition context.cc:54
virtual const std::shared_ptr< const Capabilities > & GetCapabilities() const =0
Get the capabilities of Impeller context. All optionally supported feature of the platform,...
static constexpr int32_t kMaxTasksAwaitingGPU
Definition context.h:83
const Flags & GetFlags() const
Definition context.h:271
std::vector< std::function< void()> > per_frame_task_
Definition context.h:277
virtual bool UpdateOffscreenLayerPixelFormat(PixelFormat format)
Definition context.cc:29
virtual BackendType GetBackendType() const =0
Get the graphics backend of an Impeller context.
virtual std::shared_ptr< PipelineLibrary > GetPipelineLibrary() const =0
Returns the library of pipelines used by render or compute commands.
virtual void Shutdown()=0
Force all pending asynchronous work to finish. This is achieved by deleting all owned concurrent mess...
virtual void DisposeThreadLocalCachedResources()
Definition context.h:227
virtual bool FlushCommandBuffers()
Flush all pending command buffers.
Definition context.cc:38
virtual std::shared_ptr< ShaderLibrary > GetShaderLibrary() const =0
Returns the library of shaders used to specify the programmable stages of a pipeline.
virtual RuntimeStageBackend GetRuntimeStageBackend() const =0
Retrieve the runtime stage for this context type.
virtual std::shared_ptr< SamplerLibrary > GetSamplerLibrary() const =0
Returns the library of combined image samplers used in shaders.
virtual std::shared_ptr< CommandBuffer > CreateCommandBuffer() const =0
Create a new command buffer. Command buffers can be used to encode graphics, blit,...
virtual void StoreTaskForGPU(const fml::closure &task, const fml::closure &failure)
Definition context.h:209
virtual void InitializeCommonlyUsedShadersIfNeeded() const
Definition context.h:220
virtual std::string DescribeGpuModel() const =0
virtual ~Context()
Destroys an Impeller context.
virtual std::shared_ptr< Allocator > GetResourceAllocator() const =0
Returns the allocator used to create textures and buffers on the device.
virtual bool IsValid() const =0
Determines if a context is valid. If the caller ever receives an invalid context, they must discard i...
virtual void ResetThreadLocalState() const
Definition context.cc:46
virtual bool EnqueueCommandBuffer(std::shared_ptr< CommandBuffer > command_buffer)
Enqueue command_buffer for submission by the end of the frame.
Definition context.cc:33
std::shared_ptr< impeller::Context > GetContext()
Definition context.cc:16
#define FML_CHECK(condition)
Definition logging.h:104
FlTexture * texture
std::function< void()> closure
Definition closure.h:14
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition formats.h:99