srctree

Robin Linden parent 36ed0e32 59d53101
render: Support culling

inlinesplit
render/render.cpp added: 65, removed: 9, total 56
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2021-2023 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2021-2024 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2022 Mikael Larsson <c.mikael.larsson@gmail.com>
//
// SPDX-License-Identifier: BSD-2-Clause
@@ -17,6 +17,7 @@
 
#include <algorithm>
#include <iterator>
#include <optional>
#include <string_view>
#include <utility>
#include <vector>
@@ -123,13 +124,17 @@ bool should_render(layout::LayoutBox const &layout) {
 
} // namespace
 
void render_layout(gfx::ICanvas &painter, layout::LayoutBox const &layout) {
void render_layout(gfx::ICanvas &painter, layout::LayoutBox const &layout, std::optional<geom::Rect> const &clip) {
if (clip && clip->intersected(layout.dimensions.padding_box()).empty()) {
return;
}
 
if (should_render(layout)) {
do_render(painter, layout);
}
 
for (auto const &child : layout.children) {
render_layout(painter, child);
render_layout(painter, child, clip);
}
}
 
 
render/render.h added: 65, removed: 9, total 56
@@ -1,16 +1,19 @@
// SPDX-FileCopyrightText: 2021 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2021-2024 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: BSD-2-Clause
 
#ifndef RENDER_RENDER_H_
#define RENDER_RENDER_H_
 
#include "geom/geom.h"
#include "gfx/icanvas.h"
#include "layout/layout_box.h"
 
#include <optional>
 
namespace render {
 
void render_layout(gfx::ICanvas &, layout::LayoutBox const &);
void render_layout(gfx::ICanvas &, layout::LayoutBox const &, std::optional<geom::Rect> const &clip = std::nullopt);
 
namespace debug {
void render_layout_depth(gfx::ICanvas &, layout::LayoutBox const &);
 
render/render_test.cpp added: 65, removed: 9, total 56
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2022-2023 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2022-2024 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: BSD-2-Clause
 
@@ -383,5 +383,53 @@ int main() {
}});
});
 
etest::test("culling", [] {
dom::Node dom = dom::Element{"dummy"};
auto styled = style::StyledNode{
.node = dom,
.properties = {{css::PropertyId::Display, "block"}, {css::PropertyId::BackgroundColor, "#010203"}},
};
 
auto layout = layout::LayoutBox{
.node = &styled,
.type = layout::LayoutType::Block,
.dimensions = {{0, 0, 20, 40}},
};
 
gfx::CanvasCommandSaver saver;
 
gfx::Color color{1, 2, 3};
CanvasCommands expected{gfx::DrawRectCmd{{0, 0, 20, 40}, color}};
// No cull rect.
render::render_layout(saver, layout);
expect_eq(saver.take_commands(), expected);
 
// Intersecting cull rects.
render::render_layout(saver, layout, geom::Rect{0, 0, 20, 40});
expect_eq(saver.take_commands(), expected);
render::render_layout(saver, layout, geom::Rect{10, 10, 5, 5});
expect_eq(saver.take_commands(), expected);
render::render_layout(saver, layout, geom::Rect{-1, -1, 100, 100});
expect_eq(saver.take_commands(), expected);
render::render_layout(saver, layout, geom::Rect{0, 0, 1, 1});
expect_eq(saver.take_commands(), expected);
render::render_layout(saver, layout, geom::Rect{19, 39, 1, 1});
expect_eq(saver.take_commands(), expected);
render::render_layout(saver, layout, geom::Rect{19, 0, 1, 1});
expect_eq(saver.take_commands(), expected);
render::render_layout(saver, layout, geom::Rect{0, 39, 1, 1});
expect_eq(saver.take_commands(), expected);
 
// Non-intersecting cull rects.
render::render_layout(saver, layout, geom::Rect{0, 40, 1, 1});
expect_eq(saver.take_commands(), CanvasCommands{});
render::render_layout(saver, layout, geom::Rect{20, 40, 1, 1});
expect_eq(saver.take_commands(), CanvasCommands{});
render::render_layout(saver, layout, geom::Rect{20, 0, 1, 1});
expect_eq(saver.take_commands(), CanvasCommands{});
render::render_layout(saver, layout, geom::Rect{-1, 0, 1, 1});
expect_eq(saver.take_commands(), CanvasCommands{});
});
 
return etest::run_all_tests();
}