Skip to content

Commit

Permalink
Fixed bug 4134 - Render targets lose scale quality after minimizing a…
Browse files Browse the repository at this point in the history
… 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.
  • Loading branch information
slouken committed May 8, 2018
1 parent c04dca0 commit eb14b63
Show file tree
Hide file tree
Showing 10 changed files with 32 additions and 92 deletions.
16 changes: 16 additions & 0 deletions src/render/SDL_render.c
Expand Up @@ -493,6 +493,21 @@ GetClosestSupportedFormat(SDL_Renderer * renderer, Uint32 format)
return renderer->info.texture_formats[0];
}

SDL_ScaleMode SDL_GetScaleMode(void)
{
const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);

if (!hint || SDL_strcasecmp(hint, "nearest") == 0) {
return SDL_ScaleModeNearest;
} else if (SDL_strcasecmp(hint, "linear") == 0) {
return SDL_ScaleModeLinear;
} else if (SDL_strcasecmp(hint, "best") == 0) {
return SDL_ScaleModeBest;
} else {
return (SDL_ScaleMode)SDL_atoi(hint);
}
}

SDL_Texture *
SDL_CreateTexture(SDL_Renderer * renderer, Uint32 format, int access, int w, int h)
{
Expand Down Expand Up @@ -534,6 +549,7 @@ SDL_CreateTexture(SDL_Renderer * renderer, Uint32 format, int access, int w, int
texture->g = 255;
texture->b = 255;
texture->a = 255;
texture->scaleMode = SDL_GetScaleMode();
texture->renderer = renderer;
texture->next = renderer->textures;
if (renderer->textures) {
Expand Down
8 changes: 8 additions & 0 deletions src/render/SDL_sysrender.h
Expand Up @@ -31,6 +31,13 @@

typedef struct SDL_RenderDriver SDL_RenderDriver;

typedef enum
{
SDL_ScaleModeNearest,
SDL_ScaleModeLinear,
SDL_ScaleModeBest
} SDL_ScaleMode;

typedef struct
{
float x;
Expand All @@ -55,6 +62,7 @@ struct SDL_Texture
int h; /**< The height of the texture */
int modMode; /**< The texture modulation mode */
SDL_BlendMode blendMode; /**< The texture blend mode */
SDL_ScaleMode scaleMode; /**< The texture scale mode */
Uint8 r, g, b, a; /**< Texture modulation values */

SDL_Renderer *renderer;
Expand Down
14 changes: 1 addition & 13 deletions src/render/direct3d/SDL_render_d3d.c
Expand Up @@ -664,18 +664,6 @@ D3D_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
return SDL_TRUE;
}

static D3DTEXTUREFILTERTYPE
GetScaleQuality(void)
{
const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);

if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
return D3DTEXF_POINT;
} else /* if (*hint == '1' || SDL_strcasecmp(hint, "linear") == 0) */ {
return D3DTEXF_LINEAR;
}
}

static int
D3D_CreateTextureRep(IDirect3DDevice9 *device, D3D_TextureRep *texture, DWORD usage, Uint32 format, D3DFORMAT d3dfmt, int w, int h)
{
Expand Down Expand Up @@ -829,7 +817,7 @@ D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
if (!texturedata) {
return SDL_OutOfMemory();
}
texturedata->scaleMode = GetScaleQuality();
texturedata->scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? D3DTEXF_POINT : D3DTEXF_LINEAR;

texture->driverdata = texturedata;

Expand Down
13 changes: 1 addition & 12 deletions src/render/direct3d11/SDL_render_d3d11.c
Expand Up @@ -1161,17 +1161,6 @@ D3D11_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
return SDL_TRUE;
}

static D3D11_FILTER
GetScaleQuality(void)
{
const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
return D3D11_FILTER_MIN_MAG_MIP_POINT;
} else /* if (*hint == '1' || SDL_strcasecmp(hint, "linear") == 0) */ {
return D3D11_FILTER_MIN_MAG_MIP_LINEAR;
}
}

static int
D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
Expand All @@ -1192,7 +1181,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
SDL_OutOfMemory();
return -1;
}
textureData->scaleMode = GetScaleQuality();
textureData->scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? D3D11_FILTER_MIN_MAG_MIP_POINT : D3D11_FILTER_MIN_MAG_MIP_LINEAR;

texture->driverdata = textureData;

Expand Down
3 changes: 1 addition & 2 deletions src/render/metal/SDL_render_metal.m
Expand Up @@ -853,8 +853,7 @@ - (void)dealloc
}

