| /* |
| Simple DirectMedia Layer |
| Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> |
| |
| This software is provided 'as-is', without any express or implied |
| warranty. In no event will the authors be held liable for any damages |
| arising from the use of this software. |
| |
| Permission is granted to anyone to use this software for any purpose, |
| including commercial applications, and to alter it and redistribute it |
| freely, subject to the following restrictions: |
| |
| 1. The origin of this software must not be misrepresented; you must not |
| claim that you wrote the original software. If you use this software |
| in a product, an acknowledgment in the product documentation would be |
| appreciated but is not required. |
| 2. Altered source versions must be plainly marked as such, and must not be |
| misrepresented as being the original software. |
| 3. This notice may not be removed or altered from any source distribution. |
| */ |
| #include "SDL_internal.h" |
| |
| #ifndef SDL_sysrender_h_ |
| #define SDL_sysrender_h_ |
| |
| #include "../video/SDL_surface_c.h" |
| |
| #include "SDL_yuv_sw_c.h" |
| |
| // Set up for C function definitions, even when using C++ |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /** |
| * A rectangle, with the origin at the upper left (double precision). |
| */ |
| typedef struct SDL_DRect |
| { |
| double x; |
| double y; |
| double w; |
| double h; |
| } SDL_DRect; |
| |
| // The SDL 2D rendering system |
| |
| typedef struct SDL_RenderDriver SDL_RenderDriver; |
| |
| // Rendering view state |
| typedef struct SDL_RenderViewState |
| { |
| int pixel_w; |
| int pixel_h; |
| SDL_Rect viewport; |
| SDL_Rect pixel_viewport; |
| SDL_Rect clip_rect; |
| SDL_Rect pixel_clip_rect; |
| bool clipping_enabled; |
| SDL_FPoint scale; |
| |
| // Support for logical output coordinates |
| SDL_RendererLogicalPresentation logical_presentation_mode; |
| int logical_w, logical_h; |
| SDL_FRect logical_src_rect; |
| SDL_FRect logical_dst_rect; |
| SDL_FPoint logical_scale; |
| SDL_FPoint logical_offset; |
| |
| SDL_FPoint current_scale; // this is just `scale * logical_scale`, precalculated, since we use it a lot. |
| } SDL_RenderViewState; |
| |
| // Define the SDL texture structure |
| struct SDL_Texture |
| { |
| // Public API definition |
| SDL_PixelFormat format; /**< The format of the texture, read-only */ |
| int w; /**< The width of the texture, read-only. */ |
| int h; /**< The height of the texture, read-only. */ |
| |
| int refcount; /**< Application reference count, used when freeing texture */ |
| |
| // Private API definition |
| SDL_Colorspace colorspace; // The colorspace of the texture |
| float SDR_white_point; // The SDR white point for this content |
| float HDR_headroom; // The HDR headroom needed by this content |
| SDL_TextureAccess access; // The texture access mode |
| SDL_BlendMode blendMode; // The texture blend mode |
| SDL_ScaleMode scaleMode; // The texture scale mode |
| SDL_FColor color; // Texture modulation values |
| SDL_RenderViewState view; // Target texture view state |
| |
| SDL_Renderer *renderer; |
| |
| // Support for formats not supported directly by the renderer |
| SDL_Texture *native; |
| SDL_SW_YUVTexture *yuv; |
| void *pixels; |
| int pitch; |
| SDL_Rect locked_rect; |
| SDL_Surface *locked_surface; // Locked region exposed as a SDL surface |
| |
| Uint32 last_command_generation; // last command queue generation this texture was in. |
| |
| SDL_PropertiesID props; |
| |
| void *internal; // Driver specific texture representation |
| |
| SDL_Texture *prev; |
| SDL_Texture *next; |
| }; |
| |
| // Define the GPU render state structure |
| typedef struct SDL_GPURenderStateUniformBuffer |
| { |
| Uint32 slot_index; |
| void *data; |
| Uint32 length; |
| } SDL_GPURenderStateUniformBuffer; |
| |
| // Define the GPU render state structure |
| struct SDL_GPURenderState |
| { |
| SDL_Renderer *renderer; |
| |
| Uint32 last_command_generation; // last command queue generation this state was in. |
| |
| SDL_GPUShader *fragment_shader; |
| |
| int num_sampler_bindings; |
| SDL_GPUTextureSamplerBinding *sampler_bindings; |
| |
| int num_storage_textures; |
| SDL_GPUTexture **storage_textures; |
| |
| int num_storage_buffers; |
| SDL_GPUBuffer **storage_buffers; |
| |
| int num_uniform_buffers; |
| SDL_GPURenderStateUniformBuffer *uniform_buffers; |
| }; |
| |
| typedef enum |
| { |
| SDL_RENDERCMD_NO_OP, |
| SDL_RENDERCMD_SETVIEWPORT, |
| SDL_RENDERCMD_SETCLIPRECT, |
| SDL_RENDERCMD_SETDRAWCOLOR, |
| SDL_RENDERCMD_CLEAR, |
| SDL_RENDERCMD_DRAW_POINTS, |
| SDL_RENDERCMD_DRAW_LINES, |
| SDL_RENDERCMD_FILL_RECTS, |
| SDL_RENDERCMD_COPY, |
| SDL_RENDERCMD_COPY_EX, |
| SDL_RENDERCMD_GEOMETRY |
| } SDL_RenderCommandType; |
| |
| typedef struct SDL_RenderCommand |
| { |
| SDL_RenderCommandType command; |
| union |
| { |
| struct |
| { |
| size_t first; |
| SDL_Rect rect; |
| } viewport; |
| struct |
| { |
| bool enabled; |
| SDL_Rect rect; |
| } cliprect; |
| struct |
| { |
| size_t first; |
| size_t count; |
| float color_scale; |
| SDL_FColor color; |
| SDL_BlendMode blend; |
| SDL_Texture *texture; |
| SDL_ScaleMode texture_scale_mode; |
| SDL_TextureAddressMode texture_address_mode_u; |
| SDL_TextureAddressMode texture_address_mode_v; |
| SDL_GPURenderState *gpu_render_state; |
| } draw; |
| struct |
| { |
| size_t first; |
| float color_scale; |
| SDL_FColor color; |
| } color; |
| } data; |
| struct SDL_RenderCommand *next; |
| } SDL_RenderCommand; |
| |
| typedef struct SDL_VertexSolid |
| { |
| SDL_FPoint position; |
| SDL_FColor color; |
| } SDL_VertexSolid; |
| |
| typedef enum |
| { |
| SDL_RENDERLINEMETHOD_POINTS, |
| SDL_RENDERLINEMETHOD_LINES, |
| SDL_RENDERLINEMETHOD_GEOMETRY, |
| } SDL_RenderLineMethod; |
| |
| // Define the SDL renderer structure |
| struct SDL_Renderer |
| { |
| void (*WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event); |
| bool (*GetOutputSize)(SDL_Renderer *renderer, int *w, int *h); |
| bool (*SupportsBlendMode)(SDL_Renderer *renderer, SDL_BlendMode blendMode); |
| bool (*CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, SDL_PropertiesID create_props); |
| bool (*QueueSetViewport)(SDL_Renderer *renderer, SDL_RenderCommand *cmd); |
| bool (*QueueSetDrawColor)(SDL_Renderer *renderer, SDL_RenderCommand *cmd); |
| bool (*QueueDrawPoints)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, |
| int count); |
| bool (*QueueDrawLines)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, |
| int count); |
| bool (*QueueFillRects)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FRect *rects, |
| int count); |
| bool (*QueueCopy)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, |
| const SDL_FRect *srcrect, const SDL_FRect *dstrect); |
| bool (*QueueCopyEx)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, |
| const SDL_FRect *srcquad, const SDL_FRect *dstrect, |
| const double angle, const SDL_FPoint *center, const SDL_FlipMode flip, float scale_x, float scale_y); |
| bool (*QueueGeometry)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, |
| const float *xy, int xy_stride, const SDL_FColor *color, int color_stride, const float *uv, int uv_stride, |
| int num_vertices, const void *indices, int num_indices, int size_indices, |
| float scale_x, float scale_y); |
| |
| void (*InvalidateCachedState)(SDL_Renderer *renderer); |
| bool (*RunCommandQueue)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize); |
| bool (*UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, |
| const SDL_Rect *rect, const void *pixels, |
| int pitch); |
| #ifdef SDL_HAVE_YUV |
| bool (*UpdateTextureYUV)(SDL_Renderer *renderer, SDL_Texture *texture, |
| const SDL_Rect *rect, |
| const Uint8 *Yplane, int Ypitch, |
| const Uint8 *Uplane, int Upitch, |
| const Uint8 *Vplane, int Vpitch); |
| bool (*UpdateTextureNV)(SDL_Renderer *renderer, SDL_Texture *texture, |
| const SDL_Rect *rect, |
| const Uint8 *Yplane, int Ypitch, |
| const Uint8 *UVplane, int UVpitch); |
| #endif |
| bool (*LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, |
| const SDL_Rect *rect, void **pixels, int *pitch); |
| void (*UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture); |
| bool (*SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture); |
| SDL_Surface *(*RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect); |
| bool (*RenderPresent)(SDL_Renderer *renderer); |
| void (*DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture); |
| |
| void (*DestroyRenderer)(SDL_Renderer *renderer); |
| |
| bool (*SetVSync)(SDL_Renderer *renderer, int vsync); |
| |
| void *(*GetMetalLayer)(SDL_Renderer *renderer); |
| void *(*GetMetalCommandEncoder)(SDL_Renderer *renderer); |
| |
| bool (*AddVulkanRenderSemaphores)(SDL_Renderer *renderer, Uint32 wait_stage_mask, Sint64 wait_semaphore, Sint64 signal_semaphore); |
| |
| // The current renderer info |
| const char *name; |
| SDL_PixelFormat *texture_formats; |
| int num_texture_formats; |
| bool software; |
| |
| // The window associated with the renderer |
| SDL_Window *window; |
| bool hidden; |
| |
| // Whether we should simulate vsync |
| bool wanted_vsync; |
| bool simulate_vsync; |
| Uint64 simulate_vsync_interval_ns; |
| Uint64 last_present; |
| |
| SDL_RenderViewState *view; |
| SDL_RenderViewState main_view; |
| |
| // The window pixel to point coordinate scale |
| SDL_FPoint dpi_scale; |
| |
| // The method of drawing lines |
| SDL_RenderLineMethod line_method; |
| |
| // Default scale mode for textures created with this renderer |
| SDL_ScaleMode scale_mode; |
| |
| // The list of textures |
| SDL_Texture *textures; |
| SDL_Texture *target; |
| SDL_Mutex *target_mutex; |
| |
| SDL_Colorspace output_colorspace; |
| float SDR_white_point; |
| float HDR_headroom; |
| |
| float desired_color_scale; |
| float color_scale; |
| SDL_FColor color; /**< Color for drawing operations values */ |
| SDL_BlendMode blendMode; /**< The drawing blend mode */ |
| SDL_TextureAddressMode texture_address_mode_u; |
| SDL_TextureAddressMode texture_address_mode_v; |
| SDL_GPURenderState *gpu_render_state; |
| |
| SDL_RenderCommand *render_commands; |
| SDL_RenderCommand *render_commands_tail; |
| SDL_RenderCommand *render_commands_pool; |
| Uint32 render_command_generation; |
| SDL_FColor last_queued_color; |
| float last_queued_color_scale; |
| SDL_Rect last_queued_viewport; |
| SDL_Rect last_queued_cliprect; |
| bool last_queued_cliprect_enabled; |
| bool color_queued; |
| bool viewport_queued; |
| bool cliprect_queued; |
| |
| void *vertex_data; |
| size_t vertex_data_used; |
| size_t vertex_data_allocation; |
| |
| // Shaped window support |
| bool transparent_window; |
| SDL_Surface *shape_surface; |
| SDL_Texture *shape_texture; |
| |
| SDL_PropertiesID props; |
| |
| SDL_Texture *debug_char_texture_atlas; |
| |
| bool destroyed; // already destroyed by SDL_DestroyWindow; just free this struct in SDL_DestroyRenderer. |
| |
| void *internal; |
| |
| SDL_Renderer *next; |
| }; |
| |
| // Define the SDL render driver structure |
| struct SDL_RenderDriver |
| { |
| bool (*CreateRenderer)(SDL_Renderer *renderer, SDL_Window *window, SDL_PropertiesID props); |
| |
| const char *name; |
| }; |
| |
| // Not all of these are available in a given build. Use #ifdefs, etc. |
| extern SDL_RenderDriver D3D_RenderDriver; |
| extern SDL_RenderDriver D3D11_RenderDriver; |
| extern SDL_RenderDriver D3D12_RenderDriver; |
| extern SDL_RenderDriver GL_RenderDriver; |
| extern SDL_RenderDriver GLES2_RenderDriver; |
| extern SDL_RenderDriver METAL_RenderDriver; |
| extern SDL_RenderDriver NGAGE_RenderDriver; |
| extern SDL_RenderDriver VULKAN_RenderDriver; |
| extern SDL_RenderDriver PS2_RenderDriver; |
| extern SDL_RenderDriver PSP_RenderDriver; |
| extern SDL_RenderDriver SW_RenderDriver; |
| extern SDL_RenderDriver VITA_GXM_RenderDriver; |
| extern SDL_RenderDriver GPU_RenderDriver; |
| |
| // Clean up any renderers at shutdown |
| extern void SDL_QuitRender(void); |
| |
| #define RENDER_SAMPLER_HASHKEY(scale_mode, address_u, address_v) \ |
| (((scale_mode == SDL_SCALEMODE_NEAREST) << 0) | \ |
| ((address_u == SDL_TEXTURE_ADDRESS_WRAP) << 1) | \ |
| ((address_v == SDL_TEXTURE_ADDRESS_WRAP) << 2)) |
| #define RENDER_SAMPLER_COUNT (((1 << 0) | (1 << 1) | (1 << 2)) + 1) |
| |
| // Add a supported texture format to a renderer |
| extern bool SDL_AddSupportedTextureFormat(SDL_Renderer *renderer, SDL_PixelFormat format); |
| |
| // Setup colorspace conversion |
| extern void SDL_SetupRendererColorspace(SDL_Renderer *renderer, SDL_PropertiesID props); |
| |
| // Colorspace conversion functions |
| extern bool SDL_RenderingLinearSpace(SDL_Renderer *renderer); |
| extern void SDL_ConvertToLinear(SDL_FColor *color); |
| extern void SDL_ConvertFromLinear(SDL_FColor *color); |
| |
| // Blend mode functions |
| extern SDL_BlendFactor SDL_GetBlendModeSrcColorFactor(SDL_BlendMode blendMode); |
| extern SDL_BlendFactor SDL_GetBlendModeDstColorFactor(SDL_BlendMode blendMode); |
| extern SDL_BlendOperation SDL_GetBlendModeColorOperation(SDL_BlendMode blendMode); |
| extern SDL_BlendFactor SDL_GetBlendModeSrcAlphaFactor(SDL_BlendMode blendMode); |
| extern SDL_BlendFactor SDL_GetBlendModeDstAlphaFactor(SDL_BlendMode blendMode); |
| extern SDL_BlendOperation SDL_GetBlendModeAlphaOperation(SDL_BlendMode blendMode); |
| |
| /* drivers call this during their Queue*() methods to make space in a array that are used |
| for a vertex buffer during RunCommandQueue(). Pointers returned here are only valid until |
| the next call, because it might be in an array that gets realloc()'d. */ |
| extern void *SDL_AllocateRenderVertices(SDL_Renderer *renderer, size_t numbytes, size_t alignment, size_t *offset); |
| |
| // Let the video subsystem destroy a renderer without making its pointer invalid. |
| extern void SDL_DestroyRendererWithoutFreeing(SDL_Renderer *renderer); |
| |
| // Ends C function definitions when using C++ |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif // SDL_sysrender_h_ |