From dbd6be2da0bd77579e4496b8ba19087c6db6bab7 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 6 Jan 2020 17:23:38 +0000 Subject: [PATCH] Add OpenGL error reporting (disabled by default) Add way to restart graphics subsystem on fullscreen/windowed mode transitions in OpenGL mode (disabled by default) Add check for pixels being valid in OpenGL to prevent direct crash when the allocation fails. Add define to turn off Pixel Buffer Object usage. (disabled by default) Add a way to specify the windowresolution as percentage of your current resolution. (This centers the window.) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4306 --- src/gui/sdlmain.cpp | 109 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 103 insertions(+), 6 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 96f00312..846e8e9f 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -55,6 +55,10 @@ #if C_OPENGL #include "SDL_opengl.h" +//Define to disable the usage of the pixel buffer object +//#define DB_DISABLE_DBO +//Define to report opengl errors +//#define DB_OPENGL_ERROR #ifndef APIENTRY #define APIENTRY @@ -224,8 +228,28 @@ struct SDL_Block { static SDL_Block sdl; +#if C_OPENGL +#ifdef DB_OPENGL_ERROR +void OPENGL_ERROR(const char* message) { + GLenum r = glGetError(); + if (r == GL_NO_ERROR) return; + LOG_MSG("errors from %s",message); + do { + LOG_MSG("%X",r); + } while ( (r=glGetError()) != GL_NO_ERROR); +} +#else +void OPENGL_ERROR(const char*) { + return; +} +#endif +#endif + #define SETMODE_SAVES 1 //Don't set Video Mode if nothing changes. #define SETMODE_SAVES_CLEAR 1 //Clear the screen, when the Video Mode is reused +//Restart graphics subsystem of SDL when switching windowed and fullscreen in OPENGL +//#define SETMODE_RESTARTS_SUBSYSTEM 1 + SDL_Surface* SDL_SetVideoMode_Wrap(int width,int height,int bpp,Bit32u flags){ #if SETMODE_SAVES static int i_height = 0; @@ -270,13 +294,50 @@ SDL_Surface* SDL_SetVideoMode_Wrap(int width,int height,int bpp,Bit32u flags){ } #endif //WIN32 #endif //SETMODE_SAVES + + +#if C_OPENGL +#ifdef SETMODE_RESTARTS_SUBSYSTEM + SDL_Surface* s = NULL; + Bit32u fx = flags ^i_flags; + Bit32u fa = flags & i_flags; + if (fa&SDL_OPENGL) { + if (fx & SDL_FULLSCREEN) { + if (!(flags & SDL_FULLSCREEN)) { + //RESTART FOR MACS + + //MAYBE move this above the Videomode call above and do not do the setvideomode below. + //Yes this will mess up the title bar and icon. But it is for trying... + + LOG_MSG("HIT RESTART"); + SDL_QuitSubSystem(SDL_INIT_VIDEO); + SDL_InitSubSystem(SDL_INIT_VIDEO); + LOG_MSG("AFTERRESTART"); + s = SDL_SetVideoMode(width,height,bpp,flags); + if (s == NULL) LOG_MSG("Failed to videomode"); + glFinish(); + } + } + } +#else //SETMODE_RESTARTS_SUBSYSTEM SDL_Surface* s = SDL_SetVideoMode(width,height,bpp,flags); +#endif //SETMODE_RESTARTS_SUBSYSTEM +#else //C_OPENGL + SDL_Surface* s = SDL_SetVideoMode(width,height,bpp,flags); +#endif + + #if SETMODE_SAVES if (s == NULL) return s; //Only store when successful i_height = height; i_width = width; i_bpp = bpp; i_flags = flags; +#endif +#if C_OPENGL + if(flags & SDL_OPENGL) { + OPENGL_ERROR("after setmode in wrap"); + } #endif return s; } @@ -715,7 +776,10 @@ dosurface: } glMatrixMode (GL_PROJECTION); - glDeleteTextures(1,&sdl.opengl.texture); + + if (sdl.opengl.texture > 0) { + glDeleteTextures(1,&sdl.opengl.texture); + } glGenTextures(1,&sdl.opengl.texture); glBindTexture(GL_TEXTURE_2D,sdl.opengl.texture); // No borders @@ -764,6 +828,9 @@ dosurface: glEnd(); glEndList(); + + OPENGL_ERROR("End of setsize"); + sdl.desktop.type=SCREEN_OPENGL; retFlags = GFX_CAN_32 | GFX_SCALING; if (sdl.opengl.pixel_buffer_object) @@ -924,8 +991,11 @@ bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch) { if(sdl.opengl.pixel_buffer_object) { glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, sdl.opengl.buffer); pixels=(Bit8u *)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY); - } else + } else { pixels=(Bit8u *)sdl.opengl.framebuf; + } + OPENGL_ERROR("end of start update"); + if (pixels == NULL) return false; pitch=sdl.opengl.pitch; sdl.updating=true; return true; @@ -1237,7 +1307,7 @@ static void GUI_StartUp(Section * sec) { } } } - + Bit16u windowspercentage = 0; sdl.desktop.window.width = 0; sdl.desktop.window.height = 0; const char* windowresolution=section->Get_string("windowresolution"); @@ -1251,13 +1321,20 @@ static void GUI_StartUp(Section * sec) { *height = 0; sdl.desktop.window.height = (Bit16u)atoi(height+1); sdl.desktop.window.width = (Bit16u)atoi(res); + } else { + char* percentage = const_cast(strchr(windowresolution,'%')); + if(percentage && *percentage) { + *percentage = 0; + windowspercentage = (Bit16u) atoi(res); + if (windowspercentage) putenv(const_cast("SDL_VIDEO_CENTERED=1")); + } } } } sdl.desktop.doublebuf=section->Get_bool("fulldouble"); #if SDL_VERSION_ATLEAST(1, 2, 10) -#ifdef WIN32 const SDL_VideoInfo* vidinfo = SDL_GetVideoInfo(); +#ifdef WIN32 if (vidinfo) { int sdl_w = vidinfo->current_w; int sdl_h = vidinfo->current_h; @@ -1271,15 +1348,32 @@ static void GUI_StartUp(Section * sec) { if (!sdl.desktop.full.width || !sdl.desktop.full.height){ //Can only be done on the very first call! Not restartable. //On windows don't use it as SDL returns the values without taking in account the dpi scaling - const SDL_VideoInfo* vidinfo = SDL_GetVideoInfo(); if (vidinfo) { sdl.desktop.full.width = vidinfo->current_w; sdl.desktop.full.height = vidinfo->current_h; } } + + if (!sdl.desktop.window.width || !sdl.desktop.window.height) { + if (vidinfo && windowspercentage) { + sdl.desktop.window.width = ((vidinfo->current_w*windowspercentage)/3200)*32; + sdl.desktop.window.height = ((vidinfo->current_h*windowspercentage)/2400)*24; + } + } + + #endif #endif +#ifdef WIN32 + //Can use the same code as above, if the OS scaling is disabled. + if (!sdl.desktop.window.width && windowspercentage) { + sdl.desktop.window.width = ((GetSystemMetrics(SM_CXSCREEN)*windowspercentage)/3200)*32; + } + if (!sdl.desktop.window.height && windowspercentage) { + sdl.desktop.window.height = ((GetSystemMetrics(SM_CYSCREEN)*windowspercentage)/2400)*24; + } +#endif if (!sdl.desktop.full.width) { #ifdef WIN32 sdl.desktop.full.width=(Bit16u)GetSystemMetrics(SM_CXSCREEN); @@ -1359,7 +1453,10 @@ static void GUI_StartUp(Section * sec) { sdl.opengl.paletted_texture = false; sdl.opengl.pixel_buffer_object = false; } - LOG_MSG("OpenGL extensions: packed pixel %d, paletted_texture %d, pixel_bufer_object %d",sdl.opengl.packed_pixel,sdl.opengl.paletted_texture,sdl.opengl.pixel_buffer_object); +#ifdef DB_DISABLE_DBO + sdl.opengl.pixel_buffer_object = false; +#endif + LOG_MSG("OpenGL extension: pixel_bufer_object %d",sdl.opengl.pixel_buffer_object); } } /* OPENGL is requested end */