METAL_TextureData *texturedata = [[METAL_TextureData alloc] init];
const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
if (texture->scaleMode == SDL_ScaleModeNearest) {
texturedata.mtlsampler = data.mtlsamplernearest;
} else {
texturedata.mtlsampler = data.mtlsamplerlinear;
Expand Down
14 changes: 1 addition & 13 deletions src/render/opengl/SDL_render_gl.c
Expand Up @@ -703,18 +703,6 @@ convert_format(GL_RenderData *renderdata, Uint32 pixel_format,
return SDL_TRUE;
}

static GLenum
GetScaleQuality(void)
{
const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);

if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
return GL_NEAREST;
} else {
return GL_LINEAR;
}
}

static int
GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
Expand Down Expand Up @@ -803,7 +791,7 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)

data->format = format;
data->formattype = type;
scaleMode = GetScaleQuality();
scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? GL_NEAREST : GL_LINEAR;
renderdata->glEnable(data->type);
renderdata->glBindTexture(data->type, data->texture);
renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER, scaleMode);
Expand Down
14 changes: 1 addition & 13 deletions src/render/opengles/SDL_render_gles.c
Expand Up @@ -524,18 +524,6 @@ power_of_2(int input)
return value;
}

static GLenum
GetScaleQuality(void)
{
const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);

if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
return GL_NEAREST;
} else {
return GL_LINEAR;
}
}

static int
GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
Expand Down Expand Up @@ -603,7 +591,7 @@ GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)

data->format = format;
data->formattype = type;
scaleMode = GetScaleQuality();
scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? GL_NEAREST : GL_LINEAR;
renderdata->glBindTexture(data->type, data->texture);
renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER, scaleMode);
renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER, scaleMode);
Expand Down
14 changes: 1 addition & 13 deletions src/render/opengles2/SDL_render_gles2.c
Expand Up @@ -553,18 +553,6 @@ static void GLES2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture);
static int GLES2_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture);
static void GLES2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture);

static GLenum
GetScaleQuality(void)
{
const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);

if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
return GL_NEAREST;
} else {
return GL_LINEAR;
}
}

static int
GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
{
Expand Down Expand Up @@ -625,7 +613,7 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
data->nv12 = ((texture->format == SDL_PIXELFORMAT_NV12) || (texture->format == SDL_PIXELFORMAT_NV21));
data->texture_u = 0;
data->texture_v = 0;
scaleMode = GetScaleQuality();
scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? GL_NEAREST : GL_LINEAR;

/* Allocate a blob for image renderdata */
if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
Expand Down
14 changes: 1 addition & 13 deletions src/render/psp/SDL_render_psp.c
Expand Up @@ -186,18 +186,6 @@ TextureNextPow2(unsigned int w)
}


static int
GetScaleQuality(void)
{
const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);

if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
return GU_NEAREST; /* GU_NEAREST good for tile-map */
} else {
return GU_LINEAR; /* GU_LINEAR good for scaling */
}
}

static int
PixelFormatToPSPFMT(Uint32 format)
{
Expand Down Expand Up @@ -514,7 +502,7 @@ void
TextureActivate(SDL_Texture * texture)
{
PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata;
int scaleMode = GetScaleQuality();
int scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? GU_NEAREST : GU_LINEAR;

/* Swizzling is useless with small textures. */
if (texture->w >= 16 || texture->h >= 16)
Expand Down
14 changes: 1 addition & 13 deletions src/render/software/SDL_render_sw.c
Expand Up @@ -587,18 +587,6 @@ SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
}
}

static int
GetScaleQuality(void)
{
const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);

if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
return 0;
} else {
return 1;
}
}

static int
SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_FRect * dstrect,
Expand Down Expand Up @@ -717,7 +705,7 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,

if (!retval) {
SDLgfx_rotozoomSurfaceSizeTrig(tmp_rect.w, tmp_rect.h, angle, &dstwidth, &dstheight, &cangle, &sangle);
src_rotated = SDLgfx_rotateSurface(src_clone, angle, dstwidth/2, dstheight/2, GetScaleQuality(), flip & SDL_FLIP_HORIZONTAL, flip & SDL_FLIP_VERTICAL, dstwidth, dstheight, cangle, sangle);
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);
if (src_rotated == NULL) {
retval = -1;
}
Expand Down

0 comments on commit eb14b63

Please sign in to comment.