Optimize ui painter to not draw elements not in the current bbox
This commit is contained in:
parent
e237959894
commit
884a7c745b
3 changed files with 27 additions and 4 deletions
|
|
@ -26,7 +26,9 @@ namespace psemek::ui
|
||||||
void commit_stencil() override;
|
void commit_stencil() override;
|
||||||
void end_stencil() override;
|
void end_stencil() override;
|
||||||
|
|
||||||
|
void start_frame(geom::box<float, 2> const & bbox);
|
||||||
void render(geom::matrix<float, 4, 4> const & transform);
|
void render(geom::matrix<float, 4, 4> const & transform);
|
||||||
|
geom::box<float, 2> current_bbox() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
psemek_declare_pimpl
|
psemek_declare_pimpl
|
||||||
|
|
|
||||||
|
|
@ -173,11 +173,16 @@ namespace psemek::ui
|
||||||
|
|
||||||
void controller::render(gfx::render_target const & rt)
|
void controller::render(gfx::render_target const & rt)
|
||||||
{
|
{
|
||||||
|
impl().painter.start_frame(geom::cast<float>(rt.viewport));
|
||||||
|
|
||||||
auto visitor = util::recursive([&](auto && self, element * elem) -> void {
|
auto visitor = util::recursive([&](auto && self, element * elem) -> void {
|
||||||
if (elem->hidden()) return;
|
if (elem->hidden()) return;
|
||||||
|
bool const visible = !(impl().painter.current_bbox() & elem->shape().bbox()).empty();
|
||||||
|
if (visible)
|
||||||
elem->draw(impl().painter);
|
elem->draw(impl().painter);
|
||||||
for (auto c : elem->children())
|
for (auto c : elem->children())
|
||||||
if (c) self(c);
|
if (c) self(c);
|
||||||
|
if (visible)
|
||||||
elem->post_draw(impl().painter);
|
elem->post_draw(impl().painter);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -219,6 +219,7 @@ void main()
|
||||||
|
|
||||||
int stencil_level = 0;
|
int stencil_level = 0;
|
||||||
static constexpr int max_stencil_level = 8;
|
static constexpr int max_stencil_level = 8;
|
||||||
|
std::vector<geom::box<float, 2>> stencil_bbox;
|
||||||
|
|
||||||
geom::box<float, 2> draw_bbox;
|
geom::box<float, 2> draw_bbox;
|
||||||
|
|
||||||
|
|
@ -405,6 +406,7 @@ void main()
|
||||||
batch.dpass = gl::REPLACE;
|
batch.dpass = gl::REPLACE;
|
||||||
|
|
||||||
++impl().stencil_level;
|
++impl().stencil_level;
|
||||||
|
impl().draw_bbox = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void painter_impl::commit_stencil()
|
void painter_impl::commit_stencil()
|
||||||
|
|
@ -420,6 +422,8 @@ void main()
|
||||||
batch.sfail = gl::KEEP;
|
batch.sfail = gl::KEEP;
|
||||||
batch.dfail = gl::KEEP;
|
batch.dfail = gl::KEEP;
|
||||||
batch.dpass = gl::KEEP;
|
batch.dpass = gl::KEEP;
|
||||||
|
|
||||||
|
impl().stencil_bbox.push_back(impl().draw_bbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
void painter_impl::end_stencil()
|
void painter_impl::end_stencil()
|
||||||
|
|
@ -438,7 +442,7 @@ void main()
|
||||||
clear_batch.dpass = gl::REPLACE;
|
clear_batch.dpass = gl::REPLACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
draw_rect(impl().draw_bbox, {0, 0, 0, 255});
|
draw_rect(impl().stencil_bbox.back(), {0, 0, 0, 255});
|
||||||
|
|
||||||
{
|
{
|
||||||
auto & batch = impl().batch<stencil_batch>({});
|
auto & batch = impl().batch<stencil_batch>({});
|
||||||
|
|
@ -457,6 +461,13 @@ void main()
|
||||||
}
|
}
|
||||||
|
|
||||||
--impl().stencil_level;
|
--impl().stencil_level;
|
||||||
|
|
||||||
|
impl().stencil_bbox.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
void painter_impl::start_frame(geom::box<float, 2> const & bbox)
|
||||||
|
{
|
||||||
|
impl().stencil_bbox.push_back(bbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
void painter_impl::render(geom::matrix<float, 4, 4> const & transform)
|
void painter_impl::render(geom::matrix<float, 4, 4> const & transform)
|
||||||
|
|
@ -524,13 +535,18 @@ void main()
|
||||||
for (auto const & b : impl().batches)
|
for (auto const & b : impl().batches)
|
||||||
std::visit(batch_visitor, b);
|
std::visit(batch_visitor, b);
|
||||||
|
|
||||||
|
|
||||||
impl().max_batch_count = std::max(impl().max_batch_count, impl().batches.size());
|
impl().max_batch_count = std::max(impl().max_batch_count, impl().batches.size());
|
||||||
|
|
||||||
impl().depth = 0;
|
impl().depth = 0;
|
||||||
impl().batches.clear();
|
impl().batches.clear();
|
||||||
impl().stencil_level = 0;
|
impl().stencil_level = 0;
|
||||||
|
impl().stencil_bbox.clear();
|
||||||
impl().draw_bbox = {};
|
impl().draw_bbox = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
geom::box<float, 2> painter_impl::current_bbox() const
|
||||||
|
{
|
||||||
|
return impl().stencil_bbox.back();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue