Skip to content

Commit

Permalink
Split texture caches into linear and NN scaled versions
Browse files Browse the repository at this point in the history
With textures, you can't change render scale quality once they've been created. To rectify this, I've
made the texture caches a map of caches, sorted by scale quality. This should result in no performance
overhead, since an image is simply added to the appropriate quality cache on creation instead of in
a single cache. If a different version of a texture is needed it will be loaded later.

By default, load_texture will return images using nearest neighbor scaling. GUI2 always fetches images
using linear scaling. This is consistent with the old software rendering method. Plus, we don't have
any way (as of now) to specify the render quality on a per-image basis.
  • Loading branch information
Vultraz committed Jul 26, 2017
1 parent e962c35 commit dbd6ddb
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 10 deletions.
3 changes: 2 additions & 1 deletion src/gui/core/canvas.cpp
Expand Up @@ -1068,7 +1068,8 @@ void image_shape::draw(
return;
}

image_ = image::get_texture(name);
// NOTE: if we need a key to specify NN scaling it can be added later.
image_ = image::get_texture(name, image::LINEAR);

if(!image_) {
ERR_GUI_D << "Image: '" << name << "' not found and won't be drawn." << std::endl;
Expand Down
31 changes: 25 additions & 6 deletions src/image.cpp
Expand Up @@ -31,6 +31,7 @@
#include "preferences/general.hpp"
#include "serialization/string_utils.hpp"
#include "sdl/rect.hpp"
#include "sdl/render_utils.hpp"
#include "sdl/texture.hpp"
#include "utils/general.hpp"

Expand Down Expand Up @@ -180,7 +181,9 @@ image::image_cache
* Texture caches.
* Note that the latter two are temporary and should be removed once we have OGL and shader support.
*/
image::texture_cache
using texture_cache_map = std::map<image::SCALE_QUALITY, image::texture_cache>;

texture_cache_map
textures_,
textures_hexed_,
texture_tod_colored_;
Expand Down Expand Up @@ -1271,6 +1274,15 @@ bool update_from_preferences()
* are so different. Might move this to a file of its own in the future.
*/

/** Sets the texture scale quality hint. Must be called *before* creating textures! */
static void set_scale_quality_pre_texture_creation(SCALE_QUALITY quality)
{
static const std::string n_scale_str = "nearest";
static const std::string l_scale_str = "linear";

set_texture_scale_quality(quality == NEAREST ? n_scale_str : l_scale_str);
}

/** Loads a new texture directly from disk. */
static texture create_texture_from_file(const image::locator& loc)
{
Expand Down Expand Up @@ -1416,8 +1428,13 @@ static texture create_texture_post_surface_op(const image::locator& i_locator, T
return texture(surf);
}

/** Returns a texture for the corresponding image. */
texture get_texture(const image::locator& i_locator, TYPE type)
{
return get_texture(i_locator, NEAREST, type);
}

/** Returns a texture for the corresponding image. */
texture get_texture(const image::locator& i_locator, SCALE_QUALITY quality, TYPE type)
{
texture res;

Expand All @@ -1436,13 +1453,13 @@ texture get_texture(const image::locator& i_locator, TYPE type)

switch(type) {
case HEXED:
cache = &textures_hexed_;
cache = &textures_hexed_[quality];
break;
case TOD_COLORED:
cache = &texture_tod_colored_;
cache = &texture_tod_colored_[quality];
break;
default:
cache = &textures_;
cache = &textures_[quality];
}

//
Expand All @@ -1464,10 +1481,12 @@ texture get_texture(const image::locator& i_locator, TYPE type)
}

//
// No texture was cached. In that case, create a new one. The explicit cases require special
// No texture was cached. In that case, create a new one. The explicit cases require special
// handling with surfaces in order to generate the desired effect. This shouldn't be the case
// once we get OGL and shader support.
//
set_scale_quality_pre_texture_creation(quality);

switch(type) {
case TOD_COLORED:
case HEXED:
Expand Down
3 changes: 3 additions & 0 deletions src/image.hpp
Expand Up @@ -190,10 +190,13 @@ namespace image {
/// BRIGHTENED : same as TOD_COLORED but also brightened
enum TYPE { UNSCALED, SCALED_TO_ZOOM, HEXED, SCALED_TO_HEX, TOD_COLORED, BRIGHTENED};

enum SCALE_QUALITY { NEAREST, LINEAR };

///function to get the surface corresponding to an image.
surface get_image(const locator& i_locator, TYPE type=UNSCALED);

texture get_texture(const image::locator& i_locator, TYPE type = UNSCALED);
texture get_texture(const image::locator& i_locator, SCALE_QUALITY quality, TYPE type = UNSCALED);

///function to get the surface corresponding to an image.
///after applying the lightmap encoded in ls
Expand Down
11 changes: 11 additions & 0 deletions src/sdl/render_utils.hpp
Expand Up @@ -127,3 +127,14 @@ inline void set_texture_blend_mode(texture& t, SDL_BlendMode mode)
{
SDL_SetTextureBlendMode(t, mode);
}

/**
* Sets the texture scale quality. Note this should be called *before* a texture
* is created, since the hint has no effect on existing textures or render ops.
*
* @param value The scaling mode. Use either 'linear' or 'nearest'.
*/
inline void set_texture_scale_quality(const std::string& value)
{
SDL_SetHintWithPriority(SDL_HINT_RENDER_SCALE_QUALITY, value.c_str(), SDL_HINT_OVERRIDE);
}
3 changes: 0 additions & 3 deletions src/sdl/window.cpp
Expand Up @@ -53,9 +53,6 @@ window::window(const std::string& title,
// Set default blend mode to blend.
SDL_SetRenderDrawBlendMode(*this, SDL_BLENDMODE_BLEND);

// Use linear scaling when rendering, if applicable.
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");

fill(0,0,0);

render();
Expand Down

0 comments on commit dbd6ddb

Please sign in to comment.