mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 23:32:04 +00:00
Add fallback code to Linux target so if OpenGL is either unavailable or can't be used it falls back to the old software SDL FB
This commit is contained in:
parent
6586877ac5
commit
55d9392fb8
7 changed files with 108 additions and 293 deletions
|
@ -149,27 +149,6 @@ const char *const OpenGLSWFrameBuffer::ShaderDefines[OpenGLSWFrameBuffer::NUM_SH
|
|||
OpenGLSWFrameBuffer::OpenGLSWFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen, bool bgra) :
|
||||
Super(hMonitor, ClampWidth(width), ClampHeight(height), bits, refreshHz, fullscreen, bgra)
|
||||
{
|
||||
// To do: this needs to cooperate with the same static in OpenGLFrameBuffer::InitializeState
|
||||
static bool first = true;
|
||||
if (first)
|
||||
{
|
||||
ogl_LoadFunctions();
|
||||
}
|
||||
gl_LoadExtensions();
|
||||
InitializeState();
|
||||
if (first)
|
||||
{
|
||||
gl_PrintStartupLog();
|
||||
first = false;
|
||||
}
|
||||
|
||||
// SetVSync needs to be at the very top to workaround a bug in Nvidia's OpenGL driver.
|
||||
// If wglSwapIntervalEXT is called after glBindFramebuffer in a frame the setting is not changed!
|
||||
Super::SetVSync(vid_vsync);
|
||||
|
||||
Debug = std::make_shared<FGLDebug>();
|
||||
Debug->Update();
|
||||
|
||||
VertexBuffer = nullptr;
|
||||
IndexBuffer = nullptr;
|
||||
FBTexture = nullptr;
|
||||
|
@ -181,7 +160,7 @@ OpenGLSWFrameBuffer::OpenGLSWFrameBuffer(void *hMonitor, int width, int height,
|
|||
{
|
||||
Shaders[i] = nullptr;
|
||||
}
|
||||
VSync = vid_vsync;
|
||||
|
||||
BlendingRect.left = 0;
|
||||
BlendingRect.top = 0;
|
||||
BlendingRect.right = Width;
|
||||
|
@ -214,11 +193,36 @@ OpenGLSWFrameBuffer::OpenGLSWFrameBuffer(void *hMonitor, int width, int height,
|
|||
|
||||
memcpy(SourcePalette, GPalette.BaseColors, sizeof(PalEntry) * 256);
|
||||
|
||||
// To do: this needs to cooperate with the same static in OpenGLFrameBuffer::InitializeState
|
||||
static bool first = true;
|
||||
if (first)
|
||||
{
|
||||
ogl_LoadFunctions();
|
||||
}
|
||||
gl_LoadExtensions();
|
||||
InitializeState();
|
||||
if (first)
|
||||
{
|
||||
gl_PrintStartupLog();
|
||||
first = false;
|
||||
}
|
||||
|
||||
if (!glGetString)
|
||||
return;
|
||||
|
||||
// SetVSync needs to be at the very top to workaround a bug in Nvidia's OpenGL driver.
|
||||
// If wglSwapIntervalEXT is called after glBindFramebuffer in a frame the setting is not changed!
|
||||
Super::SetVSync(vid_vsync);
|
||||
|
||||
Debug = std::make_shared<FGLDebug>();
|
||||
Debug->Update();
|
||||
|
||||
//Windowed = !(static_cast<Win32Video *>(Video)->GoFullscreen(fullscreen));
|
||||
|
||||
TrueHeight = height;
|
||||
|
||||
CreateResources();
|
||||
Valid = CreateResources();
|
||||
if (Valid)
|
||||
SetInitialState();
|
||||
}
|
||||
|
||||
|
@ -1077,7 +1081,7 @@ int OpenGLSWFrameBuffer::GetPageCount()
|
|||
|
||||
bool OpenGLSWFrameBuffer::IsValid()
|
||||
{
|
||||
return true;
|
||||
return Valid;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -422,6 +422,7 @@ private:
|
|||
|
||||
template<typename T> static void SafeRelease(T &x) { if (x != nullptr) { delete x; x = nullptr; } }
|
||||
|
||||
bool Valid = false;
|
||||
std::shared_ptr<FGLDebug> Debug;
|
||||
|
||||
std::unique_ptr<HWVertexBuffer> StreamVertexBuffer, StreamVertexBufferBurn;
|
||||
|
@ -452,7 +453,6 @@ private:
|
|||
bool UpdatePending;
|
||||
bool NeedPalUpdate;
|
||||
bool NeedGammaUpdate;
|
||||
bool VSync;
|
||||
LTRBRect BlendingRect;
|
||||
int In2D;
|
||||
bool InScene;
|
||||
|
|
|
@ -56,8 +56,6 @@ EXTERN_CVAR (Bool, fullscreen)
|
|||
EXTERN_CVAR (Bool, swtruecolor)
|
||||
EXTERN_CVAR (Float, vid_winscale)
|
||||
|
||||
CVAR (Bool, vid_sdl, 0, 0);
|
||||
|
||||
IVideo *Video;
|
||||
|
||||
extern int NewWidth, NewHeight, NewBits, DisplayBits;
|
||||
|
@ -122,8 +120,7 @@ void I_InitGraphics ()
|
|||
ticker.SetGenericRepDefault (val, CVAR_Bool);
|
||||
|
||||
//currentrenderer = vid_renderer;
|
||||
if (currentrenderer==1 || vid_sdl==0) Video = new SDLGLVideo(0);
|
||||
else Video = new SDLVideo (0);
|
||||
Video = new SDLGLVideo(0);
|
||||
|
||||
if (Video == NULL)
|
||||
I_FatalError ("Failed to initialize display");
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "c_console.h"
|
||||
|
||||
#include "sdlglvideo.h"
|
||||
#include "sdlvideo.h"
|
||||
#include "gl/system/gl_system.h"
|
||||
#include "r_defs.h"
|
||||
#include "gl/gl_functions.h"
|
||||
|
@ -29,6 +30,7 @@
|
|||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
IMPLEMENT_CLASS(SDLBaseFB, true, false)
|
||||
IMPLEMENT_CLASS(SDLGLFB, true, false)
|
||||
|
||||
struct MiniModeInfo
|
||||
|
@ -171,15 +173,15 @@ DFrameBuffer *SDLGLVideo::CreateFrameBuffer (int width, int height, bool bgra, b
|
|||
|
||||
if (old != NULL)
|
||||
{ // Reuse the old framebuffer if its attributes are the same
|
||||
SDLGLFB *fb = static_cast<SDLGLFB *> (old);
|
||||
SDLBaseFB *fb = static_cast<SDLBaseFB *> (old);
|
||||
if (fb->Width == width &&
|
||||
fb->Height == height)
|
||||
{
|
||||
bool fsnow = (SDL_GetWindowFlags (fb->Screen) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0;
|
||||
bool fsnow = (SDL_GetWindowFlags (fb->GetSDLWindow()) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0;
|
||||
|
||||
if (fsnow != fullscreen)
|
||||
{
|
||||
SDL_SetWindowFullscreen (fb->Screen, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
|
||||
SDL_SetWindowFullscreen (fb->GetSDLWindow(), fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
|
||||
}
|
||||
return old;
|
||||
}
|
||||
|
@ -192,11 +194,17 @@ DFrameBuffer *SDLGLVideo::CreateFrameBuffer (int width, int height, bool bgra, b
|
|||
// flashAmount = 0;
|
||||
}
|
||||
|
||||
SDLGLFB *fb;
|
||||
SDLBaseFB *fb;
|
||||
if (vid_renderer == 1)
|
||||
fb = new OpenGLFrameBuffer (0, width, height, 32, 60, fullscreen);
|
||||
{
|
||||
fb = new OpenGLFrameBuffer(0, width, height, 32, 60, fullscreen);
|
||||
}
|
||||
else
|
||||
fb = (SDLGLFB*)CreateGLSWFrameBuffer (width, height, bgra, fullscreen);
|
||||
{
|
||||
fb = (SDLBaseFB*)CreateGLSWFrameBuffer(width, height, bgra, fullscreen);
|
||||
if (!fb->IsValid())
|
||||
fb = new SDLFB(width, height, bgra, fullscreen, nullptr);
|
||||
}
|
||||
|
||||
retry = 0;
|
||||
|
||||
|
@ -240,7 +248,7 @@ DFrameBuffer *SDLGLVideo::CreateFrameBuffer (int width, int height, bool bgra, b
|
|||
}
|
||||
|
||||
++retry;
|
||||
fb = static_cast<SDLGLFB *>(CreateFrameBuffer (width, height, false, fullscreen, NULL));
|
||||
fb = static_cast<SDLBaseFB *>(CreateFrameBuffer (width, height, false, fullscreen, NULL));
|
||||
}
|
||||
|
||||
// fb->SetFlash (flashColor, flashAmount);
|
||||
|
|
|
@ -34,9 +34,17 @@ private:
|
|||
int IteratorMode;
|
||||
int IteratorBits;
|
||||
};
|
||||
class SDLGLFB : public DFrameBuffer
|
||||
|
||||
class SDLBaseFB : public DFrameBuffer
|
||||
{
|
||||
DECLARE_CLASS(SDLGLFB, DFrameBuffer)
|
||||
DECLARE_CLASS(SDLBaseFB, DFrameBuffer)
|
||||
public:
|
||||
virtual SDL_Window *GetSDLWindow() = 0;
|
||||
};
|
||||
|
||||
class SDLGLFB : public SDLBaseFB
|
||||
{
|
||||
DECLARE_CLASS(SDLGLFB, SDLBaseFB)
|
||||
public:
|
||||
// this must have the same parameters as the Windows version, even if they are not used!
|
||||
SDLGLFB (void *hMonitor, int width, int height, int, int, bool fullscreen, bool bgra);
|
||||
|
@ -61,6 +69,8 @@ public:
|
|||
int GetClientWidth();
|
||||
int GetClientHeight();
|
||||
|
||||
SDL_Window *GetSDLWindow() override { return Screen; }
|
||||
|
||||
protected:
|
||||
bool CanUpdate();
|
||||
void SetGammaTable(WORD *tbl);
|
||||
|
|
|
@ -24,61 +24,6 @@
|
|||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
class SDLFB : public DFrameBuffer
|
||||
{
|
||||
DECLARE_CLASS(SDLFB, DFrameBuffer)
|
||||
public:
|
||||
SDLFB (int width, int height, bool bgra, bool fullscreen, SDL_Window *oldwin);
|
||||
~SDLFB ();
|
||||
|
||||
bool Lock (bool buffer);
|
||||
void Unlock ();
|
||||
bool Relock ();
|
||||
void ForceBuffering (bool force);
|
||||
bool IsValid ();
|
||||
void Update ();
|
||||
PalEntry *GetPalette ();
|
||||
void GetFlashedPalette (PalEntry pal[256]);
|
||||
void UpdatePalette ();
|
||||
bool SetGamma (float gamma);
|
||||
bool SetFlash (PalEntry rgb, int amount);
|
||||
void GetFlash (PalEntry &rgb, int &amount);
|
||||
void SetFullscreen (bool fullscreen);
|
||||
int GetPageCount ();
|
||||
bool IsFullscreen ();
|
||||
|
||||
friend class SDLVideo;
|
||||
|
||||
virtual void SetVSync (bool vsync);
|
||||
virtual void ScaleCoordsFromWindow(SWORD &x, SWORD &y);
|
||||
|
||||
private:
|
||||
PalEntry SourcePalette[256];
|
||||
BYTE GammaTable[3][256];
|
||||
PalEntry Flash;
|
||||
int FlashAmount;
|
||||
float Gamma;
|
||||
bool UpdatePending;
|
||||
|
||||
SDL_Window *Screen;
|
||||
SDL_Renderer *Renderer;
|
||||
union
|
||||
{
|
||||
SDL_Texture *Texture;
|
||||
SDL_Surface *Surface;
|
||||
};
|
||||
|
||||
bool UsingRenderer;
|
||||
bool NeedPalUpdate;
|
||||
bool NeedGammaUpdate;
|
||||
bool NotPaletted;
|
||||
|
||||
void UpdateColors ();
|
||||
void ResetSDLRenderer ();
|
||||
|
||||
SDLFB () {}
|
||||
};
|
||||
|
||||
IMPLEMENT_CLASS(SDLFB, false, false)
|
||||
|
||||
struct MiniModeInfo
|
||||
|
@ -132,72 +77,6 @@ CUSTOM_CVAR (Float, bgamma, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
|||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
// Dummy screen sizes to pass when windowed
|
||||
static MiniModeInfo WinModes[] =
|
||||
{
|
||||
{ 320, 200 },
|
||||
{ 320, 240 },
|
||||
{ 400, 225 }, // 16:9
|
||||
{ 400, 300 },
|
||||
{ 480, 270 }, // 16:9
|
||||
{ 480, 360 },
|
||||
{ 512, 288 }, // 16:9
|
||||
{ 512, 384 },
|
||||
{ 640, 360 }, // 16:9
|
||||
{ 640, 400 },
|
||||
{ 640, 480 },
|
||||
{ 720, 480 }, // 16:10
|
||||
{ 720, 540 },
|
||||
{ 800, 450 }, // 16:9
|
||||
{ 800, 480 },
|
||||
{ 800, 500 }, // 16:10
|
||||
{ 800, 600 },
|
||||
{ 848, 480 }, // 16:9
|
||||
{ 960, 600 }, // 16:10
|
||||
{ 960, 720 },
|
||||
{ 1024, 576 }, // 16:9
|
||||
{ 1024, 600 }, // 17:10
|
||||
{ 1024, 640 }, // 16:10
|
||||
{ 1024, 768 },
|
||||
{ 1088, 612 }, // 16:9
|
||||
{ 1152, 648 }, // 16:9
|
||||
{ 1152, 720 }, // 16:10
|
||||
{ 1152, 864 },
|
||||
{ 1280, 540 }, // 21:9
|
||||
{ 1280, 720 }, // 16:9
|
||||
{ 1280, 854 },
|
||||
{ 1280, 800 }, // 16:10
|
||||
{ 1280, 960 },
|
||||
{ 1280, 1024 }, // 5:4
|
||||
{ 1360, 768 }, // 16:9
|
||||
{ 1366, 768 },
|
||||
{ 1400, 787 }, // 16:9
|
||||
{ 1400, 875 }, // 16:10
|
||||
{ 1400, 1050 },
|
||||
{ 1440, 900 },
|
||||
{ 1440, 960 },
|
||||
{ 1440, 1080 },
|
||||
{ 1600, 900 }, // 16:9
|
||||
{ 1600, 1000 }, // 16:10
|
||||
{ 1600, 1200 },
|
||||
{ 1680, 1050 }, // 16:10
|
||||
{ 1920, 1080 },
|
||||
{ 1920, 1200 },
|
||||
{ 2048, 1536 },
|
||||
{ 2560, 1080 }, // 21:9
|
||||
{ 2560, 1440 },
|
||||
{ 2560, 1600 },
|
||||
{ 2560, 2048 },
|
||||
{ 2880, 1800 },
|
||||
{ 3200, 1800 },
|
||||
{ 3440, 1440 }, // 21:9
|
||||
{ 3840, 2160 },
|
||||
{ 3840, 2400 },
|
||||
{ 4096, 2160 },
|
||||
{ 5120, 2160 }, // 21:9
|
||||
{ 5120, 2880 }
|
||||
};
|
||||
|
||||
static cycle_t BlitCycles;
|
||||
static cycle_t SDLFlipCycles;
|
||||
|
||||
|
@ -228,128 +107,6 @@ void ScaleWithAspect (int &w, int &h, int Width, int Height)
|
|||
h = y;
|
||||
}
|
||||
|
||||
SDLVideo::SDLVideo (int parm)
|
||||
{
|
||||
IteratorBits = 0;
|
||||
}
|
||||
|
||||
SDLVideo::~SDLVideo ()
|
||||
{
|
||||
}
|
||||
|
||||
void SDLVideo::StartModeIterator (int bits, bool fs)
|
||||
{
|
||||
IteratorMode = 0;
|
||||
IteratorBits = bits;
|
||||
}
|
||||
|
||||
bool SDLVideo::NextMode (int *width, int *height, bool *letterbox)
|
||||
{
|
||||
if (IteratorBits != 8)
|
||||
return false;
|
||||
|
||||
if ((unsigned)IteratorMode < sizeof(WinModes)/sizeof(WinModes[0]))
|
||||
{
|
||||
*width = WinModes[IteratorMode].Width;
|
||||
*height = WinModes[IteratorMode].Height;
|
||||
++IteratorMode;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
DFrameBuffer *SDLVideo::CreateFrameBuffer (int width, int height, bool bgra, bool fullscreen, DFrameBuffer *old)
|
||||
{
|
||||
static int retry = 0;
|
||||
static int owidth, oheight;
|
||||
|
||||
PalEntry flashColor;
|
||||
int flashAmount;
|
||||
|
||||
SDL_Window *oldwin = NULL;
|
||||
|
||||
if (old != NULL)
|
||||
{ // Reuse the old framebuffer if its attributes are the same
|
||||
SDLFB *fb = static_cast<SDLFB *> (old);
|
||||
if (fb->Width == width &&
|
||||
fb->Height == height &&
|
||||
fb->Bgra == bgra)
|
||||
{
|
||||
bool fsnow = (SDL_GetWindowFlags (fb->Screen) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0;
|
||||
|
||||
if (fsnow != fullscreen)
|
||||
{
|
||||
fb->SetFullscreen (fullscreen);
|
||||
}
|
||||
return old;
|
||||
}
|
||||
|
||||
oldwin = fb->Screen;
|
||||
fb->Screen = NULL;
|
||||
|
||||
old->GetFlash (flashColor, flashAmount);
|
||||
old->ObjectFlags |= OF_YesReallyDelete;
|
||||
if (screen == old) screen = NULL;
|
||||
delete old;
|
||||
}
|
||||
else
|
||||
{
|
||||
flashColor = 0;
|
||||
flashAmount = 0;
|
||||
}
|
||||
|
||||
SDLFB *fb = new SDLFB (width, height, bgra, fullscreen, oldwin);
|
||||
|
||||
// If we could not create the framebuffer, try again with slightly
|
||||
// different parameters in this order:
|
||||
// 1. Try with the closest size
|
||||
// 2. Try in the opposite screen mode with the original size
|
||||
// 3. Try in the opposite screen mode with the closest size
|
||||
// This is a somewhat confusing mass of recursion here.
|
||||
|
||||
while (fb == NULL || !fb->IsValid ())
|
||||
{
|
||||
if (fb != NULL)
|
||||
{
|
||||
delete fb;
|
||||
}
|
||||
|
||||
switch (retry)
|
||||
{
|
||||
case 0:
|
||||
owidth = width;
|
||||
oheight = height;
|
||||
case 2:
|
||||
// Try a different resolution. Hopefully that will work.
|
||||
I_ClosestResolution (&width, &height, 8);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// Try changing fullscreen mode. Maybe that will work.
|
||||
width = owidth;
|
||||
height = oheight;
|
||||
fullscreen = !fullscreen;
|
||||
break;
|
||||
|
||||
default:
|
||||
// I give up!
|
||||
I_FatalError ("Could not create new screen (%d x %d)", owidth, oheight);
|
||||
}
|
||||
|
||||
++retry;
|
||||
fb = static_cast<SDLFB *>(CreateFrameBuffer (width, height, bgra, fullscreen, NULL));
|
||||
}
|
||||
retry = 0;
|
||||
|
||||
fb->SetFlash (flashColor, flashAmount);
|
||||
|
||||
return fb;
|
||||
}
|
||||
|
||||
void SDLVideo::SetWindowedScale (float scale)
|
||||
{
|
||||
}
|
||||
|
||||
// FrameBuffer implementation -----------------------------------------------
|
||||
|
||||
SDLFB::SDLFB (int width, int height, bool bgra, bool fullscreen, SDL_Window *oldwin)
|
||||
|
|
|
@ -1,21 +1,60 @@
|
|||
#include "hardware.h"
|
||||
#include "v_video.h"
|
||||
#include "sdlglvideo.h"
|
||||
|
||||
class SDLVideo : public IVideo
|
||||
class SDLFB : public DFrameBuffer
|
||||
{
|
||||
public:
|
||||
SDLVideo (int parm);
|
||||
~SDLVideo ();
|
||||
DECLARE_CLASS(SDLFB, SDLBaseFB)
|
||||
public:
|
||||
SDLFB(int width, int height, bool bgra, bool fullscreen, SDL_Window *oldwin);
|
||||
~SDLFB();
|
||||
|
||||
EDisplayType GetDisplayType () { return DISPLAY_Both; }
|
||||
void SetWindowedScale (float scale);
|
||||
bool Lock(bool buffer);
|
||||
void Unlock();
|
||||
bool Relock();
|
||||
void ForceBuffering(bool force);
|
||||
bool IsValid();
|
||||
void Update();
|
||||
PalEntry *GetPalette();
|
||||
void GetFlashedPalette(PalEntry pal[256]);
|
||||
void UpdatePalette();
|
||||
bool SetGamma(float gamma);
|
||||
bool SetFlash(PalEntry rgb, int amount);
|
||||
void GetFlash(PalEntry &rgb, int &amount);
|
||||
void SetFullscreen(bool fullscreen);
|
||||
int GetPageCount();
|
||||
bool IsFullscreen();
|
||||
|
||||
DFrameBuffer *CreateFrameBuffer (int width, int height, bool bgra, bool fs, DFrameBuffer *old);
|
||||
friend class SDLGLVideo;
|
||||
|
||||
void StartModeIterator (int bits, bool fs);
|
||||
bool NextMode (int *width, int *height, bool *letterbox);
|
||||
virtual void SetVSync(bool vsync);
|
||||
virtual void ScaleCoordsFromWindow(SWORD &x, SWORD &y);
|
||||
|
||||
SDL_Window *GetSDLWindow() override { return Screen; }
|
||||
|
||||
private:
|
||||
int IteratorMode;
|
||||
int IteratorBits;
|
||||
PalEntry SourcePalette[256];
|
||||
BYTE GammaTable[3][256];
|
||||
PalEntry Flash;
|
||||
int FlashAmount;
|
||||
float Gamma;
|
||||
bool UpdatePending;
|
||||
|
||||
SDL_Window *Screen;
|
||||
SDL_Renderer *Renderer;
|
||||
union
|
||||
{
|
||||
SDL_Texture *Texture;
|
||||
SDL_Surface *Surface;
|
||||
};
|
||||
|
||||
bool UsingRenderer;
|
||||
bool NeedPalUpdate;
|
||||
bool NeedGammaUpdate;
|
||||
bool NotPaletted;
|
||||
|
||||
void UpdateColors();
|
||||
void ResetSDLRenderer();
|
||||
|
||||
SDLFB() {}
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue