foxygit / doom Log in
commit f90f95af2624c933a49d94874e677e2d8768282e
Author:     Jonathan Dowland <jon@dow.land>
AuthorDate: Thu Jul 7 22:28:10 2016 +0100
Commit:     Jonathan Dowland <jon+github@alcopop.org>
CommitDate: Wed Jul 13 17:06:57 2016 +0100

    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.
---
 src/i_video.c       | 36 +++++++++++++++++++++++++-----------
 src/i_video.h       |  1 +
 src/m_config.c      |  6 ++++++
 src/setup/display.c |  2 ++
 4 files changed, 34 insertions(+), 11 deletions(-)

diff --git a/src/i_video.c b/src/i_video.c
index 0b986494..ea0d5300 100644
--- a/src/i_video.c
+++ b/src/i_video.c
@@ -116,6 +116,11 @@ int fullscreen = true;

 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 @@ static void SetVideoMode(void)
     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 @@ static void SetVideoMode(void)

     // 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,8 +1078,14 @@ static void SetVideoMode(void)

     // The SDL_RENDERER_TARGETTEXTURE flag is required to render the
     // intermediate texture into the upscaled texture.
+    renderer_flags = SDL_RENDERER_TARGETTEXTURE;
+
+    if (force_software_renderer)
+    {
+        renderer_flags |= SDL_RENDERER_SOFTWARE;
+    }

-    renderer = SDL_CreateRenderer(screen, -1, SDL_RENDERER_TARGETTEXTURE);
+    renderer = SDL_CreateRenderer(screen, -1, renderer_flags);

     if (renderer == NULL)
     {
@@ -1233,6 +1246,7 @@ void I_BindVideoVariables(void)
     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);
diff --git a/src/i_video.h b/src/i_video.h
index 3f414ffb..591e7809 100644
--- a/src/i_video.h
+++ b/src/i_video.h
@@ -92,5 +92,6 @@ extern int screen_width;
 extern int screen_height;
 extern int fullscreen;
 extern int aspect_ratio_correct;
+extern int force_software_renderer;

 #endif
diff --git a/src/m_config.c b/src/m_config.c
index 3d52c085..172c66ce 100644
--- a/src/m_config.c
+++ b/src/m_config.c
@@ -900,6 +900,12 @@ static default_t extra_defaults_list[] =

     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

     //!
diff --git a/src/setup/display.c b/src/setup/display.c
index 51f4de52..75b7ae3f 100644
--- a/src/setup/display.c
+++ b/src/setup/display.c
@@ -66,6 +66,7 @@ static window_size_t window_sizes_scaled[] =
 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 @@ void BindDisplayVariables(void)
     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)