mirror of
https://github.com/dhewm/dhewm3.git
synced 2024-12-02 09:13:51 +00:00
SDL3: Handle r_fillWindowAlphaChan, cleanups and comments
r_fillWindowAlphaChan is a hack to work around an older issue with Wayland/Mesa, which has been fixed in Mesa 24.1 (and also seems to work with current NVIDIA drivers). Additionally, in SDL3 the EGL-specific (and thus mostly only affecting Wayland) SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY has been replaced with the generic SDL_PROP_WINDOW_CREATE_TRANSPARENT_BOOLEAN (that could also affect other platforms), so it's harder to enable this only for Wayland. I think most people using SDL3 will use a recent Mesa/driver versions, so I don't enable it by default for SDL3 (SDL2 behaves like before). However, with `r_fillWindowAlphaChan 1` the hack can be enabled anyway (r_fillWindowAlphaChan defaults to "-1" which means "let dhewm3 decide whether to enable this")
This commit is contained in:
parent
3a6210b154
commit
81ba620984
5 changed files with 39 additions and 22 deletions
|
@ -30,7 +30,7 @@ If you have questions concerning this license or the applicable additional terms
|
|||
|
||||
#include "renderer/tr_local.h"
|
||||
|
||||
static idCVar r_fillWindowAlphaChan( "r_fillWindowAlphaChan", "-1", CVAR_SYSTEM | CVAR_NOCHEAT | CVAR_ARCHIVE, "Make sure alpha channel of windows default framebuffer is completely opaque at the end of each frame. Needed at least when using Wayland.\n 1: do this, 0: don't do it, -1: let dhewm3 decide (default)" );
|
||||
static idCVar r_fillWindowAlphaChan( "r_fillWindowAlphaChan", "-1", CVAR_SYSTEM | CVAR_NOCHEAT | CVAR_ARCHIVE, "Make sure alpha channel of windows default framebuffer is completely opaque at the end of each frame. Needed at least when using Wayland with older drivers.\n 1: do this, 0: don't do it, -1: let dhewm3 decide (default)" );
|
||||
|
||||
frameData_t *frameData;
|
||||
backEndState_t backEnd;
|
||||
|
|
|
@ -1073,7 +1073,7 @@ typedef struct {
|
|||
bool fullScreen;
|
||||
bool fullScreenDesktop;
|
||||
bool stereo;
|
||||
int displayHz;
|
||||
int displayHz; // TODO: SDL3 uses float
|
||||
int multiSamples;
|
||||
} glimpParms_t;
|
||||
|
||||
|
|
|
@ -30,9 +30,6 @@ If you have questions concerning this license or the applicable additional terms
|
|||
|
||||
#ifdef D3_SDL3
|
||||
#include <SDL3/SDL_cpuinfo.h>
|
||||
// in SDL3, SDL_Has3DNow() has been removed, and nowadays it's not really relevant anyway,
|
||||
// so just replace it with 0/false
|
||||
#define SDL_Has3DNow() 0
|
||||
#else // SDL1.2 or SDL2
|
||||
#include <SDL_cpuinfo.h>
|
||||
#endif
|
||||
|
@ -208,8 +205,11 @@ int Sys_GetProcessorId( void ) {
|
|||
if (SDL_HasMMX())
|
||||
flags |= CPUID_MMX;
|
||||
|
||||
// SDL3 doesn't support detecting 3DNow, and current CPUs (even from AMD) don't support it either
|
||||
#ifndef D3_SDL3
|
||||
if (SDL_Has3DNow())
|
||||
flags |= CPUID_3DNOW;
|
||||
#endif
|
||||
|
||||
if (SDL_HasSSE())
|
||||
flags |= CPUID_SSE;
|
||||
|
|
|
@ -152,8 +152,6 @@ If you have questions concerning this license or the applicable additional terms
|
|||
|
||||
#define IS_SDL_BTN_DOWN(EV) EV.down
|
||||
|
||||
// FIXME: at some point I need to enable (and possibly later disable) SDL_TextInput!
|
||||
|
||||
#else // SDL2 and SDL1.2
|
||||
|
||||
#define IS_SDL_BTN_DOWN(EV) (EV.state == SDL_PRESSED)
|
||||
|
@ -1209,7 +1207,9 @@ sysEvent_t Sys_GetEvent() {
|
|||
}
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
// s used to have SDL_TEXTINPUTEVENT_TEXT_SIZE (32) bytes, but in SDL3 the string can have
|
||||
// s holds the string from the last SDL_TEXTINPUT event, to generate SE_CHARS D3 events,
|
||||
// one event per call to this function until all chars have been handled
|
||||
// it used to have SDL_TEXTINPUTEVENT_TEXT_SIZE (32) bytes, but in SDL3 the string can have
|
||||
// arbitrary size, however I assume that 128 should still be more than enough
|
||||
static char s[128] = {0};
|
||||
static size_t s_pos = 0;
|
||||
|
@ -1229,6 +1229,9 @@ sysEvent_t Sys_GetEvent() {
|
|||
}
|
||||
#endif
|
||||
|
||||
// c holds a single char for a SE_CHAR event, probably coming from a SDL_KEYDOWN event
|
||||
// (that was also returned as SE_KEY), or from a SDL_TEXTINPUT event that contained just one char.
|
||||
// It's 0 when not currently holding a char to generate an event
|
||||
static byte c = 0;
|
||||
|
||||
if (c) {
|
||||
|
@ -1421,6 +1424,7 @@ sysEvent_t Sys_GetEvent() {
|
|||
if (ev.key.state == SDL_PRESSED && (ev.key.keysym.unicode & 0xff00) == 0)
|
||||
c = ev.key.keysym.unicode & 0xff;
|
||||
#endif
|
||||
// Note: c will be sent as SE_CHAR next time this function is called
|
||||
|
||||
return res;
|
||||
|
||||
|
@ -1440,7 +1444,9 @@ sysEvent_t Sys_GetEvent() {
|
|||
memcpy( s, ev.text.text, SDL_TEXTINPUTEVENT_TEXT_SIZE );
|
||||
s[SDL_TEXTINPUTEVENT_TEXT_SIZE] = '\0';
|
||||
#endif
|
||||
s_pos = 1; // pos 0 is returned
|
||||
// pos 0 is returned, the rest of s is returned as SE_CHAR events
|
||||
// at the next times this function is called
|
||||
s_pos = 1;
|
||||
}
|
||||
return res;
|
||||
} else if( D3_UTF8toISO8859_1( ev.text.text, s, sizeof(s) ) && s[0] != '\0' ) {
|
||||
|
@ -1449,7 +1455,9 @@ sysEvent_t Sys_GetEvent() {
|
|||
s_pos = 0;
|
||||
s[0] = '\0';
|
||||
} else {
|
||||
s_pos = 1; // pos 0 is returned
|
||||
// pos 0 is returned, the rest of s is returned as SE_CHAR events
|
||||
// at the next times this function is called
|
||||
s_pos = 1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -219,20 +219,25 @@ bool GLimp_Init(glimpParms_t parms) {
|
|||
* rendering bugs (the window is partly transparent or very white in areas with low alpha).
|
||||
* Mesa introduced an EGL extension that's supposed to fix that (EGL_EXT_present_opaque)
|
||||
* and newer SDL2 versions use it by default (in the Wayland backend).
|
||||
* Unfortunately, the implementation of that extension is (currently?) broken (at least
|
||||
* in Mesa), seems like they just give you a visual without any alpha chan - which doesn't
|
||||
* Unfortunately, the implementation of that extension was broken (at least in Mesa before 24.1),
|
||||
* seems like they just give you a visual without any alpha chan - which doesn't
|
||||
* work for Doom3, as it needs a functioning alpha chan for blending operations, see above.
|
||||
* See also: https://gitlab.freedesktop.org/mesa/mesa/-/issues/5886
|
||||
*
|
||||
* So to make sure dhewm3 (finally) works as expected on Wayland, we tell SDL2 to
|
||||
* allow transparency and then fill the alpha-chan ourselves in RB_SwapBuffers()
|
||||
* (unless the user disables that with r_fillWindowAlphaChan 0) */
|
||||
* (unless the user disables that with r_fillWindowAlphaChan 0)
|
||||
*
|
||||
* NOTE: This bug is fixed in Mesa 24.1 and newer, and doesn't seem to occur with recent
|
||||
* NVIDIA drivers either, so for SDL3 (which should be mostly used with current drivers/mesa)
|
||||
* I don't enable this hack by default. If r_fillWindowAlphaChan == 1, it's enabled
|
||||
* when creating the window, though.
|
||||
*/
|
||||
#ifdef SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY
|
||||
SDL_SetHint(SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY, "1");
|
||||
#elif SDL_MAJOR_VERSION == 2 // little hack so this works if the SDL2 version used for building is older than runtime version
|
||||
SDL_SetHint("SDL_VIDEO_EGL_ALLOW_TRANSPARENCY", "1");
|
||||
#endif
|
||||
// Note: for SDL3 we use SDL_PROP_WINDOW_CREATE_TRANSPARENT_BOOLEAN below
|
||||
#endif
|
||||
|
||||
int colorbits = 24;
|
||||
|
@ -401,15 +406,17 @@ try_again:
|
|||
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, parms.width);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, parms.height);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_FLAGS_NUMBER, flags);
|
||||
// TODO: the following is probably redundant with the flag already set
|
||||
//if ( parms.fullScreen && parms.fullScreenDesktop ) {
|
||||
// SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_FULLSCREEN_BOOLEAN, true);
|
||||
//} // for exclusive fullscreen, create in windowed mode first, need to call
|
||||
|
||||
// TODO: SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_TRANSPARENT_BOOLEAN, true);
|
||||
// as replacement for SDL_VIDEO_EGL_ALLOW_TRANSPARENCY - but when?
|
||||
// I don't want this on all platforms.. but can I already detect wayland at this point?
|
||||
// Also: recent mesa versions should have this fixed, so maybe ignore the issue for SDL3? what about nvidia?
|
||||
// See above for the big comment about Wayland and alpha channels.
|
||||
// When using SDL3 I assume that people usually won't be affected by this bug,
|
||||
// because it's fixed in recent Mesa versions (and also works with the NVIDIA driver).
|
||||
// However, with `r_fillWindowAlphaChan 1` its usage can still be enforced
|
||||
// on Unix-like platforms (I don't think there's a point in this on Windows or Mac)
|
||||
#if defined(__unix__) && !defined(__APPLE__)
|
||||
if ( cvarSystem->GetCVarInteger( "r_fillWindowAlphaChan" ) == 1 ) {
|
||||
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_TRANSPARENT_BOOLEAN, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
window = SDL_CreateWindowWithProperties(props);
|
||||
SDL_DestroyProperties(props);
|
||||
|
@ -753,7 +760,9 @@ try_again:
|
|||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
const char* videoDriver = SDL_GetCurrentVideoDriver();
|
||||
if (idStr::Icmp(videoDriver, "wayland") == 0) {
|
||||
#if SDL_MAJOR_VERSION == 2 // don't enable this hack by default with SDL3
|
||||
glConfig.shouldFillWindowAlpha = true;
|
||||
#endif
|
||||
glConfig.isWayland = true;
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue