Loading...
Searching...
No Matches
GPUDriver.h
Go to the documentation of this file.
1/**************************************************************************************************
2 * This file is a part of Ultralight. *
3 * *
4 * See <https://ultralig.ht> for licensing and more. *
5 * *
6 * (C) 2024 Ultralight, Inc. *
7 **************************************************************************************************/
8
9// clang-format off
10#pragma once
11#pragma warning(disable : 4251)
12#include <Ultralight/Defines.h>
13#include <Ultralight/Geometry.h>
14#include <Ultralight/Matrix.h>
15#include <Ultralight/Bitmap.h>
16
17namespace ultralight {
18
19/// \cond ignore
20/// This pragma pack(push, 1) command is important!
21/// GPU structs should not be padded with any bytes.
22/// \endcond
23#pragma pack(push, 1)
24
25///
26/// Render buffer description.
27///
28/// This structure describes a render buffer that can be used as a target for drawing commands.
29///
30/// @see GPUDriver::CreateRenderBuffer.
31///
33 uint32_t texture_id; ///< The backing texture for this RenderBuffer
34 uint32_t width; ///< The width of the RenderBuffer texture
35 uint32_t height; ///< The height of the RenderBuffer texture
36 bool has_stencil_buffer; ///< Currently unused, always false.
37 bool has_depth_buffer; ///< Currently unsued, always false.
38};
39
40///
41/// Vertex layout for path vertices.
42///
43/// This struct is the in-memory layout for each path vertex (useful for synthesizing or modifying
44/// your own vertex data).
45///
47 float pos[2];
48 unsigned char color[4];
49 float obj[2];
50};
51
52///
53/// Vertex layout for quad vertices.
54///
55/// This struct is the in-memory layout for each quad vertex (useful for synthesizing or modifying
56/// your own vertex data).
57///
59 float pos[2];
60 unsigned char color[4];
61 float tex[2];
62 float obj[2];
63 float data0[4];
64 float data1[4];
65 float data2[4];
66 float data3[4];
67 float data4[4];
68 float data5[4];
69 float data6[4];
70};
71
72///
73/// Vertex buffer formats.
74///
75/// This enumeration describes the format of a vertex buffer.
76///
77/// @note Identifiers start with an underscore due to C++ naming rules.
78///
79/// @see VertexBuffer
80///
81enum class VertexBufferFormat : uint8_t {
82 _2f_4ub_2f, ///< Vertex_2f_4ub_2f (used for path rendering)
83 _2f_4ub_2f_2f_28f, ///< Vertex_2f_4ub_2f_2f_28f (used for quad rendering)
84};
85
86///
87/// Vertex buffer description.
88///
89/// @see GPUDriver::CreateGeometry
90///
92 VertexBufferFormat format; ///< The format of the vertex buffer.
93 uint32_t size; ///< The size of the vertex buffer in bytes.
94 uint8_t* data; ///< The raw vertex buffer data.
95};
96
97///
98/// Vertex index type.
99///
100typedef uint32_t IndexType;
101
102///
103/// Index buffer description.
104///
105/// This structure describes an index buffer that can be used to index into a vertex buffer.
106///
107/// @note The index buffer is a simple array of IndexType values.
108///
109/// @see GPUDriver::CreateGeometry
110///
112 uint32_t size; ///< The size of the index buffer in bytes.
113 uint8_t* data; ///< The raw index buffer data.
114};
115
116///
117/// Shader program types.
118///
119/// Each of these correspond to a vertex/pixel shader pair. You can find stock shader code for
120/// these in the `shaders` folder of the AppCore repo.
121///
122/// @see GPUState::shader_type
123///
124enum class ShaderType : uint8_t {
125 Fill, ///< Shader program for filling quad geometry.
126 FillPath, ///< Shader program for filling tesselated path geometry.
127};
128
129///
130/// The state of the GPU for a given draw command.
131///
132/// This structure describes the current state of the GPU for a given draw command.
133///
134/// @see Command::gpu_state
135///
137 /// Viewport width in pixels
139
140 /// Viewport height in pixels
142
143 /// Transform matrix-- you should multiply this with the screen-space orthographic projection
144 /// matrix then pass to the vertex shader.
146
147 /// Whether or not we should enable texturing for the current draw command.
149
150 /// Whether or not we should enable blending for the current draw command. If blending is
151 /// disabled, any drawn pixels should overwrite existing. This is mainly used so we can modify
152 /// alpha values of the RenderBuffer during scissored clears.
154
155 /// The vertex/pixel shader program pair to use for the current draw command.
157
158 /// The render buffer to use for the current draw command.
160
161 /// The texture id to bind to slot #1. (Will be 0 if none)
162 uint32_t texture_1_id;
163
164 /// The texture id to bind to slot #2. (Will be 0 if none)
165 uint32_t texture_2_id;
166
167 /// The texture id to bind to slot #3. (Will be 0 if none)
168 uint32_t texture_3_id;
169
170 /// The uniform scalars (passed to the pixel shader via uniforms).
171 float uniform_scalar[8];
172
173 /// The uniform vectors (passed to the pixel shader via uniforms).
174 vec4 uniform_vector[8];
175
176 /// The clip size (passed to the pixel shader via uniforms).
177 uint8_t clip_size;
178
179 /// The clip stack (passed to the pixel shader via uniforms).
180 Matrix4x4 clip[8];
181
182 /// Whether or not scissor testing should be used for the current draw command.
184
185 /// The scissor rect to use for scissor testing (units in pixels)
187};
188
189///
190/// The types of commands.
191///
192/// This enumeration describes the type of command to execute on the GPU.
193///
194/// @see Command
195///
196enum class CommandType : uint8_t {
197 ClearRenderBuffer, ///< Clear the specified render buffer.
198 DrawGeometry, ///< Draw the specified geometry to the specified render buffer.
199};
200
201///
202/// A command to execute on the GPU.
203///
204/// This structure describes a command to be executed on the GPU.
205///
206/// Commands are dispatched to the GPU driver asynchronously via GPUDriver::UpdateCommandList(),
207/// the GPU driver should consume these commands and execute them at an appropriate time.
208///
209/// @see CommandList
210///
212 CommandType command_type; ///< The type of command to dispatch.
213 GPUState gpu_state; ///< The current GPU state.
214 uint32_t geometry_id; ///< The geometry ID to bind. (used with CommandType::DrawGeometry)
215 uint32_t indices_count; ///< The number of indices. (used with CommandType::DrawGeometry)
216 uint32_t indices_offset; ///< The index to start from. (used with CommandType::DrawGeometry)
217};
218
219///
220/// List of commands to execute on the GPU.
221///
222/// @see GPUDriver::UpdateCommandList
223///
225 uint32_t size; ///< The number of commands in the list.
226 Command* commands; ///< The raw command list data.
227};
228
229#pragma pack(pop)
230
231///
232/// User-defined GPU driver interface.
233///
234/// The library uses this to optionally render Views on the GPU (see ViewConfig::is_accelerated).
235///
236/// You can provide the library with your own GPU driver implementation so that all rendering is
237/// performed using an existing GPU context (useful for game engines).
238///
239/// When a View is rendered on the GPU, you can retrieve the backing texture ID via
240/// View::render_target().
241///
242/// ## Default Implementation
243///
244/// A platform-specific implementation of GPUDriver is provided for you when you call App::Create(),
245/// (currently D3D11, Metal, and OpenGL). We recommend using these classes as a starting point for
246/// your own implementation (available open-source in the AppCore repository on GitHub).
247///
248/// ## Setting the GPU Driver
249///
250/// When using Renderer::Create(), you can provide your own implementation of this
251/// class via Platform::set_gpu_driver().
252///
253/// ## State Synchronization
254///
255/// During each call to Renderer::Render(), the library will update the state of the GPU driver
256/// (textures, render buffers, geometry, command lists, etc.) to match the current state of the
257/// library.
258///
259/// ### Detecting State Changes
260///
261/// The library will call BeginSynchronize() before any state is updated and EndSynchronize() after
262/// all state is updated. All `Create` / `Update` / `Destroy` calls will be made between these two
263/// calls.
264///
265/// This allows the GPU driver implementation to prepare the GPU for any state changes.
266///
267/// ## Drawing
268///
269/// All drawing is done via command lists (UpdateCommandList()) to allow asynchronous execution
270/// of commands on the GPU.
271///
272/// The library will dispatch a list of commands to the GPU driver during state synchronization. The
273/// GPU driver implementation should periodically consume the command list and execute the commands
274/// at an appropriate time.
275///
276/// @see Platform::set_gpu_driver()
277///
279 public:
280 virtual ~GPUDriver();
281
282 ///
283 /// Called before any state (eg, CreateTexture(), UpdateTexture(), DestroyTexture(), etc.) is
284 /// updated during a call to Renderer::Render().
285 ///
286 /// This is a good time to prepare the GPU for any state updates.
287 ///
288 virtual void BeginSynchronize() = 0;
289
290 ///
291 /// Called after all state has been updated during a call to Renderer::Render().
292 ///
293 virtual void EndSynchronize() = 0;
294
295 ///
296 /// Get the next available texture ID.
297 ///
298 /// This is used to generate a unique texture ID for each texture created by the library. The
299 /// GPU driver implementation is responsible for mapping these IDs to a native ID.
300 ///
301 /// @note Numbering should start at 1, 0 is reserved for "no texture".
302 ///
303 /// @return Returns the next available texture ID.
304 ///
305 virtual uint32_t NextTextureId() = 0;
306
307 ///
308 /// Create a texture with a certain ID and optional bitmap.
309 ///
310 /// @param texture_id The texture ID to use for the new texture.
311 ///
312 /// @param bitmap The bitmap to initialize the texture with (can be empty).
313 ///
314 /// @note If the Bitmap is empty (Bitmap::IsEmpty), then a RTT Texture should be created instead.
315 /// This will be used as a backing texture for a new RenderBuffer.
316 ///
317 /// @warning A deep copy of the bitmap data should be made if you are uploading it to the GPU
318 /// asynchronously, it will not persist beyond this call.
319 ///
320 virtual void CreateTexture(uint32_t texture_id, RefPtr<Bitmap> bitmap) = 0;
321
322 ///
323 /// Update an existing non-RTT texture with new bitmap data.
324 ///
325 /// @param texture_id The texture to update.
326 ///
327 /// @param bitmap The new bitmap data.
328 ///
329 /// @warning A deep copy of the bitmap data should be made if you are uploading it to the GPU
330 /// asynchronously, it will not persist beyond this call.
331 ///
332 virtual void UpdateTexture(uint32_t texture_id, RefPtr<Bitmap> bitmap) = 0;
333
334 ///
335 /// Destroy a texture.
336 ///
337 /// @param texture_id The texture to destroy.
338 ///
339 virtual void DestroyTexture(uint32_t texture_id) = 0;
340
341 ///
342 /// Get the next available render buffer ID.
343 ///
344 /// This is used to generate a unique render buffer ID for each render buffer created by the
345 /// library. The GPU driver implementation is responsible for mapping these IDs to a native ID.
346 ///
347 /// @note Numbering should start at 1, 0 is reserved for "no render buffer".
348 ///
349 /// @return Returns the next available render buffer ID.
350 ///
351 virtual uint32_t NextRenderBufferId() = 0;
352
353 ///
354 /// Create a render buffer with certain ID and buffer description.
355 ///
356 /// @param render_buffer_id The render buffer ID to use for the new render buffer.
357 ///
358 /// @param buffer The render buffer description.
359 ///
360 virtual void CreateRenderBuffer(uint32_t render_buffer_id, const RenderBuffer& buffer) = 0;
361
362 ///
363 /// Destroy a render buffer.
364 ///
365 /// @param render_buffer_id The render buffer to destroy.
366 ///
367 virtual void DestroyRenderBuffer(uint32_t render_buffer_id) = 0;
368
369 ///
370 /// Get the next available geometry ID.
371 ///
372 /// This is used to generate a unique geometry ID for each geometry created by the library. The
373 /// GPU driver implementation is responsible for mapping these IDs to a native ID.
374 ///
375 /// @note Numbering should start at 1, 0 is reserved for "no geometry".
376 ///
377 /// @return Returns the next available geometry ID.
378 ///
379 virtual uint32_t NextGeometryId() = 0;
380
381 ///
382 /// Create geometry with certain ID and vertex/index data.
383 ///
384 /// @param geometry_id The geometry ID to use for the new geometry.
385 ///
386 /// @param vertices The vertex buffer data.
387 ///
388 /// @param indices The index buffer data.
389 ///
390 /// @warning A deep copy of the vertex/index data should be made if you are uploading it to the
391 /// GPU asynchronously, it will not persist beyond this call.
392 ///
393 virtual void CreateGeometry(uint32_t geometry_id, const VertexBuffer& vertices,
394 const IndexBuffer& indices)
395 = 0;
396
397 ///
398 /// Update existing geometry with new vertex/index data.
399 ///
400 /// @param geometry_id The geometry to update.
401 ///
402 /// @param vertices The new vertex buffer data.
403 ///
404 /// @param indices The new index buffer data.
405 ///
406 /// @warning A deep copy of the vertex/index data should be made if you are uploading it to the
407 /// GPU asynchronously, it will not persist beyond this call.
408 ///
409 virtual void UpdateGeometry(uint32_t geometry_id, const VertexBuffer& vertices,
410 const IndexBuffer& indices)
411 = 0;
412
413 ///
414 /// Destroy geometry.
415 ///
416 /// @param geometry_id The geometry to destroy.
417 ///
418 virtual void DestroyGeometry(uint32_t geometry_id) = 0;
419
420 ///
421 /// Update the pending command list with commands to execute on the GPU.
422 ///
423 /// Commands are dispatched to the GPU driver asynchronously via this method. The GPU driver
424 /// implementation should consume these commands and execute them at an appropriate time.
425 ///
426 /// @param list The list of commands to execute.
427 ///
428 /// @warning Implementations should make a deep copy of the command list, it will not persist
429 /// beyond this call.
430 ///
431 virtual void UpdateCommandList(const CommandList& list) = 0;
432};
433
434} // namespace ultralight
435
436// clang-format on
#define UExport
Definition Exports.h:25
User-defined GPU driver interface.
Definition GPUDriver.h:278
virtual void EndSynchronize()=0
Called after all state has been updated during a call to Renderer::Render().
virtual void BeginSynchronize()=0
Called before any state (eg, CreateTexture(), UpdateTexture(), DestroyTexture(), etc....
virtual void CreateRenderBuffer(uint32_t render_buffer_id, const RenderBuffer &buffer)=0
Create a render buffer with certain ID and buffer description.
virtual uint32_t NextRenderBufferId()=0
Get the next available render buffer ID.
virtual uint32_t NextTextureId()=0
Get the next available texture ID.
virtual void CreateGeometry(uint32_t geometry_id, const VertexBuffer &vertices, const IndexBuffer &indices)=0
Create geometry with certain ID and vertex/index data.
virtual void DestroyTexture(uint32_t texture_id)=0
Destroy a texture.
virtual void CreateTexture(uint32_t texture_id, RefPtr< Bitmap > bitmap)=0
Create a texture with a certain ID and optional bitmap.
virtual void UpdateTexture(uint32_t texture_id, RefPtr< Bitmap > bitmap)=0
Update an existing non-RTT texture with new bitmap data.
virtual void UpdateCommandList(const CommandList &list)=0
Update the pending command list with commands to execute on the GPU.
virtual void DestroyRenderBuffer(uint32_t render_buffer_id)=0
Destroy a render buffer.
virtual void DestroyGeometry(uint32_t geometry_id)=0
Destroy geometry.
virtual uint32_t NextGeometryId()=0
Get the next available geometry ID.
virtual void UpdateGeometry(uint32_t geometry_id, const VertexBuffer &vertices, const IndexBuffer &indices)=0
Update existing geometry with new vertex/index data.
A nullable smart pointer.
Definition RefPtr.h:79
Definition App.h:14
CommandType
The types of commands.
Definition GPUDriver.h:196
@ ClearRenderBuffer
Clear the specified render buffer.
@ DrawGeometry
Draw the specified geometry to the specified render buffer.
ShaderType
Shader program types.
Definition GPUDriver.h:124
@ FillPath
Shader program for filling tesselated path geometry.
@ Fill
Shader program for filling quad geometry.
VertexBufferFormat
Vertex buffer formats.
Definition GPUDriver.h:81
@ _2f_4ub_2f
Vertex_2f_4ub_2f (used for path rendering)
@ _2f_4ub_2f_2f_28f
Vertex_2f_4ub_2f_2f_28f (used for quad rendering)
uint32_t IndexType
Vertex index type.
Definition GPUDriver.h:100
A command to execute on the GPU.
Definition GPUDriver.h:211
GPUState gpu_state
The current GPU state.
Definition GPUDriver.h:213
CommandType command_type
The type of command to dispatch.
Definition GPUDriver.h:212
uint32_t indices_count
The number of indices. (used with CommandType::DrawGeometry)
Definition GPUDriver.h:215
uint32_t geometry_id
The geometry ID to bind. (used with CommandType::DrawGeometry)
Definition GPUDriver.h:214
uint32_t indices_offset
The index to start from. (used with CommandType::DrawGeometry)
Definition GPUDriver.h:216
List of commands to execute on the GPU.
Definition GPUDriver.h:224
Command * commands
The raw command list data.
Definition GPUDriver.h:226
uint32_t size
The number of commands in the list.
Definition GPUDriver.h:225
The state of the GPU for a given draw command.
Definition GPUDriver.h:136
uint32_t viewport_height
Viewport height in pixels.
Definition GPUDriver.h:141
uint32_t texture_3_id
The texture id to bind to slot #3. (Will be 0 if none)
Definition GPUDriver.h:168
uint32_t texture_1_id
The texture id to bind to slot #1. (Will be 0 if none)
Definition GPUDriver.h:162
uint32_t texture_2_id
The texture id to bind to slot #2. (Will be 0 if none)
Definition GPUDriver.h:165
IntRect scissor_rect
The scissor rect to use for scissor testing (units in pixels)
Definition GPUDriver.h:186
bool enable_blend
Whether or not we should enable blending for the current draw command.
Definition GPUDriver.h:153
Matrix4x4 transform
Transform matrix– you should multiply this with the screen-space orthographic projection matrix then ...
Definition GPUDriver.h:145
uint32_t render_buffer_id
The render buffer to use for the current draw command.
Definition GPUDriver.h:159
bool enable_texturing
Whether or not we should enable texturing for the current draw command.
Definition GPUDriver.h:148
bool enable_scissor
Whether or not scissor testing should be used for the current draw command.
Definition GPUDriver.h:183
ShaderType shader_type
The vertex/pixel shader program pair to use for the current draw command.
Definition GPUDriver.h:156
uint8_t clip_size
The clip size (passed to the pixel shader via uniforms).
Definition GPUDriver.h:177
uint32_t viewport_width
Viewport width in pixels.
Definition GPUDriver.h:138
Index buffer description.
Definition GPUDriver.h:111
uint32_t size
The size of the index buffer in bytes.
Definition GPUDriver.h:112
uint8_t * data
The raw index buffer data.
Definition GPUDriver.h:113
Integer Rectangle Helper.
Definition Geometry.h:529
4x4 Matrix Helper
Definition Matrix.h:18
Render buffer description.
Definition GPUDriver.h:32
bool has_depth_buffer
Currently unsued, always false.
Definition GPUDriver.h:37
uint32_t texture_id
The backing texture for this RenderBuffer.
Definition GPUDriver.h:33
uint32_t width
The width of the RenderBuffer texture.
Definition GPUDriver.h:34
bool has_stencil_buffer
Currently unused, always false.
Definition GPUDriver.h:36
uint32_t height
The height of the RenderBuffer texture.
Definition GPUDriver.h:35
Vertex layout for quad vertices.
Definition GPUDriver.h:58
float obj[2]
Definition GPUDriver.h:62
float data2[4]
Definition GPUDriver.h:65
float data3[4]
Definition GPUDriver.h:66
float data1[4]
Definition GPUDriver.h:64
float tex[2]
Definition GPUDriver.h:61
float data4[4]
Definition GPUDriver.h:67
unsigned char color[4]
Definition GPUDriver.h:60
float data5[4]
Definition GPUDriver.h:68
float data0[4]
Definition GPUDriver.h:63
float pos[2]
Definition GPUDriver.h:59
float data6[4]
Definition GPUDriver.h:69
Vertex layout for path vertices.
Definition GPUDriver.h:46
float obj[2]
Definition GPUDriver.h:49
unsigned char color[4]
Definition GPUDriver.h:48
float pos[2]
Definition GPUDriver.h:47
Vertex buffer description.
Definition GPUDriver.h:91
VertexBufferFormat format
The format of the vertex buffer.
Definition GPUDriver.h:92
uint32_t size
The size of the vertex buffer in bytes.
Definition GPUDriver.h:93
uint8_t * data
The raw vertex buffer data.
Definition GPUDriver.h:94
4D Vector Helper
Definition Geometry.h:283