- Use SDL_RenderSetLogicalSize to handle animorphic ratios in fullscreen with SDL backend.

- Reuse the old window in the SDL backend since in some instances switching windows causes issues (OS X fullscreen for instance (while using the SDL backend of course)).
- Clear the SDL render before copying in the framebuffer to remove HOM-like effect.
This commit is contained in:
Braden Obrzut 2015-05-19 17:09:20 -04:00
parent 4d496f8b04
commit 4d082d93cd

View file

@ -28,7 +28,7 @@ class SDLFB : public DFrameBuffer
{ {
DECLARE_CLASS(SDLFB, DFrameBuffer) DECLARE_CLASS(SDLFB, DFrameBuffer)
public: public:
SDLFB (int width, int height, bool fullscreen); SDLFB (int width, int height, bool fullscreen, SDL_Window *oldwin);
~SDLFB (); ~SDLFB ();
bool Lock (bool buffer); bool Lock (bool buffer);
@ -67,7 +67,6 @@ private:
SDL_Texture *Texture; SDL_Texture *Texture;
SDL_Surface *Surface; SDL_Surface *Surface;
}; };
SDL_Rect UpdateRect;
bool UsingRenderer; bool UsingRenderer;
bool NeedPalUpdate; bool NeedPalUpdate;
@ -261,6 +260,8 @@ DFrameBuffer *SDLVideo::CreateFrameBuffer (int width, int height, bool fullscree
PalEntry flashColor; PalEntry flashColor;
int flashAmount; int flashAmount;
SDL_Window *oldwin = NULL;
if (old != NULL) if (old != NULL)
{ // Reuse the old framebuffer if its attributes are the same { // Reuse the old framebuffer if its attributes are the same
SDLFB *fb = static_cast<SDLFB *> (old); SDLFB *fb = static_cast<SDLFB *> (old);
@ -275,6 +276,10 @@ DFrameBuffer *SDLVideo::CreateFrameBuffer (int width, int height, bool fullscree
} }
return old; return old;
} }
oldwin = fb->Screen;
fb->Screen = NULL;
old->GetFlash (flashColor, flashAmount); old->GetFlash (flashColor, flashAmount);
old->ObjectFlags |= OF_YesReallyDelete; old->ObjectFlags |= OF_YesReallyDelete;
if (screen == old) screen = NULL; if (screen == old) screen = NULL;
@ -286,7 +291,7 @@ DFrameBuffer *SDLVideo::CreateFrameBuffer (int width, int height, bool fullscree
flashAmount = 0; flashAmount = 0;
} }
SDLFB *fb = new SDLFB (width, height, fullscreen); SDLFB *fb = new SDLFB (width, height, fullscreen, oldwin);
// If we could not create the framebuffer, try again with slightly // If we could not create the framebuffer, try again with slightly
// different parameters in this order: // different parameters in this order:
@ -340,7 +345,7 @@ void SDLVideo::SetWindowedScale (float scale)
// FrameBuffer implementation ----------------------------------------------- // FrameBuffer implementation -----------------------------------------------
SDLFB::SDLFB (int width, int height, bool fullscreen) SDLFB::SDLFB (int width, int height, bool fullscreen, SDL_Window *oldwin)
: DFrameBuffer (width, height) : DFrameBuffer (width, height)
{ {
int i; int i;
@ -351,15 +356,27 @@ SDLFB::SDLFB (int width, int height, bool fullscreen)
NotPaletted = false; NotPaletted = false;
FlashAmount = 0; FlashAmount = 0;
if (oldwin)
{
// In some cases (Mac OS X fullscreen) SDL2 doesn't like having multiple windows which
// appears to inevitably happen while compositor animations are running. So lets try
// to reuse the existing window.
Screen = oldwin;
SDL_SetWindowSize (Screen, width, height);
SetFullscreen (fullscreen);
}
else
{
FString caption; FString caption;
caption.Format(GAMESIG " %s (%s)", GetVersionString(), GetGitTime()); caption.Format(GAMESIG " %s (%s)", GetVersionString(), GetGitTime());
Screen = SDL_CreateWindow (caption, Screen = SDL_CreateWindow (caption,
SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter),
width, height, (fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)); width, height, (fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)|SDL_WINDOW_RESIZABLE);
if (Screen == NULL) if (Screen == NULL)
return; return;
}
Renderer = NULL; Renderer = NULL;
Texture = NULL; Texture = NULL;
@ -380,8 +397,6 @@ SDLFB::SDLFB (int width, int height, bool fullscreen)
SDLFB::~SDLFB () SDLFB::~SDLFB ()
{
if(Screen)
{ {
if (Renderer) if (Renderer)
{ {
@ -390,6 +405,8 @@ SDLFB::~SDLFB ()
SDL_DestroyRenderer (Renderer); SDL_DestroyRenderer (Renderer);
} }
if(Screen)
{
SDL_DestroyWindow (Screen); SDL_DestroyWindow (Screen);
} }
} }
@ -498,7 +515,8 @@ void SDLFB::Update ()
SDL_UnlockTexture (Texture); SDL_UnlockTexture (Texture);
SDLFlipCycles.Clock(); SDLFlipCycles.Clock();
SDL_RenderCopy(Renderer, Texture, NULL, &UpdateRect); SDL_RenderClear(Renderer);
SDL_RenderCopy(Renderer, Texture, NULL, NULL);
SDL_RenderPresent(Renderer); SDL_RenderPresent(Renderer);
SDLFlipCycles.Unclock(); SDLFlipCycles.Unclock();
} }
@ -613,6 +631,9 @@ void SDLFB::GetFlashedPalette (PalEntry pal[256])
void SDLFB::SetFullscreen (bool fullscreen) void SDLFB::SetFullscreen (bool fullscreen)
{ {
if (IsFullscreen() == fullscreen)
return;
SDL_SetWindowFullscreen (Screen, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); SDL_SetWindowFullscreen (Screen, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
if (!fullscreen) if (!fullscreen)
{ {
@ -645,6 +666,8 @@ void SDLFB::ResetSDLRenderer ()
if (!Renderer) if (!Renderer)
return; return;
SDL_SetRenderDrawColor(Renderer, 0, 0, 0, 255);
Uint32 fmt; Uint32 fmt;
switch(vid_displaybits) switch(vid_displaybits)
{ {
@ -681,24 +704,18 @@ void SDLFB::ResetSDLRenderer ()
NotPaletted = false; NotPaletted = false;
} }
// Calculate update rectangle // In fullscreen, set logical size according to animorphic ratio.
// Windowed modes are always rendered 1:1.
if (IsFullscreen ()) if (IsFullscreen ())
{ {
int w, h; int w, h;
SDL_GetWindowSize (Screen, &w, &h); SDL_GetWindowSize (Screen, &w, &h);
UpdateRect.w = w; ScaleWithAspect (w, h, Width, Height);
UpdateRect.h = h; SDL_RenderSetLogicalSize (Renderer, w, h);
ScaleWithAspect (UpdateRect.w, UpdateRect.h, Width, Height);
UpdateRect.x = (w - UpdateRect.w)/2;
UpdateRect.y = (h - UpdateRect.h)/2;
} }
else else
{ {
// In windowed mode we just update the whole window. SDL_RenderSetLogicalSize (Renderer, Width, Height);
UpdateRect.x = 0;
UpdateRect.y = 0;
UpdateRect.w = Width;
UpdateRect.h = Height;
} }
} }