Merge pull request #5697 from stevecotton/simplify_canvas

Simplify canvas: renderer lifetime and only one list of shapes
This commit is contained in:
Charles Dang 2021-04-14 21:50:07 -04:00 committed by GitHub
commit 35348ff246
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 54 deletions

View file

@ -798,12 +798,10 @@ void text_shape::draw(surface& canvas,
canvas::canvas()
: shapes_()
, drawn_shapes_()
, blur_depth_(0)
, w_(0)
, h_(0)
, canvas_()
, renderer_(nullptr)
, variables_()
, functions_()
, is_dirty_(true)
@ -812,24 +810,16 @@ canvas::canvas()
canvas::canvas(canvas&& c) noexcept
: shapes_(std::move(c.shapes_))
, drawn_shapes_(std::move(c.drawn_shapes_))
, blur_depth_(c.blur_depth_)
, w_(c.w_)
, h_(c.h_)
, canvas_(std::move(c.canvas_))
, renderer_(std::exchange(c.renderer_, nullptr))
, variables_(c.variables_)
, functions_(c.functions_)
, is_dirty_(c.is_dirty_)
{
}
canvas::~canvas()
{
if(renderer_)
SDL_DestroyRenderer(renderer_);
}
void canvas::draw(const bool force)
{
log_scope2(log_gui_draw, "Canvas: drawing.");
@ -844,33 +834,27 @@ void canvas::draw(const bool force)
variables_.add("height", wfl::variant(h_));
}
auto renderer = std::unique_ptr<SDL_Renderer, decltype(&SDL_DestroyRenderer)> {nullptr, &SDL_DestroyRenderer};
if(canvas_) {
DBG_GUI_D << "Canvas: use cached canvas.\n";
renderer.reset(SDL_CreateSoftwareRenderer(canvas_));
SDL_SetRenderDrawColor(renderer.get(), 0, 0, 0, 0);
SDL_RenderClear(renderer.get());
} else {
// create surface
DBG_GUI_D << "Canvas: create new empty canvas.\n";
canvas_ = surface(w_, h_);
renderer.reset(SDL_CreateSoftwareRenderer(canvas_));
}
if(renderer_) {
SDL_DestroyRenderer(renderer_);
}
renderer_ = SDL_CreateSoftwareRenderer(canvas_);
SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawBlendMode(renderer.get(), SDL_BLENDMODE_BLEND);
// draw items
for(auto& shape : shapes_) {
lg::scope_logger inner_scope_logging_object__(log_gui_draw, "Canvas: draw shape.");
shape->draw(canvas_, renderer_, variables_);
shape->draw(canvas_, renderer.get(), variables_);
}
// The shapes have been drawn and the draw result has been cached. Clear the list.
std::copy(shapes_.begin(), shapes_.end(), std::back_inserter(drawn_shapes_));
shapes_.clear();
SDL_RenderPresent(renderer_);
SDL_RenderPresent(renderer.get());
is_dirty_ = false;
}
@ -911,17 +895,17 @@ void canvas::parse_cfg(const config& cfg)
DBG_GUI_P << "Canvas: found shape of the type " << type << ".\n";
if(type == "line") {
shapes_.emplace_back(std::make_shared<line_shape>(data));
shapes_.emplace_back(std::make_unique<line_shape>(data));
} else if(type == "rectangle") {
shapes_.emplace_back(std::make_shared<rectangle_shape>(data));
shapes_.emplace_back(std::make_unique<rectangle_shape>(data));
} else if(type == "round_rectangle") {
shapes_.emplace_back(std::make_shared<round_rectangle_shape>(data));
shapes_.emplace_back(std::make_unique<round_rectangle_shape>(data));
} else if(type == "circle") {
shapes_.emplace_back(std::make_shared<circle_shape>(data));
shapes_.emplace_back(std::make_unique<circle_shape>(data));
} else if(type == "image") {
shapes_.emplace_back(std::make_shared<image_shape>(data, functions_));
shapes_.emplace_back(std::make_unique<image_shape>(data, functions_));
} else if(type == "text") {
shapes_.emplace_back(std::make_shared<text_shape>(data));
shapes_.emplace_back(std::make_unique<text_shape>(data));
} else if(type == "pre_commit") {
/* note this should get split if more preprocessing is used. */
@ -949,28 +933,17 @@ void canvas::clear_shapes(const bool force)
{
if(force) {
shapes_.clear();
drawn_shapes_.clear();
} else {
auto conditional = [](const shape_ptr s)->bool { return !s->immutable(); };
auto conditional = [](const std::unique_ptr<shape>& s)->bool { return !s->immutable(); };
auto iter = std::remove_if(shapes_.begin(), shapes_.end(), conditional);
shapes_.erase(iter, shapes_.end());
iter = std::remove_if(drawn_shapes_.begin(), drawn_shapes_.end(), conditional);
drawn_shapes_.erase(iter, drawn_shapes_.end());
}
}
void canvas::invalidate_cache()
{
canvas_ = nullptr;
if(shapes_.empty()) {
shapes_.swap(drawn_shapes_);
} else {
std::copy(drawn_shapes_.begin(), drawn_shapes_.end(), std::inserter(shapes_, shapes_.begin()));
drawn_shapes_.clear();
}
}
/***** ***** ***** ***** ***** SHAPE ***** ***** ***** ***** *****/

View file

@ -84,15 +84,10 @@ public:
bool immutable_;
};
typedef std::shared_ptr<shape> shape_ptr;
typedef std::shared_ptr<const shape> const_shape_ptr;
canvas();
canvas(const canvas&) = delete;
canvas(canvas&& c) noexcept;
~canvas();
/**
* Draws the canvas.
*
@ -180,11 +175,7 @@ public:
private:
/** Vector with the shapes to draw. */
std::vector<shape_ptr> shapes_;
/** All shapes which have been already drawn. Kept around in case
* the cache needs to be invalidated. */
std::vector<shape_ptr> drawn_shapes_;
std::vector<std::unique_ptr<shape>> shapes_;
/**
* The depth of the blur to use in the pre committing.
@ -205,8 +196,6 @@ private:
/** The surface we draw all items on. */
surface canvas_;
SDL_Renderer* renderer_;
/** The variables of the canvas. */
wfl::map_formula_callable variables_;