1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "SDL_internal.h"
22
23#ifndef SDL_sysrender_h_
24#define SDL_sysrender_h_
25
26#include "../video/SDL_surface_c.h"
27
28#include "SDL_yuv_sw_c.h"
29
30// Set up for C function definitions, even when using C++
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35typedef enum SDL_TextureAddressMode
36{
37 SDL_TEXTURE_ADDRESS_INVALID = -1,
38 SDL_TEXTURE_ADDRESS_AUTO,
39 SDL_TEXTURE_ADDRESS_CLAMP,
40 SDL_TEXTURE_ADDRESS_WRAP,
41} SDL_TextureAddressMode;
42
43/**
44 * A rectangle, with the origin at the upper left (double precision).
45 */
46typedef struct SDL_DRect
47{
48 double x;
49 double y;
50 double w;
51 double h;
52} SDL_DRect;
53
54// The SDL 2D rendering system
55
56typedef struct SDL_RenderDriver SDL_RenderDriver;
57
58// Rendering view state
59typedef struct SDL_RenderViewState
60{
61 int pixel_w;
62 int pixel_h;
63 SDL_Rect viewport;
64 SDL_Rect pixel_viewport;
65 SDL_Rect clip_rect;
66 SDL_Rect pixel_clip_rect;
67 bool clipping_enabled;
68 SDL_FPoint scale;
69
70 // Support for logical output coordinates
71 SDL_RendererLogicalPresentation logical_presentation_mode;
72 int logical_w, logical_h;
73 SDL_FRect logical_src_rect;
74 SDL_FRect logical_dst_rect;
75 SDL_FPoint logical_scale;
76 SDL_FPoint logical_offset;
77
78 SDL_FPoint current_scale; // this is just `scale * logical_scale`, precalculated, since we use it a lot.
79} SDL_RenderViewState;
80
81// Define the SDL texture structure
82struct SDL_Texture
83{
84 // Public API definition
85 SDL_PixelFormat format; /**< The format of the texture, read-only */
86 int w; /**< The width of the texture, read-only. */
87 int h; /**< The height of the texture, read-only. */
88
89 int refcount; /**< Application reference count, used when freeing texture */
90
91 // Private API definition
92 SDL_Colorspace colorspace; // The colorspace of the texture
93 float SDR_white_point; // The SDR white point for this content
94 float HDR_headroom; // The HDR headroom needed by this content
95 SDL_TextureAccess access; // The texture access mode
96 SDL_BlendMode blendMode; // The texture blend mode
97 SDL_ScaleMode scaleMode; // The texture scale mode
98 SDL_FColor color; // Texture modulation values
99 SDL_RenderViewState view; // Target texture view state
100
101 SDL_Renderer *renderer;
102
103 // Support for formats not supported directly by the renderer
104 SDL_Texture *native;
105 SDL_SW_YUVTexture *yuv;
106 void *pixels;
107 int pitch;
108 SDL_Rect locked_rect;
109 SDL_Surface *locked_surface; // Locked region exposed as a SDL surface
110
111 Uint32 last_command_generation; // last command queue generation this texture was in.
112
113 SDL_PropertiesID props;
114
115 void *internal; // Driver specific texture representation
116
117 SDL_Texture *prev;
118 SDL_Texture *next;
119};
120
121// Define the GPU render state structure
122typedef struct SDL_GPURenderStateUniformBuffer
123{
124 Uint32 slot_index;
125 void *data;
126 Uint32 length;
127} SDL_GPURenderStateUniformBuffer;
128
129// Define the GPU render state structure
130struct SDL_GPURenderState
131{
132 SDL_Renderer *renderer;
133
134 Uint32 last_command_generation; // last command queue generation this state was in.
135
136 SDL_GPUShader *fragment_shader;
137
138 int num_sampler_bindings;
139 SDL_GPUTextureSamplerBinding *sampler_bindings;
140
141 int num_storage_textures;
142 SDL_GPUTexture **storage_textures;
143
144 int num_storage_buffers;
145 SDL_GPUBuffer **storage_buffers;
146
147 int num_uniform_buffers;
148 SDL_GPURenderStateUniformBuffer *uniform_buffers;
149};
150
151typedef enum
152{
153 SDL_RENDERCMD_NO_OP,
154 SDL_RENDERCMD_SETVIEWPORT,
155 SDL_RENDERCMD_SETCLIPRECT,
156 SDL_RENDERCMD_SETDRAWCOLOR,
157 SDL_RENDERCMD_CLEAR,
158 SDL_RENDERCMD_DRAW_POINTS,
159 SDL_RENDERCMD_DRAW_LINES,
160 SDL_RENDERCMD_FILL_RECTS,
161 SDL_RENDERCMD_COPY,
162 SDL_RENDERCMD_COPY_EX,
163 SDL_RENDERCMD_GEOMETRY
164} SDL_RenderCommandType;
165
166typedef struct SDL_RenderCommand
167{
168 SDL_RenderCommandType command;
169 union
170 {
171 struct
172 {
173 size_t first;
174 SDL_Rect rect;
175 } viewport;
176 struct
177 {
178 bool enabled;
179 SDL_Rect rect;
180 } cliprect;
181 struct
182 {
183 size_t first;
184 size_t count;
185 float color_scale;
186 SDL_FColor color;
187 SDL_BlendMode blend;
188 SDL_Texture *texture;
189 SDL_ScaleMode texture_scale_mode;
190 SDL_TextureAddressMode texture_address_mode;
191 SDL_GPURenderState *gpu_render_state;
192 } draw;
193 struct
194 {
195 size_t first;
196 float color_scale;
197 SDL_FColor color;
198 } color;
199 } data;
200 struct SDL_RenderCommand *next;
201} SDL_RenderCommand;
202
203typedef struct SDL_VertexSolid
204{
205 SDL_FPoint position;
206 SDL_FColor color;
207} SDL_VertexSolid;
208
209typedef enum
210{
211 SDL_RENDERLINEMETHOD_POINTS,
212 SDL_RENDERLINEMETHOD_LINES,
213 SDL_RENDERLINEMETHOD_GEOMETRY,
214} SDL_RenderLineMethod;
215
216// Define the SDL renderer structure
217struct SDL_Renderer
218{
219 void (*WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event);
220 bool (*GetOutputSize)(SDL_Renderer *renderer, int *w, int *h);
221 bool (*SupportsBlendMode)(SDL_Renderer *renderer, SDL_BlendMode blendMode);
222 bool (*CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, SDL_PropertiesID create_props);
223 bool (*QueueSetViewport)(SDL_Renderer *renderer, SDL_RenderCommand *cmd);
224 bool (*QueueSetDrawColor)(SDL_Renderer *renderer, SDL_RenderCommand *cmd);
225 bool (*QueueDrawPoints)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points,
226 int count);
227 bool (*QueueDrawLines)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points,
228 int count);
229 bool (*QueueFillRects)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FRect *rects,
230 int count);
231 bool (*QueueCopy)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
232 const SDL_FRect *srcrect, const SDL_FRect *dstrect);
233 bool (*QueueCopyEx)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
234 const SDL_FRect *srcquad, const SDL_FRect *dstrect,
235 const double angle, const SDL_FPoint *center, const SDL_FlipMode flip, float scale_x, float scale_y);
236 bool (*QueueGeometry)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
237 const float *xy, int xy_stride, const SDL_FColor *color, int color_stride, const float *uv, int uv_stride,
238 int num_vertices, const void *indices, int num_indices, int size_indices,
239 float scale_x, float scale_y);
240
241 void (*InvalidateCachedState)(SDL_Renderer *renderer);
242 bool (*RunCommandQueue)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize);
243 bool (*UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture,
244 const SDL_Rect *rect, const void *pixels,
245 int pitch);
246#ifdef SDL_HAVE_YUV
247 bool (*UpdateTextureYUV)(SDL_Renderer *renderer, SDL_Texture *texture,
248 const SDL_Rect *rect,
249 const Uint8 *Yplane, int Ypitch,
250 const Uint8 *Uplane, int Upitch,
251 const Uint8 *Vplane, int Vpitch);
252 bool (*UpdateTextureNV)(SDL_Renderer *renderer, SDL_Texture *texture,
253 const SDL_Rect *rect,
254 const Uint8 *Yplane, int Ypitch,
255 const Uint8 *UVplane, int UVpitch);
256#endif
257 bool (*LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture,
258 const SDL_Rect *rect, void **pixels, int *pitch);
259 void (*UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture);
260 bool (*SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture);
261 SDL_Surface *(*RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect);
262 bool (*RenderPresent)(SDL_Renderer *renderer);
263 void (*DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture);
264
265 void (*DestroyRenderer)(SDL_Renderer *renderer);
266
267 bool (*SetVSync)(SDL_Renderer *renderer, int vsync);
268
269 void *(*GetMetalLayer)(SDL_Renderer *renderer);
270 void *(*GetMetalCommandEncoder)(SDL_Renderer *renderer);
271
272 bool (*AddVulkanRenderSemaphores)(SDL_Renderer *renderer, Uint32 wait_stage_mask, Sint64 wait_semaphore, Sint64 signal_semaphore);
273
274 // The current renderer info
275 const char *name;
276 SDL_PixelFormat *texture_formats;
277 int num_texture_formats;
278 bool software;
279
280 // The window associated with the renderer
281 SDL_Window *window;
282 bool hidden;
283
284 // Whether we should simulate vsync
285 bool wanted_vsync;
286 bool simulate_vsync;
287 Uint64 simulate_vsync_interval_ns;
288 Uint64 last_present;
289
290 SDL_RenderViewState *view;
291 SDL_RenderViewState main_view;
292
293 // The window pixel to point coordinate scale
294 SDL_FPoint dpi_scale;
295
296 // The method of drawing lines
297 SDL_RenderLineMethod line_method;
298
299 // Default scale mode for textures created with this renderer
300 SDL_ScaleMode scale_mode;
301
302 // The list of textures
303 SDL_Texture *textures;
304 SDL_Texture *target;
305 SDL_Mutex *target_mutex;
306
307 SDL_Colorspace output_colorspace;
308 float SDR_white_point;
309 float HDR_headroom;
310
311 float desired_color_scale;
312 float color_scale;
313 SDL_FColor color; /**< Color for drawing operations values */
314 SDL_BlendMode blendMode; /**< The drawing blend mode */
315 SDL_TextureAddressMode texture_address_mode;
316 SDL_GPURenderState *gpu_render_state;
317
318 SDL_RenderCommand *render_commands;
319 SDL_RenderCommand *render_commands_tail;
320 SDL_RenderCommand *render_commands_pool;
321 Uint32 render_command_generation;
322 SDL_FColor last_queued_color;
323 float last_queued_color_scale;
324 SDL_Rect last_queued_viewport;
325 SDL_Rect last_queued_cliprect;
326 bool last_queued_cliprect_enabled;
327 bool color_queued;
328 bool viewport_queued;
329 bool cliprect_queued;
330
331 void *vertex_data;
332 size_t vertex_data_used;
333 size_t vertex_data_allocation;
334
335 // Shaped window support
336 bool transparent_window;
337 SDL_Surface *shape_surface;
338 SDL_Texture *shape_texture;
339
340 SDL_PropertiesID props;
341
342 SDL_Texture *debug_char_texture_atlas;
343
344 bool destroyed; // already destroyed by SDL_DestroyWindow; just free this struct in SDL_DestroyRenderer.
345
346 void *internal;
347
348 SDL_Renderer *next;
349};
350
351// Define the SDL render driver structure
352struct SDL_RenderDriver
353{
354 bool (*CreateRenderer)(SDL_Renderer *renderer, SDL_Window *window, SDL_PropertiesID props);
355
356 const char *name;
357};
358
359// Not all of these are available in a given build. Use #ifdefs, etc.
360extern SDL_RenderDriver D3D_RenderDriver;
361extern SDL_RenderDriver D3D11_RenderDriver;
362extern SDL_RenderDriver D3D12_RenderDriver;
363extern SDL_RenderDriver GL_RenderDriver;
364extern SDL_RenderDriver GLES2_RenderDriver;
365extern SDL_RenderDriver METAL_RenderDriver;
366extern SDL_RenderDriver VULKAN_RenderDriver;
367extern SDL_RenderDriver PS2_RenderDriver;
368extern SDL_RenderDriver PSP_RenderDriver;
369extern SDL_RenderDriver SW_RenderDriver;
370extern SDL_RenderDriver VITA_GXM_RenderDriver;
371extern SDL_RenderDriver GPU_RenderDriver;
372
373// Clean up any renderers at shutdown
374extern void SDL_QuitRender(void);
375
376// Add a supported texture format to a renderer
377extern bool SDL_AddSupportedTextureFormat(SDL_Renderer *renderer, SDL_PixelFormat format);
378
379// Setup colorspace conversion
380extern void SDL_SetupRendererColorspace(SDL_Renderer *renderer, SDL_PropertiesID props);
381
382// Colorspace conversion functions
383extern bool SDL_RenderingLinearSpace(SDL_Renderer *renderer);
384extern void SDL_ConvertToLinear(SDL_FColor *color);
385extern void SDL_ConvertFromLinear(SDL_FColor *color);
386
387// Blend mode functions
388extern SDL_BlendFactor SDL_GetBlendModeSrcColorFactor(SDL_BlendMode blendMode);
389extern SDL_BlendFactor SDL_GetBlendModeDstColorFactor(SDL_BlendMode blendMode);
390extern SDL_BlendOperation SDL_GetBlendModeColorOperation(SDL_BlendMode blendMode);
391extern SDL_BlendFactor SDL_GetBlendModeSrcAlphaFactor(SDL_BlendMode blendMode);
392extern SDL_BlendFactor SDL_GetBlendModeDstAlphaFactor(SDL_BlendMode blendMode);
393extern SDL_BlendOperation SDL_GetBlendModeAlphaOperation(SDL_BlendMode blendMode);
394
395/* drivers call this during their Queue*() methods to make space in a array that are used
396 for a vertex buffer during RunCommandQueue(). Pointers returned here are only valid until
397 the next call, because it might be in an array that gets realloc()'d. */
398extern void *SDL_AllocateRenderVertices(SDL_Renderer *renderer, size_t numbytes, size_t alignment, size_t *offset);
399
400// Let the video subsystem destroy a renderer without making its pointer invalid.
401extern void SDL_DestroyRendererWithoutFreeing(SDL_Renderer *renderer);
402
403// Ends C function definitions when using C++
404#ifdef __cplusplus
405}
406#endif
407
408#endif // SDL_sysrender_h_
409