Fixed bug 4134 - Render targets lose scale quality after minimizing a fullscreen window
authorSam Lantinga <slouken@libsdl.org>
Mon, 07 May 2018 19:52:25 -0700
changeset 11958d7582d7286aa
parent 11957 eba3a7c4ba16
child 11959 4cc8aad8d434
Fixed bug 4134 - Render targets lose scale quality after minimizing a fullscreen window

Olli-Samuli Lehmus

If one creates a window with the SDL_WINDOW_FULLSCREEN_DESKTOP flag, and creates a render target with SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"), and afterwards sets SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest"), after minimizing the window, the scale quality hint is lost on the render target. Textures however do keep their interpolation modes.
src/render/SDL_render.c
src/render/SDL_sysrender.h
src/render/direct3d/SDL_render_d3d.c
src/render/direct3d11/SDL_render_d3d11.c
src/render/metal/SDL_render_metal.m
src/render/opengl/SDL_render_gl.c
src/render/opengles/SDL_render_gles.c
src/render/opengles2/SDL_render_gles2.c
src/render/psp/SDL_render_psp.c
src/render/software/SDL_render_sw.c
     1.1 --- a/src/render/SDL_render.c	Mon May 07 19:26:02 2018 -0700
     1.2 +++ b/src/render/SDL_render.c	Mon May 07 19:52:25 2018 -0700
     1.3 @@ -493,6 +493,21 @@
     1.4      return renderer->info.texture_formats[0];
     1.5  }
     1.6  
     1.7 +SDL_ScaleMode SDL_GetScaleMode(void)
     1.8 +{
     1.9 +    const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
    1.10 +
    1.11 +    if (!hint || SDL_strcasecmp(hint, "nearest") == 0) {
    1.12 +        return SDL_ScaleModeNearest;
    1.13 +    } else if (SDL_strcasecmp(hint, "linear") == 0) {
    1.14 +        return SDL_ScaleModeLinear;
    1.15 +    } else if (SDL_strcasecmp(hint, "best") == 0) {
    1.16 +        return SDL_ScaleModeBest;
    1.17 +    } else {
    1.18 +        return (SDL_ScaleMode)SDL_atoi(hint);
    1.19 +    }
    1.20 +}
    1.21 +
    1.22  SDL_Texture *
    1.23  SDL_CreateTexture(SDL_Renderer * renderer, Uint32 format, int access, int w, int h)
    1.24  {
    1.25 @@ -534,6 +549,7 @@
    1.26      texture->g = 255;
    1.27      texture->b = 255;
    1.28      texture->a = 255;
    1.29 +    texture->scaleMode = SDL_GetScaleMode();
    1.30      texture->renderer = renderer;
    1.31      texture->next = renderer->textures;
    1.32      if (renderer->textures) {
     2.1 --- a/src/render/SDL_sysrender.h	Mon May 07 19:26:02 2018 -0700
     2.2 +++ b/src/render/SDL_sysrender.h	Mon May 07 19:52:25 2018 -0700
     2.3 @@ -31,6 +31,13 @@
     2.4  
     2.5  typedef struct SDL_RenderDriver SDL_RenderDriver;
     2.6  
     2.7 +typedef enum
     2.8 +{
     2.9 +    SDL_ScaleModeNearest,
    2.10 +    SDL_ScaleModeLinear,
    2.11 +    SDL_ScaleModeBest
    2.12 +} SDL_ScaleMode;
    2.13 +
    2.14  typedef struct
    2.15  {
    2.16      float x;
    2.17 @@ -55,6 +62,7 @@
    2.18      int h;                      /**< The height of the texture */
    2.19      int modMode;                /**< The texture modulation mode */
    2.20      SDL_BlendMode blendMode;    /**< The texture blend mode */
    2.21 +    SDL_ScaleMode scaleMode;    /**< The texture scale mode */
    2.22      Uint8 r, g, b, a;           /**< Texture modulation values */
    2.23  
    2.24      SDL_Renderer *renderer;
     3.1 --- a/src/render/direct3d/SDL_render_d3d.c	Mon May 07 19:26:02 2018 -0700
     3.2 +++ b/src/render/direct3d/SDL_render_d3d.c	Mon May 07 19:52:25 2018 -0700
     3.3 @@ -664,18 +664,6 @@
     3.4      return SDL_TRUE;
     3.5  }
     3.6  
     3.7 -static D3DTEXTUREFILTERTYPE
     3.8 -GetScaleQuality(void)
     3.9 -{
    3.10 -    const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
    3.11 -
    3.12 -    if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
    3.13 -        return D3DTEXF_POINT;
    3.14 -    } else /* if (*hint == '1' || SDL_strcasecmp(hint, "linear") == 0) */ {
    3.15 -        return D3DTEXF_LINEAR;
    3.16 -    }
    3.17 -}
    3.18 -
    3.19  static int
    3.20  D3D_CreateTextureRep(IDirect3DDevice9 *device, D3D_TextureRep *texture, DWORD usage, Uint32 format, D3DFORMAT d3dfmt, int w, int h)
    3.21  {
    3.22 @@ -829,7 +817,7 @@
    3.23      if (!texturedata) {
    3.24          return SDL_OutOfMemory();
    3.25      }
    3.26 -    texturedata->scaleMode = GetScaleQuality();
    3.27 +    texturedata->scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? D3DTEXF_POINT : D3DTEXF_LINEAR;
    3.28  
    3.29      texture->driverdata = texturedata;
    3.30  
     4.1 --- a/src/render/direct3d11/SDL_render_d3d11.c	Mon May 07 19:26:02 2018 -0700
     4.2 +++ b/src/render/direct3d11/SDL_render_d3d11.c	Mon May 07 19:52:25 2018 -0700
     4.3 @@ -1161,17 +1161,6 @@
     4.4      return SDL_TRUE;
     4.5  }
     4.6  
     4.7 -static D3D11_FILTER
     4.8 -GetScaleQuality(void)
     4.9 -{
    4.10 -    const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
    4.11 -    if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
    4.12 -        return D3D11_FILTER_MIN_MAG_MIP_POINT;
    4.13 -    } else /* if (*hint == '1' || SDL_strcasecmp(hint, "linear") == 0) */ {
    4.14 -        return D3D11_FILTER_MIN_MAG_MIP_LINEAR;
    4.15 -    }
    4.16 -}
    4.17 -
    4.18  static int
    4.19  D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
    4.20  {
    4.21 @@ -1192,7 +1181,7 @@
    4.22          SDL_OutOfMemory();
    4.23          return -1;
    4.24      }
    4.25 -    textureData->scaleMode = GetScaleQuality();
    4.26 +    textureData->scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ?  D3D11_FILTER_MIN_MAG_MIP_POINT : D3D11_FILTER_MIN_MAG_MIP_LINEAR;
    4.27  
    4.28      texture->driverdata = textureData;
    4.29  
     5.1 --- a/src/render/metal/SDL_render_metal.m	Mon May 07 19:26:02 2018 -0700
     5.2 +++ b/src/render/metal/SDL_render_metal.m	Mon May 07 19:52:25 2018 -0700
     5.3 @@ -853,8 +853,7 @@
     5.4      }
     5.5  
     5.6      METAL_TextureData *texturedata = [[METAL_TextureData alloc] init];
     5.7 -    const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
     5.8 -    if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
     5.9 +    if (texture->scaleMode == SDL_ScaleModeNearest) {
    5.10          texturedata.mtlsampler = data.mtlsamplernearest;
    5.11      } else {
    5.12          texturedata.mtlsampler = data.mtlsamplerlinear;
     6.1 --- a/src/render/opengl/SDL_render_gl.c	Mon May 07 19:26:02 2018 -0700
     6.2 +++ b/src/render/opengl/SDL_render_gl.c	Mon May 07 19:52:25 2018 -0700
     6.3 @@ -703,18 +703,6 @@
     6.4      return SDL_TRUE;
     6.5  }
     6.6  
     6.7 -static GLenum
     6.8 -GetScaleQuality(void)
     6.9 -{
    6.10 -    const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
    6.11 -
    6.12 -    if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
    6.13 -        return GL_NEAREST;
    6.14 -    } else {
    6.15 -        return GL_LINEAR;
    6.16 -    }
    6.17 -}
    6.18 -
    6.19  static int
    6.20  GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
    6.21  {
    6.22 @@ -803,7 +791,7 @@
    6.23  
    6.24      data->format = format;
    6.25      data->formattype = type;
    6.26 -    scaleMode = GetScaleQuality();
    6.27 +    scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? GL_NEAREST : GL_LINEAR;
    6.28      renderdata->glEnable(data->type);
    6.29      renderdata->glBindTexture(data->type, data->texture);
    6.30      renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER, scaleMode);
     7.1 --- a/src/render/opengles/SDL_render_gles.c	Mon May 07 19:26:02 2018 -0700
     7.2 +++ b/src/render/opengles/SDL_render_gles.c	Mon May 07 19:52:25 2018 -0700
     7.3 @@ -524,18 +524,6 @@
     7.4      return value;
     7.5  }
     7.6  
     7.7 -static GLenum
     7.8 -GetScaleQuality(void)
     7.9 -{
    7.10 -    const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
    7.11 -
    7.12 -    if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
    7.13 -        return GL_NEAREST;
    7.14 -    } else {
    7.15 -        return GL_LINEAR;
    7.16 -    }
    7.17 -}
    7.18 -
    7.19  static int
    7.20  GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
    7.21  {
    7.22 @@ -603,7 +591,7 @@
    7.23  
    7.24      data->format = format;
    7.25      data->formattype = type;
    7.26 -    scaleMode = GetScaleQuality();
    7.27 +    scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? GL_NEAREST : GL_LINEAR;
    7.28      renderdata->glBindTexture(data->type, data->texture);
    7.29      renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER, scaleMode);
    7.30      renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER, scaleMode);
     8.1 --- a/src/render/opengles2/SDL_render_gles2.c	Mon May 07 19:26:02 2018 -0700
     8.2 +++ b/src/render/opengles2/SDL_render_gles2.c	Mon May 07 19:52:25 2018 -0700
     8.3 @@ -553,18 +553,6 @@
     8.4  static int GLES2_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture);
     8.5  static void GLES2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture);
     8.6  
     8.7 -static GLenum
     8.8 -GetScaleQuality(void)
     8.9 -{
    8.10 -    const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
    8.11 -
    8.12 -    if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
    8.13 -        return GL_NEAREST;
    8.14 -    } else {
    8.15 -        return GL_LINEAR;
    8.16 -    }
    8.17 -}
    8.18 -
    8.19  static int
    8.20  GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
    8.21  {
    8.22 @@ -625,7 +613,7 @@
    8.23      data->nv12 = ((texture->format == SDL_PIXELFORMAT_NV12) || (texture->format == SDL_PIXELFORMAT_NV21));
    8.24      data->texture_u = 0;
    8.25      data->texture_v = 0;
    8.26 -    scaleMode = GetScaleQuality();
    8.27 +    scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? GL_NEAREST : GL_LINEAR;
    8.28  
    8.29      /* Allocate a blob for image renderdata */
    8.30      if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
     9.1 --- a/src/render/psp/SDL_render_psp.c	Mon May 07 19:26:02 2018 -0700
     9.2 +++ b/src/render/psp/SDL_render_psp.c	Mon May 07 19:52:25 2018 -0700
     9.3 @@ -187,18 +187,6 @@
     9.4  
     9.5  
     9.6  static int
     9.7 -GetScaleQuality(void)
     9.8 -{
     9.9 -    const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
    9.10 -
    9.11 -    if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
    9.12 -        return GU_NEAREST; /* GU_NEAREST good for tile-map */
    9.13 -    } else {
    9.14 -        return GU_LINEAR; /* GU_LINEAR good for scaling */
    9.15 -    }
    9.16 -}
    9.17 -
    9.18 -static int
    9.19  PixelFormatToPSPFMT(Uint32 format)
    9.20  {
    9.21      switch (format) {
    9.22 @@ -514,7 +502,7 @@
    9.23  TextureActivate(SDL_Texture * texture)
    9.24  {
    9.25      PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata;
    9.26 -    int scaleMode = GetScaleQuality();
    9.27 +    int scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? GU_NEAREST : GU_LINEAR;
    9.28  
    9.29      /* Swizzling is useless with small textures. */
    9.30      if (texture->w >= 16 || texture->h >= 16)
    10.1 --- a/src/render/software/SDL_render_sw.c	Mon May 07 19:26:02 2018 -0700
    10.2 +++ b/src/render/software/SDL_render_sw.c	Mon May 07 19:52:25 2018 -0700
    10.3 @@ -588,18 +588,6 @@
    10.4  }
    10.5  
    10.6  static int
    10.7 -GetScaleQuality(void)
    10.8 -{
    10.9 -    const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
   10.10 -
   10.11 -    if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
   10.12 -        return 0;
   10.13 -    } else {
   10.14 -        return 1;
   10.15 -    }
   10.16 -}
   10.17 -
   10.18 -static int
   10.19  SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
   10.20                  const SDL_Rect * srcrect, const SDL_FRect * dstrect,
   10.21                  const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip)
   10.22 @@ -717,7 +705,7 @@
   10.23  
   10.24      if (!retval) {
   10.25          SDLgfx_rotozoomSurfaceSizeTrig(tmp_rect.w, tmp_rect.h, angle, &dstwidth, &dstheight, &cangle, &sangle);
   10.26 -        src_rotated = SDLgfx_rotateSurface(src_clone, angle, dstwidth/2, dstheight/2, GetScaleQuality(), flip & SDL_FLIP_HORIZONTAL, flip & SDL_FLIP_VERTICAL, dstwidth, dstheight, cangle, sangle);
   10.27 +        src_rotated = SDLgfx_rotateSurface(src_clone, angle, dstwidth/2, dstheight/2, (texture->scaleMode == SDL_ScaleModeNearest) ? 0 : 1, flip & SDL_FLIP_HORIZONTAL, flip & SDL_FLIP_VERTICAL, dstwidth, dstheight, cangle, sangle);
   10.28          if (src_rotated == NULL) {
   10.29              retval = -1;
   10.30          }