mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-03-09 18:45:35 +00:00
render: Add Suspend/Resume calls for GDK support
This commit is contained in:
@@ -667,9 +667,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_UnregisterApp(void);
|
||||
* This should be called from an event watch in response to an
|
||||
* `SDL_EVENT_DID_ENTER_BACKGROUND` event.
|
||||
*
|
||||
* When using SDL_Render, your event watch should be added _after_ creating
|
||||
* the `SDL_Renderer`; this allows the timing of the D3D12 command queue
|
||||
* suspension to execute in the correct order.
|
||||
* When using SDL_Render, this should be called after calling SDL_GDKSuspendRenderer.
|
||||
*
|
||||
* When using SDL_GPU, this should be called after calling SDL_GDKSuspendGPU.
|
||||
*
|
||||
|
||||
@@ -3082,6 +3082,40 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetGPURenderState(SDL_Renderer *renderer, S
|
||||
*/
|
||||
extern SDL_DECLSPEC void SDLCALL SDL_DestroyGPURenderState(SDL_GPURenderState *state);
|
||||
|
||||
#ifdef SDL_PLATFORM_GDK
|
||||
|
||||
/**
|
||||
* Call this to suspend Render operations on Xbox when you receive the
|
||||
* SDL_EVENT_DID_ENTER_BACKGROUND event.
|
||||
*
|
||||
* Do NOT call any SDL_Render functions after calling this function! This must
|
||||
* also be called before calling SDL_GDKSuspendComplete.
|
||||
*
|
||||
* \param renderer the renderer which should suspend operation
|
||||
*
|
||||
* \since This function is available since SDL 3.6.0.
|
||||
*
|
||||
* \sa SDL_AddEventWatch
|
||||
*/
|
||||
extern SDL_DECLSPEC void SDLCALL SDL_GDKSuspendRenderer(SDL_Renderer *renderer);
|
||||
|
||||
/**
|
||||
* Call this to resume Render operations on Xbox when you receive the
|
||||
* SDL_EVENT_WILL_ENTER_FOREGROUND event.
|
||||
*
|
||||
* When resuming, this function MUST be called before calling any other
|
||||
* SDL_Render functions.
|
||||
*
|
||||
* \param renderer the renderer which should resume operation
|
||||
*
|
||||
* \since This function is available since SDL 3.6.0.
|
||||
*
|
||||
* \sa SDL_AddEventWatch
|
||||
*/
|
||||
extern SDL_DECLSPEC void SDLCALL SDL_GDKResumeRenderer(SDL_Renderer *renderer);
|
||||
|
||||
#endif /* SDL_PLATFORM_GDK */
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -69,6 +69,14 @@ void SDL_GDKResumeGPU(SDL_GPUDevice *device)
|
||||
{
|
||||
}
|
||||
|
||||
void SDL_GDKSuspendRenderer(SDL_Renderer *renderer)
|
||||
{
|
||||
}
|
||||
|
||||
void SDL_GDKResumeRenderer(SDL_Renderer *renderer)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* !SDL_PLATFORM_GDK */
|
||||
|
||||
#if !defined(SDL_PLATFORM_WINDOWS)
|
||||
|
||||
@@ -35,6 +35,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_GDKSuspendComplete(void);
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_GetGDKDefaultUser(XUserHandle *outUserHandle);
|
||||
extern SDL_DECLSPEC void SDLCALL SDL_GDKSuspendGPU(SDL_GPUDevice *device);
|
||||
extern SDL_DECLSPEC void SDLCALL SDL_GDKResumeGPU(SDL_GPUDevice *device);
|
||||
extern SDL_DECLSPEC void SDLCALL SDL_GDKSuspendRenderer(SDL_Renderer *renderer);
|
||||
extern SDL_DECLSPEC void SDLCALL SDL_GDKResumeRenderer(SDL_Renderer *renderer);
|
||||
#endif /* !SDL_PLATFORM_GDK */
|
||||
|
||||
#if !defined(SDL_PLATFORM_WINDOWS)
|
||||
|
||||
@@ -1283,6 +1283,8 @@ SDL3_0.0.0 {
|
||||
SDL_SetGPURenderStateSamplerBindings;
|
||||
SDL_SetGPURenderStateStorageTextures;
|
||||
SDL_SetGPURenderStateStorageBuffers;
|
||||
SDL_GDKSuspendRenderer;
|
||||
SDL_GDKResumeRenderer;
|
||||
# extra symbols go here (don't modify this line)
|
||||
local: *;
|
||||
};
|
||||
|
||||
@@ -1309,3 +1309,5 @@
|
||||
#define SDL_SetGPURenderStateSamplerBindings SDL_SetGPURenderStateSamplerBindings_REAL
|
||||
#define SDL_SetGPURenderStateStorageTextures SDL_SetGPURenderStateStorageTextures_REAL
|
||||
#define SDL_SetGPURenderStateStorageBuffers SDL_SetGPURenderStateStorageBuffers_REAL
|
||||
#define SDL_GDKSuspendRenderer SDL_GDKSuspendRenderer_REAL
|
||||
#define SDL_GDKResumeRenderer SDL_GDKResumeRenderer_REAL
|
||||
|
||||
@@ -1317,3 +1317,5 @@ SDL_DYNAPI_PROC(SDL_Tray*,SDL_CreateTrayWithProperties,(SDL_PropertiesID a),(a),
|
||||
SDL_DYNAPI_PROC(bool,SDL_SetGPURenderStateSamplerBindings,(SDL_GPURenderState *a,int b,const SDL_GPUTextureSamplerBinding *c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(bool,SDL_SetGPURenderStateStorageTextures,(SDL_GPURenderState *a,int b,SDL_GPUTexture *const*c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(bool,SDL_SetGPURenderStateStorageBuffers,(SDL_GPURenderState *a,int b,SDL_GPUBuffer *const*c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(void,SDL_GDKSuspendRenderer,(SDL_Renderer *a),(a),)
|
||||
SDL_DYNAPI_PROC(void,SDL_GDKResumeRenderer,(SDL_Renderer *a),(a),)
|
||||
|
||||
@@ -6347,3 +6347,23 @@ void SDL_DestroyGPURenderState(SDL_GPURenderState *state)
|
||||
SDL_free(state->storage_buffers);
|
||||
SDL_free(state);
|
||||
}
|
||||
|
||||
#ifdef SDL_PLATFORM_GDK
|
||||
|
||||
void SDLCALL SDL_GDKSuspendRenderer(SDL_Renderer *renderer)
|
||||
{
|
||||
CHECK_RENDERER_MAGIC(renderer,);
|
||||
if (renderer->GDKSuspendRenderer != NULL) {
|
||||
renderer->GDKSuspendRenderer(renderer);
|
||||
}
|
||||
}
|
||||
|
||||
void SDLCALL SDL_GDKResumeRenderer(SDL_Renderer *renderer)
|
||||
{
|
||||
CHECK_RENDERER_MAGIC(renderer,);
|
||||
if (renderer->GDKResumeRenderer != NULL) {
|
||||
renderer->GDKResumeRenderer(renderer);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_PLATFORM_GDK */
|
||||
|
||||
@@ -280,6 +280,11 @@ struct SDL_Renderer
|
||||
|
||||
bool (*AddVulkanRenderSemaphores)(SDL_Renderer *renderer, Uint32 wait_stage_mask, Sint64 wait_semaphore, Sint64 signal_semaphore);
|
||||
|
||||
#ifdef SDL_PLATFORM_GDK
|
||||
void (*GDKSuspendRenderer)(SDL_Renderer *renderer);
|
||||
void (*GDKResumeRenderer)(SDL_Renderer *renderer);
|
||||
#endif
|
||||
|
||||
// The current renderer info
|
||||
const char *name;
|
||||
SDL_PixelFormat *texture_formats;
|
||||
|
||||
@@ -563,25 +563,25 @@ static HRESULT D3D12_IssueBatch(D3D12_RenderData *data)
|
||||
}
|
||||
|
||||
#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
|
||||
static bool SDLCALL D3D12_GDKEventFilter(void* userdata, SDL_Event* event)
|
||||
|
||||
static void D3D12_GDKSuspendRenderer(SDL_Renderer *renderer)
|
||||
{
|
||||
D3D12_RenderData *data = (D3D12_RenderData *)userdata;
|
||||
if (event->type == SDL_EVENT_DID_ENTER_BACKGROUND) {
|
||||
data->commandQueue->SuspendX(0);
|
||||
} else if (event->type == SDL_EVENT_WILL_ENTER_FOREGROUND) {
|
||||
data->commandQueue->ResumeX();
|
||||
}
|
||||
return true;
|
||||
D3D12_RenderData *data = (D3D12_RenderData *)renderer->internal;
|
||||
data->commandQueue->SuspendX(0);
|
||||
}
|
||||
|
||||
static void D3D12_GDKResumeRenderer(SDL_Renderer *renderer)
|
||||
{
|
||||
D3D12_RenderData *data = (D3D12_RenderData *)renderer->internal;
|
||||
data->commandQueue->ResumeX();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void D3D12_DestroyRenderer(SDL_Renderer *renderer)
|
||||
{
|
||||
D3D12_RenderData *data = (D3D12_RenderData *)renderer->internal;
|
||||
if (data) {
|
||||
#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
|
||||
SDL_RemoveEventWatch(D3D12_GDKEventFilter, data);
|
||||
#endif
|
||||
D3D12_WaitForGPU(data);
|
||||
D3D12_ReleaseAll(renderer);
|
||||
SDL_free(data);
|
||||
@@ -1128,10 +1128,6 @@ static HRESULT D3D12_CreateDeviceResources(SDL_Renderer *renderer)
|
||||
SDL_SetPointerProperty(props, SDL_PROP_RENDERER_D3D12_DEVICE_POINTER, data->d3dDevice);
|
||||
SDL_SetPointerProperty(props, SDL_PROP_RENDERER_D3D12_COMMAND_QUEUE_POINTER, data->commandQueue);
|
||||
|
||||
#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
|
||||
SDL_AddEventWatch(D3D12_GDKEventFilter, data);
|
||||
#endif
|
||||
|
||||
done:
|
||||
D3D_SAFE_RELEASE(d3dDevice);
|
||||
return result;
|
||||
@@ -3517,6 +3513,10 @@ bool D3D12_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_Proper
|
||||
renderer->DestroyTexture = D3D12_DestroyTexture;
|
||||
renderer->DestroyRenderer = D3D12_DestroyRenderer;
|
||||
renderer->SetVSync = D3D12_SetVSync;
|
||||
#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
|
||||
renderer->GDKSuspendRenderer = D3D12_GDKSuspendRenderer;
|
||||
renderer->GDKResumeRenderer = D3D12_GDKResumeRenderer;
|
||||
#endif
|
||||
renderer->internal = data;
|
||||
D3D12_InvalidateCachedState(renderer);
|
||||
|
||||
|
||||
@@ -1563,17 +1563,19 @@ static void GPU_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||
}
|
||||
|
||||
#ifdef SDL_PLATFORM_GDK
|
||||
static bool SDLCALL GPU_GDKEventFilter(void *userdata, SDL_Event *event)
|
||||
|
||||
static void GPU_GDKSuspendRenderer(SDL_Renderer *renderer)
|
||||
{
|
||||
GPU_RenderData *data = (GPU_RenderData *)userdata;
|
||||
SDL_assert(!data->external_device);
|
||||
if (event->type == SDL_EVENT_DID_ENTER_BACKGROUND) {
|
||||
SDL_GDKSuspendGPU(data->device);
|
||||
} else if (event->type == SDL_EVENT_WILL_ENTER_FOREGROUND) {
|
||||
SDL_GDKResumeGPU(data->device);
|
||||
}
|
||||
return true;
|
||||
GPU_RenderData *data = (GPU_RenderData *)renderer->internal;
|
||||
SDL_GDKSuspendGPU(data->device);
|
||||
}
|
||||
|
||||
static void GPU_GDKResumeRenderer(SDL_Renderer *renderer)
|
||||
{
|
||||
GPU_RenderData *data = (GPU_RenderData *)renderer->internal;
|
||||
SDL_GDKResumeGPU(data->device);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void GPU_DestroyRenderer(SDL_Renderer *renderer)
|
||||
@@ -1609,9 +1611,6 @@ static void GPU_DestroyRenderer(SDL_Renderer *renderer)
|
||||
if (data->device) {
|
||||
GPU_ReleaseShaders(&data->shaders, data->device);
|
||||
if (!data->external_device) {
|
||||
#ifdef SDL_PLATFORM_GDK
|
||||
SDL_RemoveEventWatch(GPU_GDKEventFilter, data);
|
||||
#endif
|
||||
SDL_DestroyGPUDevice(data->device);
|
||||
}
|
||||
}
|
||||
@@ -1722,6 +1721,10 @@ static bool GPU_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_P
|
||||
renderer->DestroyTexture = GPU_DestroyTexture;
|
||||
renderer->DestroyRenderer = GPU_DestroyRenderer;
|
||||
renderer->SetVSync = GPU_SetVSync;
|
||||
#ifdef SDL_PLATFORM_GDK
|
||||
renderer->GDKSuspendRenderer = GPU_GDKSuspendRenderer;
|
||||
renderer->GDKResumeRenderer = GPU_GDKResumeRenderer;
|
||||
#endif
|
||||
renderer->internal = data;
|
||||
renderer->window = window;
|
||||
renderer->name = GPU_RenderDriver.name;
|
||||
@@ -1775,10 +1778,6 @@ static bool GPU_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_P
|
||||
if (!data->device) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef SDL_PLATFORM_GDK
|
||||
SDL_AddEventWatch(GPU_GDKEventFilter, data);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!GPU_InitShaders(&data->shaders, data->device)) {
|
||||
|
||||
@@ -40,6 +40,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_GDKSuspendGPU(void);
|
||||
extern SDL_DECLSPEC void SDLCALL SDL_GDKSuspendComplete(void);
|
||||
extern SDL_DECLSPEC void SDLCALL SDL_GetGDKDefaultUser(void);
|
||||
extern SDL_DECLSPEC void SDLCALL SDL_GetGDKTaskQueue(void);
|
||||
extern SDL_DECLSPEC void SDLCALL SDL_GDKSuspendRenderer(void);
|
||||
extern SDL_DECLSPEC void SDLCALL SDL_GDKResumeRenderer(void);
|
||||
#endif
|
||||
|
||||
#if !defined(SDL_PLATFORM_IOS)
|
||||
|
||||
Reference in New Issue
Block a user