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