mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-03-10 02:55:36 +00:00
gdk: Render/GPU can call SuspendX, document when to call SuspendComplete
(cherry picked from commit 5770e013c2)
This commit is contained in:
@@ -291,9 +291,8 @@ static void DrawSprites(SDL_Renderer * renderer, SDL_Texture * sprite)
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
||||
static void loop()
|
||||
static void update()
|
||||
{
|
||||
int i;
|
||||
SDL_Event event;
|
||||
|
||||
/* Check for events */
|
||||
@@ -310,13 +309,31 @@ static void loop()
|
||||
SDLTest_CommonEvent(state, &event, &done);
|
||||
#endif
|
||||
}
|
||||
fillerup();
|
||||
}
|
||||
|
||||
static void draw()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < state->num_windows; ++i) {
|
||||
if (state->windows[i] == NULL) {
|
||||
continue;
|
||||
}
|
||||
DrawSprites(state->renderers[i], sprites[i]);
|
||||
}
|
||||
fillerup();
|
||||
}
|
||||
|
||||
static bool SDLCALL GDKEventWatch(void* userdata, SDL_Event* event)
|
||||
{
|
||||
bool *suppressdraw = (bool *)userdata;
|
||||
SDL_assert(suppressdraw != NULL);
|
||||
if (event->type == SDL_EVENT_DID_ENTER_BACKGROUND) {
|
||||
*suppressdraw = true;
|
||||
SDL_GDKSuspendComplete();
|
||||
} else if (event->type == SDL_EVENT_WILL_ENTER_FOREGROUND) {
|
||||
*suppressdraw = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@@ -324,6 +341,7 @@ int main(int argc, char *argv[])
|
||||
int i;
|
||||
const char *icon = "icon.bmp";
|
||||
char *soundname = NULL;
|
||||
bool suppressdraw = false;
|
||||
|
||||
/* Initialize parameters */
|
||||
num_sprites = NUM_SPRITES;
|
||||
@@ -390,6 +408,9 @@ int main(int argc, char *argv[])
|
||||
quit(2);
|
||||
}
|
||||
|
||||
/* By this point the renderers are made, so we can now add this watcher */
|
||||
SDL_AddEventWatch(GDKEventWatch, &suppressdraw);
|
||||
|
||||
/* Create the windows, initialize the renderers, and load the textures */
|
||||
sprites =
|
||||
(SDL_Texture **) SDL_malloc(state->num_windows * sizeof(*sprites));
|
||||
@@ -441,7 +462,10 @@ int main(int argc, char *argv[])
|
||||
AddUserSilent();
|
||||
|
||||
while (!done) {
|
||||
loop();
|
||||
update();
|
||||
if (!suppressdraw) {
|
||||
draw();
|
||||
}
|
||||
}
|
||||
|
||||
quit(0);
|
||||
|
||||
@@ -664,6 +664,13 @@ extern SDL_DECLSPEC void SDLCALL SDL_UnregisterApp(void);
|
||||
/**
|
||||
* Callback from the application to let the suspend continue.
|
||||
*
|
||||
* When using SDL_Render or SDL_GPU, this function should be called _after_
|
||||
* creating the `SDL_Renderer` or `SDL_GPUDevice`; this allows the timing of the
|
||||
* D3D12 command queue suspension to execute in the correct order.
|
||||
*
|
||||
* If you're writing your own D3D12 renderer, this should be called after
|
||||
* calling `ID3D12CommandQueue::SuspendX`.
|
||||
*
|
||||
* This function is only needed for Xbox GDK support; all other platforms will
|
||||
* do nothing and set an "unsupported" error message.
|
||||
*
|
||||
|
||||
@@ -586,10 +586,26 @@ static HRESULT D3D12_IssueBatch(D3D12_RenderData *data)
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef SDL_PLATFORM_GDK
|
||||
static bool SDLCALL D3D12_GDKEventFilter(void* userdata, SDL_Event* event)
|
||||
{
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void D3D12_DestroyRenderer(SDL_Renderer *renderer)
|
||||
{
|
||||
D3D12_RenderData *data = (D3D12_RenderData *)renderer->internal;
|
||||
if (data) {
|
||||
#ifdef SDL_PLATFORM_GDK
|
||||
SDL_RemoveEventWatch(D3D12_GDKEventFilter, data);
|
||||
#endif
|
||||
D3D12_WaitForGPU(data);
|
||||
D3D12_ReleaseAll(renderer);
|
||||
SDL_free(data);
|
||||
@@ -1136,6 +1152,10 @@ 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);
|
||||
|
||||
#ifdef SDL_PLATFORM_GDK
|
||||
SDL_AddEventWatch(D3D12_GDKEventFilter, data);
|
||||
#endif
|
||||
|
||||
done:
|
||||
D3D_SAFE_RELEASE(d3dDevice);
|
||||
return result;
|
||||
|
||||
@@ -1546,6 +1546,20 @@ static void GPU_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||
texture->internal = NULL;
|
||||
}
|
||||
|
||||
#ifdef SDL_PLATFORM_GDK
|
||||
static bool SDLCALL GPU_GDKEventFilter(void *userdata, SDL_Event *event)
|
||||
{
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void GPU_DestroyRenderer(SDL_Renderer *renderer)
|
||||
{
|
||||
GPU_RenderData *data = (GPU_RenderData *)renderer->internal;
|
||||
@@ -1579,6 +1593,9 @@ 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);
|
||||
}
|
||||
}
|
||||
@@ -1742,6 +1759,10 @@ 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)) {
|
||||
|
||||
Reference in New Issue
Block a user