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 |
32 | extern "C" { |
33 | #endif |
34 | |
35 | typedef 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 | */ |
46 | typedef 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 | |
56 | typedef struct SDL_RenderDriver SDL_RenderDriver; |
57 | |
58 | // Rendering view state |
59 | typedef 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 |
82 | struct 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 |
122 | typedef 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 |
130 | struct 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 | |
151 | typedef 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 | |
166 | typedef 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 | |
203 | typedef struct SDL_VertexSolid |
204 | { |
205 | SDL_FPoint position; |
206 | SDL_FColor color; |
207 | } SDL_VertexSolid; |
208 | |
209 | typedef enum |
210 | { |
211 | SDL_RENDERLINEMETHOD_POINTS, |
212 | SDL_RENDERLINEMETHOD_LINES, |
213 | SDL_RENDERLINEMETHOD_GEOMETRY, |
214 | } SDL_RenderLineMethod; |
215 | |
216 | // Define the SDL renderer structure |
217 | struct 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 |
352 | struct 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. |
360 | extern SDL_RenderDriver D3D_RenderDriver; |
361 | extern SDL_RenderDriver D3D11_RenderDriver; |
362 | extern SDL_RenderDriver D3D12_RenderDriver; |
363 | extern SDL_RenderDriver GL_RenderDriver; |
364 | extern SDL_RenderDriver GLES2_RenderDriver; |
365 | extern SDL_RenderDriver METAL_RenderDriver; |
366 | extern SDL_RenderDriver VULKAN_RenderDriver; |
367 | extern SDL_RenderDriver PS2_RenderDriver; |
368 | extern SDL_RenderDriver PSP_RenderDriver; |
369 | extern SDL_RenderDriver SW_RenderDriver; |
370 | extern SDL_RenderDriver VITA_GXM_RenderDriver; |
371 | extern SDL_RenderDriver GPU_RenderDriver; |
372 | |
373 | // Clean up any renderers at shutdown |
374 | extern void SDL_QuitRender(void); |
375 | |
376 | // Add a supported texture format to a renderer |
377 | extern bool SDL_AddSupportedTextureFormat(SDL_Renderer *renderer, SDL_PixelFormat format); |
378 | |
379 | // Setup colorspace conversion |
380 | extern void SDL_SetupRendererColorspace(SDL_Renderer *renderer, SDL_PropertiesID props); |
381 | |
382 | // Colorspace conversion functions |
383 | extern bool SDL_RenderingLinearSpace(SDL_Renderer *renderer); |
384 | extern void SDL_ConvertToLinear(SDL_FColor *color); |
385 | extern void SDL_ConvertFromLinear(SDL_FColor *color); |
386 | |
387 | // Blend mode functions |
388 | extern SDL_BlendFactor SDL_GetBlendModeSrcColorFactor(SDL_BlendMode blendMode); |
389 | extern SDL_BlendFactor SDL_GetBlendModeDstColorFactor(SDL_BlendMode blendMode); |
390 | extern SDL_BlendOperation SDL_GetBlendModeColorOperation(SDL_BlendMode blendMode); |
391 | extern SDL_BlendFactor SDL_GetBlendModeSrcAlphaFactor(SDL_BlendMode blendMode); |
392 | extern SDL_BlendFactor SDL_GetBlendModeDstAlphaFactor(SDL_BlendMode blendMode); |
393 | extern 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. */ |
398 | extern 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. |
401 | extern 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 | |