From a9e8d281c9be6ddb8b9ad2bbd895aed877bd2083 Mon Sep 17 00:00:00 2001 From: GaryOderNichts <12049776+GaryOderNichts@users.noreply.github.com> Date: Thu, 8 Sep 2022 00:51:51 +0200 Subject: [PATCH] wiiu: make sure nothing gets drawn while in background --- src/render/SDL_render.c | 6 ++++-- src/render/wiiu/SDL_render_wiiu.c | 6 +++--- src/render/wiiu/SDL_rqueue_wiiu.c | 7 +++++++ src/render/wiiu/SDL_rtexture_wiiu.c | 17 ++++++++++++++--- src/video/wiiu/SDL_wiiuvideo.c | 25 +++++++++++++++++++++---- 5 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index 979a711da..846b97b88 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -38,8 +38,10 @@ that will crash the app. However, these apps _should_ have used SDL_AddEventWatch to catch SDL_APP_WILLENTERBACKGROUND events and stopped drawing themselves. Other platforms still draw, as the compositor can use it, and more importantly: drawing to render targets isn't lost. But I still think -this should probably be removed at some point in the future. --ryan. */ -#if defined(__IPHONEOS__) || defined(__TVOS__) || defined(__ANDROID__) +this should probably be removed at some point in the future. --ryan.*/ +/* Same goes for Wii U. If you draw things while not in foreground the app +will just crash. --gary*/ +#if defined(__IPHONEOS__) || defined(__TVOS__) || defined(__ANDROID__) || defined(__WIIU__) #define DONT_DRAW_WHILE_HIDDEN 1 #else #define DONT_DRAW_WHILE_HIDDEN 0 diff --git a/src/render/wiiu/SDL_render_wiiu.c b/src/render/wiiu/SDL_render_wiiu.c index 1cd5485d7..a81029dc4 100644 --- a/src/render/wiiu/SDL_render_wiiu.c +++ b/src/render/wiiu/SDL_render_wiiu.c @@ -203,11 +203,11 @@ void WIIU_SDL_DestroyRenderer(SDL_Renderer * renderer) if (videodata->hasForeground) { GX2DrawDone(); - - WIIU_FreeRenderData(data); - WIIU_TextureDoneRendering(data); } + WIIU_FreeRenderData(data); + WIIU_TextureDoneRendering(data); + free(data->ctx); WIIU_SDL_DestroyShaders(); diff --git a/src/render/wiiu/SDL_rqueue_wiiu.c b/src/render/wiiu/SDL_rqueue_wiiu.c index 28e33d71d..e6123cc84 100644 --- a/src/render/wiiu/SDL_rqueue_wiiu.c +++ b/src/render/wiiu/SDL_rqueue_wiiu.c @@ -350,6 +350,13 @@ static int WIIU_SDL_SetDrawState(WIIU_RenderData * data, const SDL_RenderCommand int WIIU_SDL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) { WIIU_RenderData* data = (WIIU_RenderData*) renderer->driverdata; + WIIU_VideoData *videodata = (WIIU_VideoData *) SDL_GetVideoDevice()->driverdata; + + /* The command queue is still ran, even with DONT_DRAW_WHILE_HIDDEN + So check manually for foreground here */ + if (!videodata->hasForeground) { + return 0; + } /* make sure we're using the correct renderer ctx */ WIIU_SDL_SetRenderTarget(renderer, renderer->target); diff --git a/src/render/wiiu/SDL_rtexture_wiiu.c b/src/render/wiiu/SDL_rtexture_wiiu.c index eee69604a..828c33a17 100644 --- a/src/render/wiiu/SDL_rtexture_wiiu.c +++ b/src/render/wiiu/SDL_rtexture_wiiu.c @@ -122,13 +122,16 @@ int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) int WIIU_SDL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, void **pixels, int *pitch) { + WIIU_VideoData *videodata = (WIIU_VideoData *) SDL_GetVideoDevice()->driverdata; WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata; Uint32 BytesPerPixel = SDL_BYTESPERPIXEL(texture->format); void* pixel_buffer; - /* Wait for the texture rendering to finish */ - WIIU_TextureCheckWaitRendering(data, tdata); + if (videodata->hasForeground) { + /* Wait for the texture rendering to finish */ + WIIU_TextureCheckWaitRendering(data, tdata); + } pixel_buffer = GX2RLockSurfaceEx(&tdata->texture.surface, 0, 0); @@ -164,11 +167,16 @@ void WIIU_SDL_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture int WIIU_SDL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch) { + WIIU_VideoData *videodata = (WIIU_VideoData *) SDL_GetVideoDevice()->driverdata; Uint32 BytesPerPixel = SDL_BYTESPERPIXEL(texture->format); size_t length = rect->w * BytesPerPixel; Uint8 *src = (Uint8 *) pixels, *dst; int row, dst_pitch; + if (!videodata->hasForeground) { + return 0; + } + /* We write the rules, and we say all textures are streaming */ WIIU_SDL_LockTexture(renderer, texture, rect, (void**)&dst, &dst_pitch); @@ -185,6 +193,7 @@ int WIIU_SDL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, void WIIU_SDL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) { + WIIU_VideoData *videodata = (WIIU_VideoData *) SDL_GetVideoDevice()->driverdata; WIIU_RenderData *data; WIIU_TextureData *tdata; @@ -196,7 +205,9 @@ void WIIU_SDL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) tdata = (WIIU_TextureData *) texture->driverdata; /* Wait for the texture rendering to finish */ - WIIU_TextureCheckWaitRendering(data, tdata); + if (videodata->hasForeground) { + WIIU_TextureCheckWaitRendering(data, tdata); + } if (data->drawState.texture == texture) { data->drawState.texture = NULL; diff --git a/src/video/wiiu/SDL_wiiuvideo.c b/src/video/wiiu/SDL_wiiuvideo.c index 1edf51942..04f010ba5 100644 --- a/src/video/wiiu/SDL_wiiuvideo.c +++ b/src/video/wiiu/SDL_wiiuvideo.c @@ -92,10 +92,17 @@ static int WIIU_ForegroundAcquired(_THIS) GX2Invalidate(GX2_INVALIDATE_MODE_CPU, videodata->drcScanBuffer, videodata->drcScanBufferSize); GX2SetDRCBuffer(videodata->drcScanBuffer, videodata->drcScanBufferSize, videodata->drcRenderMode, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8, GX2_BUFFERING_MODE_DOUBLE); - // TODO recreate MEM1 surfaces for all windows while (window) { SDL_Renderer* renderer = SDL_GetRenderer(window); - //WIIU_SDL_CreateWindowTex(renderer, window); + + // Recreate the window texture, now that we have foreground memory available + if (renderer) { + // TODO + //WIIU_SDL_CreateWindowTex(renderer, window); + } + + // We're now in foreground, window is visible + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0); window = window->next; } @@ -121,10 +128,17 @@ static int WIIU_ForegroundReleased(_THIS) videodata->drcScanBuffer = NULL; } - // TODO destroy MEM1 surfaces for all windows while (window) { SDL_Renderer* renderer = SDL_GetRenderer(window); - //WIIU_SDL_DestroyWindowTex(renderer, window); + + // No longer in foreground, window is no longer visible + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_HIDDEN, 0, 0); + + // Destroy window texture, we no longer have access to foreground memory + if (renderer) { + // TODO + //WIIU_SDL_DestroyWindowTex(renderer, window); + } window = window->next; } @@ -315,6 +329,9 @@ static SDL_VideoDevice *WIIU_CreateDevice(int devindex) device->driverdata = videodata; + // Setup amount of available displays + device->num_displays = 0; + device->VideoInit = WIIU_VideoInit; device->VideoQuit = WIIU_VideoQuit; device->CreateSDLWindow = WIIU_CreateSDLWindow;