Skip to content

Commit

Permalink
GUI2/Canvas: optimized cached texture management
Browse files Browse the repository at this point in the history
Instead of throwing out the cached texture every time the canvas was dirty, I've added a flag so that
only happens if its size has actually changed. There still seem to be some issues in GUI2 where canvas
objects keep getting reset, but I'm not sure why. Will have to look into that.

Anyway, the addition of the SDL_RenderClear call also seems to have fixed the weird graphics bleed-through
I was getting when running the game with the OGL driver.

I don't know if the canvas copy or move ctors are needed for anything. I added them for a test, but I'll
leave them for now in case I need them later.
  • Loading branch information
Vultraz committed Jul 26, 2017
1 parent f38346a commit aed88d9
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 6 deletions.
30 changes: 28 additions & 2 deletions src/gui/core/canvas.cpp
Expand Up @@ -1374,6 +1374,7 @@ canvas::canvas()
, variables_()
, functions_()
, is_dirty_(true)
, size_changed_(true)
{
}

Expand All @@ -1398,14 +1399,29 @@ void canvas::draw(const bool force)

DBG_GUI_D << "Canvas: resetting canvas.\n";

// Recreate the texture. Will print an error if creation fails.
texture_.reset(w_, h_, SDL_TEXTUREACCESS_TARGET);
// If cached texture is null or size has changed, throw it out and create a new one.
if(!texture_ || size_changed_) {
texture_.reset(w_, h_, SDL_TEXTUREACCESS_TARGET);

size_changed_ = false;
}

// Something went wrong! Bail! The texture ctor will print the error if applicable.
if(!texture_) {
return;
}

// Set the render target. *Must* be called after the above block in case the texture's
// been recreated or else the game will crash upon trying to write to a null texture.
render_target_setter target_setter(texture_);

// Clear the texture. SDL_RenderClear operates on the current rendering target, so the
// cached texture will be filled in even if it wasn't recreated. This prevents weird
// graphics bleed-through with certain driver configurations.
set_draw_color(renderer_, 0, 0, 0, 0);

SDL_RenderClear(renderer_); // TODO: move to its own wrapper.

// Draw items.
for(auto& shape : shapes_) {
lg::scope_logger inner_scope_logging_object__(log_gui_draw, "Canvas: draw shape.");
Expand Down Expand Up @@ -1508,6 +1524,16 @@ void canvas::clear_shapes(const bool force)
shapes_.erase(iter, shapes_.end());
}

void canvas::update_size(unsigned int& value, unsigned int new_value)
{
if(value != new_value) {
value = new_value;

size_changed_ = true;
set_is_dirty(true);
}
}

/***** ***** ***** ***** ***** SHAPE ***** ***** ***** ***** *****/

} // namespace gui2
Expand Down
15 changes: 11 additions & 4 deletions src/gui/core/canvas.hpp
Expand Up @@ -91,6 +91,9 @@ class canvas
typedef std::shared_ptr<const shape> const_shape_ptr;

canvas();
canvas(const canvas&) = default;
canvas(canvas&&) = default;

~canvas();

/**
Expand Down Expand Up @@ -138,8 +141,7 @@ class canvas

void set_width(const unsigned width)
{
w_ = width;
set_is_dirty(true);
update_size(w_, width);
}

unsigned get_width() const
Expand All @@ -149,8 +151,7 @@ class canvas

void set_height(const unsigned height)
{
h_ = height;
set_is_dirty(true);
update_size(h_, height);
}

unsigned get_height() const
Expand Down Expand Up @@ -204,6 +205,9 @@ class canvas
/** The dirty state of the canvas. */
bool is_dirty_;

/** Whether canvas dimensions changed. */
bool size_changed_;

/**
* Parses a config object.
*
Expand All @@ -217,6 +221,9 @@ class canvas
void parse_cfg(const config& cfg);

void clear_shapes(const bool force);

/** Small helper to handle size variable update logic. */
void update_size(unsigned int& value, unsigned int new_value);
};

} // namespace gui2

0 comments on commit aed88d9

Please sign in to comment.