shithub: choc

Download patch

ref: f90f95af2624c933a49d94874e677e2d8768282e
parent: f4d455c2f00c0e7b172357c05a01ad2f14b0745e
author: Jonathan Dowland <jon@dow.land>
date: Thu Jul 7 18:28:10 EDT 2016

Add force_software_renderer video rendering option

Add a hidden configuration option force_software_renderer which
asks SDL2 to use its own software renderer. This is faster than
Mesa when real acceleration is not available (actually, even if
it is) but reportedly looks worse for some scaling sizes.

Some benchmarks (timedemo demo1)

    setup       before after
    VNC server  50     163
    Mac OS X    279    312

Rename a local variable 'flags' in SetVideoMode to 'window_flags'
to help distinguish it from the new 'renderer_flags' variable.

fixes #741.

--- a/src/i_video.c
+++ b/src/i_video.c
@@ -116,6 +116,11 @@
 
 int aspect_ratio_correct = true;
 
+// Force software rendering, for systems which lack effective hardware
+// acceleration
+
+int force_software_renderer = false;
+
 // Time to wait for the screen to settle on startup before starting the
 // game (ms)
 
@@ -1006,7 +1011,7 @@
     int x, y;
     unsigned int rmask, gmask, bmask, amask;
     int unused_bpp;
-    int flags = 0;
+    int window_flags = 0, renderer_flags = 0;
 
     doompal = W_CacheLumpName(DEH_String("PLAYPAL"), PU_CACHE);
 
@@ -1034,33 +1039,35 @@
 
     // In windowed mode, the window can be resized while the game is
     // running.
-    flags = SDL_WINDOW_RESIZABLE;
+    window_flags = SDL_WINDOW_RESIZABLE;
 
     // Set the highdpi flag - this makes a big difference on Macs with
     // retina displays, especially when using small window sizes.
-    flags |= SDL_WINDOW_ALLOW_HIGHDPI;
+    window_flags |= SDL_WINDOW_ALLOW_HIGHDPI;
 
     if (fullscreen)
     {
         if (fullscreen_width == 0 && fullscreen_height == 0)
         {
-            // This flags means "Never change the screen resolution! Instead,
-            // draw to the entire screen by scaling the texture appropriately".
-            flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
+            // This window_flags means "Never change the screen resolution!
+            // Instead, draw to the entire screen by scaling the texture
+            // appropriately".
+            window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
         }
         else
         {
             w = fullscreen_width;
             h = fullscreen_height;
-            flags |= SDL_WINDOW_FULLSCREEN;
+            window_flags |= SDL_WINDOW_FULLSCREEN;
         }
     }
 
     // Create window and renderer contexts. We set the window title
-    // later anyway and leave the window position "undefined". If "flags"
-    // contains the fullscreen flag (see above), then w and h are ignored.
+    // later anyway and leave the window position "undefined". If
+    // "window_flags" contains the fullscreen flag (see above), then
+    // w and h are ignored.
 
-    screen = SDL_CreateWindow(NULL, x, y, w, h, flags);
+    screen = SDL_CreateWindow(NULL, x, y, w, h, window_flags);
 
     if (screen == NULL)
     {
@@ -1071,9 +1078,15 @@
 
     // The SDL_RENDERER_TARGETTEXTURE flag is required to render the
     // intermediate texture into the upscaled texture.
+    renderer_flags = SDL_RENDERER_TARGETTEXTURE;
 
-    renderer = SDL_CreateRenderer(screen, -1, SDL_RENDERER_TARGETTEXTURE);
+    if (force_software_renderer)
+    {
+        renderer_flags |= SDL_RENDERER_SOFTWARE;
+    }
 
+    renderer = SDL_CreateRenderer(screen, -1, renderer_flags);
+
     if (renderer == NULL)
     {
         I_Error("Error creating renderer for screen window: %s",
@@ -1233,6 +1246,7 @@
     M_BindIntVariable("startup_delay",             &startup_delay);
     M_BindIntVariable("fullscreen_width",          &fullscreen_width);
     M_BindIntVariable("fullscreen_height",         &fullscreen_height);
+    M_BindIntVariable("force_software_renderer",   &force_software_renderer);
     M_BindIntVariable("window_width",              &window_width);
     M_BindIntVariable("window_height",             &window_height);
     M_BindIntVariable("grabmouse",                 &grabmouse);
--- a/src/i_video.h
+++ b/src/i_video.h
@@ -92,5 +92,6 @@
 extern int screen_height;
 extern int fullscreen;
 extern int aspect_ratio_correct;
+extern int force_software_renderer;
 
 #endif
--- a/src/m_config.c
+++ b/src/m_config.c
@@ -900,6 +900,12 @@
 
     CONFIG_VARIABLE_STRING(window_position),
 
+    //!
+    // If non-zero, force the use of a software renderer. For use on
+    // systems lacking hardware acceleration.
+    //
+    CONFIG_VARIABLE_INT(force_software_renderer),
+
 #ifdef FEATURE_MULTIPLAYER
 
     //!
--- a/src/setup/display.c
+++ b/src/setup/display.c
@@ -66,6 +66,7 @@
 static char *video_driver = "";
 static char *window_position = "";
 static int aspect_ratio_correct = 1;
+static int force_software_renderer = 0;
 static int fullscreen = 1;
 static int fullscreen_width = 0, fullscreen_height = 0;
 static int window_width = 640, window_height = 480;
@@ -254,6 +255,7 @@
     M_BindStringVariable("window_position",        &window_position);
     M_BindIntVariable("usegamma",                  &usegamma);
     M_BindIntVariable("png_screenshots",           &png_screenshots);
+    M_BindIntVariable("force_software_renderer",   &force_software_renderer);
 
     if (gamemission == doom || gamemission == heretic
      || gamemission == strife)