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#pragma once
6
7#include <memory>
8#include <string>
9
10#include "flutter/fml/macros.h"
11#include "impeller/core/formats.h"
12#include "impeller/core/host_buffer.h"
13#include "impeller/renderer/capabilities.h"
14#include "impeller/renderer/pool.h"
15
16namespace impeller {
17
18class ShaderLibrary;
19class SamplerLibrary;
20class CommandBuffer;
21class PipelineLibrary;
22class Allocator;
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`.
46class Context {
47 public:
48 enum class BackendType {
49 kMetal,
50 kOpenGLES,
51 kVulkan,
52 };
53
54 //----------------------------------------------------------------------------
55 /// @brief Destroys an Impeller context.
56 ///
57 virtual ~Context();
58
59 //----------------------------------------------------------------------------
60 /// @brief Get the graphics backend of an Impeller context.
61 ///
62 /// This is useful for cases where a renderer needs to track and
63 /// lookup backend-specific resources, like shaders or uniform
64 /// layout information.
65 ///
66 /// It's not recommended to use this as a substitute for
67 /// per-backend capability checking. Instead, check for specific
68 /// capabilities via `GetCapabilities()`.
69 ///
70 /// @return The graphics backend of the `Context`.
71 ///
72 virtual BackendType GetBackendType() const = 0;
73
74 // TODO(129920): Refactor and move to capabilities.
75 virtual std::string DescribeGpuModel() const = 0;
76
77 //----------------------------------------------------------------------------
78 /// @brief Determines if a context is valid. If the caller ever receives
79 /// an invalid context, they must discard it and construct a new
80 /// context. There is no recovery mechanism to repair a bad
81 /// context.
82 ///
83 /// It is convention in Impeller to never return an invalid
84 /// context from a call that returns an pointer to a context. The
85 /// call implementation performs validity checks itself and return
86 /// a null context instead of a pointer to an invalid context.
87 ///
88 /// How a context goes invalid is backend specific. It could
89 /// happen due to device loss, or any other unrecoverable error.
90 ///
91 /// @return If the context is valid.
92 ///
93 virtual bool IsValid() const = 0;
94
95 //----------------------------------------------------------------------------
96 /// @brief Get the capabilities of Impeller context. All optionally
97 /// supported feature of the platform, client-rendering API, and
98 /// device can be queried using the `Capabilities`.
99 ///
100 /// @return The capabilities. Can never be `nullptr` for a valid context.
101 ///
102 virtual const std::shared_ptr<const Capabilities>& GetCapabilities()
103 const = 0;
104
105 // TODO(129920): Refactor and move to capabilities.
106 virtual bool UpdateOffscreenLayerPixelFormat(PixelFormat format);
107
108 //----------------------------------------------------------------------------
109 /// @brief Returns the allocator used to create textures and buffers on
110 /// the device.
111 ///
112 /// @return The resource allocator. Can never be `nullptr` for a valid
113 /// context.
114 ///
115 virtual std::shared_ptr<Allocator> GetResourceAllocator() const = 0;
116
117 //----------------------------------------------------------------------------
118 /// @brief Returns the library of shaders used to specify the
119 /// programmable stages of a pipeline.
120 ///
121 /// @return The shader library. Can never be `nullptr` for a valid
122 /// context.
123 ///
124 virtual std::shared_ptr<ShaderLibrary> GetShaderLibrary() const = 0;
125
126 //----------------------------------------------------------------------------
127 /// @brief Returns the library of combined image samplers used in
128 /// shaders.
129 ///
130 /// @return The sampler library. Can never be `nullptr` for a valid
131 /// context.
132 ///
133 virtual std::shared_ptr<SamplerLibrary> GetSamplerLibrary() const = 0;
134
135 //----------------------------------------------------------------------------
136 /// @brief Returns the library of pipelines used by render or compute
137 /// commands.
138 ///
139 /// @return The pipeline library. Can never be `nullptr` for a valid
140 /// context.
141 ///
142 virtual std::shared_ptr<PipelineLibrary> GetPipelineLibrary() const = 0;
143
144 //----------------------------------------------------------------------------
145 /// @brief Create a new command buffer. Command buffers can be used to
146 /// encode graphics, blit, or compute commands to be submitted to
147 /// the device.
148 ///
149 /// A command buffer can only be used on a single thread.
150 /// Multi-threaded render, blit, or compute passes must create a
151 /// new command buffer on each thread.
152 ///
153 /// @return A new command buffer.
154 ///
155 virtual std::shared_ptr<CommandBuffer> CreateCommandBuffer() const = 0;
156
157 //----------------------------------------------------------------------------
158 /// @brief Force all pending asynchronous work to finish. This is
159 /// achieved by deleting all owned concurrent message loops.
160 ///
161 virtual void Shutdown() = 0;
162
163 //----------------------------------------------------------------------------
164 /// @brief Accessor for a pool of HostBuffers.
165 Pool<HostBuffer>& GetHostBufferPool() const { return host_buffer_pool_; }
166
167 protected:
168 Context();
169
170 private:
171 mutable Pool<HostBuffer> host_buffer_pool_ = Pool<HostBuffer>(1'000'000);
172
173 FML_DISALLOW_COPY_AND_ASSIGN(Context);
174};
175
176} // namespace impeller
177

source code of flutter_engine/flutter/impeller/renderer/context.h