Browse Source

Get a fresh window surface before rendering to it (#358)

* Get a fresh window surface before rendering to it

It is possible that a window surface gets invalidated since we initially
obtained it. We need to call GetWindowSurface every time we want one,
instead of keeping a pointer to a possibly stale one.

See https://hg.libsdl.org/SDL/file/369b01006eb2/src/video/SDL_video.c#l2312

Fixes #351
pull/362/head
Gleb Mazovetskiy 7 years ago committed by Anders Jenbo
parent
commit
dd5bc39816
  1. 1
      CMakeLists.txt
  2. 19
      SourceX/dx.cpp
  3. 17
      SourceX/miniwin/ddraw.cpp
  4. 7
      SourceX/miniwin/ddraw.h
  5. 4
      SourceX/storm/storm.cpp

1
CMakeLists.txt

@ -205,6 +205,7 @@ add_library(devilution STATIC
set(devilutionx_SRCS
SourceX/dx.cpp
SourceX/miniwin/ddraw.cpp
SourceX/miniwin/misc.cpp
SourceX/miniwin/misc_io.cpp
SourceX/miniwin/misc_msg.cpp

19
SourceX/dx.cpp

@ -22,8 +22,8 @@ SDL_Texture *texture;
SDL_Palette *palette;
unsigned int pal_surface_palette_version = 0;
/** 32-bit in-memory backbuffer surface */
SDL_Surface *surface;
/** 24-bit renderer texture surface */
SDL_Surface *renderer_texture_surface = nullptr;
/** 8-bit surface wrapper around #gpBuffer */
SDL_Surface *pal_surface;
@ -58,9 +58,7 @@ void dx_create_back_buffer()
void dx_create_primary_surface()
{
#ifdef USE_SDL1
surface = SDL_GetVideoSurface();
#else
#ifndef USE_SDL1
if (renderer) {
int width, height;
if (SDL_GetRendererOutputSize(renderer, &width, &height) <= -1) {
@ -69,12 +67,10 @@ void dx_create_primary_surface()
Uint32 format;
if (SDL_QueryTexture(texture, &format, nullptr, nullptr, nullptr) < 0)
ErrSdl();
surface = SDL_CreateRGBSurfaceWithFormat(0, width, height, SDL_BITSPERPIXEL(format), format);
} else {
surface = SDL_GetWindowSurface(window);
renderer_texture_surface = SDL_CreateRGBSurfaceWithFormat(0, width, height, SDL_BITSPERPIXEL(format), format);
}
#endif
if (surface == NULL) {
if (GetOutputSurface() == nullptr) {
ErrSdl();
}
}
@ -140,7 +136,7 @@ void dx_cleanup()
SDL_FreeSurface(pal_surface);
pal_surface = nullptr;
SDL_FreePalette(palette);
SDL_FreeSurface(surface);
SDL_FreeSurface(renderer_texture_surface);
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
@ -195,7 +191,7 @@ void BltFast(DWORD dwX, DWORD dwY, LPRECT lpSrcRect)
};
// Convert from 8-bit to 32-bit
if (SDL_BlitSurface(pal_surface, &src_rect, surface, &dst_rect) <= -1) {
if (SDL_BlitSurface(pal_surface, &src_rect, GetOutputSurface(), &dst_rect) <= -1) {
ErrSdl();
}
@ -204,6 +200,7 @@ void BltFast(DWORD dwX, DWORD dwY, LPRECT lpSrcRect)
void RenderPresent()
{
SDL_Surface *surface = GetOutputSurface();
assert(!SDL_MUSTLOCK(surface));
if (!bufferUpdated) {

17
SourceX/miniwin/ddraw.cpp

@ -0,0 +1,17 @@
#include "miniwin/ddraw.h"
namespace dvl {
extern SDL_Surface *renderer_texture_surface; // defined in dx.cpp
SDL_Surface *GetOutputSurface() {
#ifdef USE_SDL1
return SDL_GetVideoSurface();
#else
if (renderer)
return renderer_texture_surface;
return SDL_GetWindowSurface(window);
#endif
}
} // namespace dvl

7
SourceX/miniwin/ddraw.h

@ -7,10 +7,15 @@ extern SDL_Window *window;
extern SDL_Renderer *renderer;
extern SDL_Texture *texture;
extern SDL_Surface *surface;
extern SDL_Palette *palette;
extern SDL_Surface *pal_surface;
extern unsigned int pal_surface_palette_version;
extern bool bufferUpdated;
// Returns:
// SDL1: Video surface.
// SDL2, no upscale: Window surface.
// SDL2, upscale: Renderer texture surface.
SDL_Surface *GetOutputSurface();
} // namespace dvl

4
SourceX/storm/storm.cpp

@ -684,7 +684,7 @@ BOOL SVidPlayContinue(void)
#ifndef USE_SDL1
if (renderer) {
if (SDL_BlitSurface(SVidSurface, NULL, surface, NULL) <= -1) {
if (SDL_BlitSurface(SVidSurface, NULL, GetOutputSurface(), NULL) <= -1) {
SDL_Log(SDL_GetError());
return false;
}
@ -716,7 +716,7 @@ BOOL SVidPlayContinue(void)
Uint32 format = SDL_GetWindowPixelFormat(window);
SDL_Surface *tmp = SDL_ConvertSurfaceFormat(SVidSurface, format, 0);
#endif
if (SDL_BlitScaled(tmp, NULL, surface, &pal_surface_offset) <= -1) {
if (SDL_BlitScaled(tmp, NULL, GetOutputSurface(), &pal_surface_offset) <= -1) {
SDL_Log(SDL_GetError());
return false;
}

Loading…
Cancel
Save