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 end_stencil() override;
|
||||
|
||||
void start_frame(geom::box<float, 2> const & bbox);
|
||||
void render(geom::matrix<float, 4, 4> const & transform);
|
||||
geom::box<float, 2> current_bbox() const;
|
||||
|
||||
private:
|
||||
psemek_declare_pimpl
|
||||
|
|
|
|||
|
|
@ -173,12 +173,17 @@ namespace psemek::ui
|
|||
|
||||
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 {
|
||||
if (elem->hidden()) return;
|
||||
elem->draw(impl().painter);
|
||||
bool const visible = !(impl().painter.current_bbox() & elem->shape().bbox()).empty();
|
||||
if (visible)
|
||||
elem->draw(impl().painter);
|
||||
for (auto c : elem->children())
|
||||
if (c) self(c);
|
||||
elem->post_draw(impl().painter);
|
||||
if (visible)
|
||||
elem->post_draw(impl().painter);
|
||||
});
|
||||
|
||||
visitor(impl().root.get());
|
||||
|
|
|
|||
|
|
@ -219,6 +219,7 @@ void main()
|
|||
|
||||
int stencil_level = 0;
|
||||
static constexpr int max_stencil_level = 8;
|
||||
std::vector<geom::box<float, 2>> stencil_bbox;
|
||||
|
||||
geom::box<float, 2> draw_bbox;
|
||||
|
||||
|
|
@ -405,6 +406,7 @@ void main()
|
|||
batch.dpass = gl::REPLACE;
|
||||
|
||||
++impl().stencil_level;
|
||||
impl().draw_bbox = {};
|
||||
}
|
||||
|
||||
void painter_impl::commit_stencil()
|
||||
|
|
@ -420,6 +422,8 @@ void main()
|
|||
batch.sfail = gl::KEEP;
|
||||
batch.dfail = gl::KEEP;
|
||||
batch.dpass = gl::KEEP;
|
||||
|
||||
impl().stencil_bbox.push_back(impl().draw_bbox);
|
||||
}
|
||||
|
||||
void painter_impl::end_stencil()
|
||||
|
|
@ -438,7 +442,7 @@ void main()
|
|||
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>({});
|
||||
|
|
@ -457,6 +461,13 @@ void main()
|
|||
}
|
||||
|
||||
--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)
|
||||
|
|
@ -524,13 +535,18 @@ void main()
|
|||
for (auto const & b : impl().batches)
|
||||
std::visit(batch_visitor, b);
|
||||
|
||||
|
||||
impl().max_batch_count = std::max(impl().max_batch_count, impl().batches.size());
|
||||
|
||||
impl().depth = 0;
|
||||
impl().batches.clear();
|
||||
impl().stencil_level = 0;
|
||||
impl().stencil_bbox.clear();
|
||||
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