From 6a4f4e0df32eb1790986ac0871d4e8fd2c608c05 Mon Sep 17 00:00:00 2001 From: Clownacy Date: Mon, 15 Jul 2019 17:47:22 +0100 Subject: [PATCH] Added handlers for render target loss/window resize These only really happen when you use exclusive fullscreen and alt-tab out. Or, at least, it does on Windows with SDL2 in DirectX mode. --- src/Backends/Rendering.h | 2 ++ src/Backends/Rendering/SDLTexture.cpp | 27 +++++++++++++++++++++++++++ src/Backends/Rendering/Software.cpp | 19 +++++++++++++++---- src/Draw.cpp | 10 ++++++++++ src/Draw.h | 2 ++ src/Main.cpp | 10 ++++++++++ 6 files changed, 66 insertions(+), 4 deletions(-) diff --git a/src/Backends/Rendering.h b/src/Backends/Rendering.h index 9416c958..12c2d5e9 100644 --- a/src/Backends/Rendering.h +++ b/src/Backends/Rendering.h @@ -21,3 +21,5 @@ void Backend_ColourFillToScreen(const RECT *rect, unsigned char red, unsigned ch void Backend_ScreenToSurface(Backend_Surface *surface, const RECT *rect); void Backend_DrawText(Backend_Surface *surface, FontObject *font, int x, int y, const char *text, unsigned long colour); void Backend_DrawTextToScreen(FontObject *font, int x, int y, const char *text, unsigned long colour); +void Backend_HandleDeviceLoss(void); +void Backend_HandleWindowResize(void); diff --git a/src/Backends/Rendering/SDLTexture.cpp b/src/Backends/Rendering/SDLTexture.cpp index 4fc4a004..852fd519 100644 --- a/src/Backends/Rendering/SDLTexture.cpp +++ b/src/Backends/Rendering/SDLTexture.cpp @@ -14,11 +14,16 @@ struct Backend_Surface BOOL needs_syncing; SDL_Surface *sdl_surface; SDL_Texture *texture; + + struct Backend_Surface *next; + struct Backend_Surface *prev; }; static SDL_Renderer *renderer; static SDL_Texture *screen_texture; +static Backend_Surface *surface_list_head; + static void FlushSurface(Backend_Surface *surface) { unsigned char *buffer = (unsigned char*)malloc(surface->sdl_surface->w * surface->sdl_surface->h * 4); @@ -120,11 +125,21 @@ Backend_Surface* Backend_CreateSurface(unsigned int width, unsigned int height) surface->needs_syncing = FALSE; + surface->next = surface_list_head; + if (surface->next) + surface->next->prev = surface; + surface_list_head = surface; + return surface; } void Backend_FreeSurface(Backend_Surface *surface) { + if (surface->next) + surface->next->prev = surface->prev; + if (surface->prev) + surface->prev->next = surface->next; + SDL_FreeSurface(surface->sdl_surface); free(surface); } @@ -274,3 +289,15 @@ void Backend_DrawTextToScreen(FontObject *font, int x, int y, const char *text, SDL_RenderCopy(renderer, texture, NULL, NULL); SDL_DestroyTexture(texture); } + +void Backend_HandleDeviceLoss(void) +{ + // All of our textures have been lost, so regenerate them + for (Backend_Surface *surface = surface_list_head; surface != NULL; surface = surface->next) + surface->needs_syncing = TRUE; +} + +void Backend_HandleWindowResize(void) +{ + // No problem for us +} diff --git a/src/Backends/Rendering/Software.cpp b/src/Backends/Rendering/Software.cpp index 2aea1f5b..8ae95281 100644 --- a/src/Backends/Rendering/Software.cpp +++ b/src/Backends/Rendering/Software.cpp @@ -83,10 +83,10 @@ void Backend_FreeSurface(Backend_Surface *surface) void Backend_LoadPixels(Backend_Surface *surface, const unsigned char *pixels, unsigned int width, unsigned int height, unsigned int pitch) { - for (unsigned int h = 0; h < height; ++h) + for (unsigned int i = 0; i < height; ++i) { - const unsigned char *src_row = &pixels[h * pitch]; - unsigned char *dst_row = &surface->pixels[h * surface->pitch]; + const unsigned char *src_row = &pixels[i * pitch]; + unsigned char *dst_row = &surface->pixels[i * surface->pitch]; memcpy(dst_row, src_row, width * 3); } @@ -231,10 +231,21 @@ void Backend_ScreenToSurface(Backend_Surface *surface, const RECT *rect) void Backend_DrawText(Backend_Surface *surface, FontObject *font, int x, int y, const char *text, unsigned long colour) { DrawText(font, surface->pixels, surface->pitch, surface->width, surface->height, x, y, colour, text, strlen(text)); - //surf[surf_no].needs_updating = TRUE; } void Backend_DrawTextToScreen(FontObject *font, int x, int y, const char *text, unsigned long colour) { Backend_DrawText(&framebuffer, font, x, y, text, colour); } + +void Backend_HandleDeviceLoss(void) +{ + // No problem for us +} + +void Backend_HandleWindowResize(void) +{ + // https://wiki.libsdl.org/SDL_GetWindowSurface + // We need to fetch a new surface pointer + window_surface = SDL_GetWindowSurface(window); +} diff --git a/src/Draw.cpp b/src/Draw.cpp index 8d81b01e..3bf6c3da 100644 --- a/src/Draw.cpp +++ b/src/Draw.cpp @@ -569,3 +569,13 @@ void EndTextObject() UnloadFont(gFont); gFont = NULL; } + +void HandleDeviceLoss() +{ + Backend_HandleDeviceLoss(); +} + +void HandleWindowResize() +{ + Backend_HandleWindowResize(); +} diff --git a/src/Draw.h b/src/Draw.h index d50bef34..e7e537b8 100644 --- a/src/Draw.h +++ b/src/Draw.h @@ -72,3 +72,5 @@ void InitTextObject(const char *font_name); void PutText(int x, int y, const char *text, unsigned long color); void PutText2(int x, int y, const char *text, unsigned long color, Surface_Ids surf_no); void EndTextObject(); +void HandleDeviceLoss(); +void HandleWindowResize(); diff --git a/src/Main.cpp b/src/Main.cpp index ea6fc2fc..f3b98f7a 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -463,9 +463,19 @@ BOOL SystemTask() return FALSE; break; + case SDL_RENDER_TARGETS_RESET: + case SDL_RENDER_DEVICE_RESET: + HandleDeviceLoss(); + break; + case SDL_WINDOWEVENT: switch (event.window.event) { + case SDL_WINDOWEVENT_RESIZED: + case SDL_WINDOWEVENT_SIZE_CHANGED: + HandleWindowResize(); + break; + case SDL_WINDOWEVENT_FOCUS_GAINED: focusGained = TRUE; ActiveWindow();