四个方向 分块渲染

This commit is contained in:
2026-08-12 09:01:25 +08:00
parent b34c0d31b1
commit 9331b4cbf6
24 changed files with 788 additions and 108 deletions
+69
View File
@@ -0,0 +1,69 @@
#pragma once
#include <algorithm>
#include <chrono>
#include <cstddef>
#include <thread>
namespace renderive::detail {
inline constexpr int maximum_render_partitions = 16;
struct Render_Partition_Range {
std::size_t first{};
std::size_t last{};
};
inline Render_Partition_Range render_partition_range(std::size_t size,
int index,
int count) noexcept {
if (size == 0 || count <= 0 || index < 0 || index >= count)
return {};
return {size * static_cast<std::size_t>(index) / static_cast<std::size_t>(count),
size * static_cast<std::size_t>(index + 1) / static_cast<std::size_t>(count)};
}
class Adaptive_Render_Partitioner {
public:
Adaptive_Render_Partitioner() noexcept
: automatic_count_(std::clamp(
static_cast<int>(std::thread::hardware_concurrency()), 1,
maximum_render_partitions)) {}
int begin(int configured_count, std::size_t work_size) noexcept {
automatic_ = configured_count == 0;
const int requested = automatic_ ? automatic_count_ : configured_count;
const int useful = static_cast<int>(
std::min<std::size_t>(maximum_render_partitions,
std::max<std::size_t>(1, work_size)));
active_count_ = std::clamp(requested, 1,
std::min(maximum_render_partitions, useful));
started_at_ = Clock::now();
return active_count_;
}
void finish(std::size_t work_size) noexcept {
if (!automatic_)
return;
const auto elapsed =
std::chrono::duration_cast<std::chrono::microseconds>(Clock::now() - started_at_);
constexpr auto target = std::chrono::microseconds(1500);
if (elapsed > target * 2 && active_count_ < maximum_render_partitions &&
work_size / static_cast<std::size_t>(active_count_) >= 512) {
automatic_count_ = std::min(maximum_render_partitions, active_count_ + 1);
} else if (elapsed < target / 2 && active_count_ > 1) {
automatic_count_ = active_count_ - 1;
} else {
automatic_count_ = active_count_;
}
}
private:
using Clock = std::chrono::steady_clock;
Clock::time_point started_at_{};
int automatic_count_{1};
int active_count_{1};
bool automatic_{true};
};
} // namespace renderive::detail
+29
View File
@@ -54,6 +54,35 @@ void Renderable::render(const ::Scene_Render_Context& context) {
}
}
void Renderable::build_task_graph(Renderable_Task_Graph& graph) {
build_paint_task_graph(graph);
}
void Renderable::build_paint_task_graph(Renderable_Task_Graph& graph) {
add_paint_task(graph, "paint", [this](detail::Painter& painter,
const Render_State_View& state) {
paint(painter, state);
});
}
Renderable_Task_Graph::Task Renderable::add_paint_task(
Renderable_Task_Graph& graph,
std::string name,
Paint_Task_Function function) {
return graph.emplace(
[this, function = std::move(function)](const Scene_Render_Context& context) {
if (!is_visible() || context.color_cache == nullptr)
return;
auto* cache = dynamic_cast<detail::Blend2D_Color_Cache*>(context.color_cache);
if (!cache)
return;
detail::Painter painter(*cache, viewport_size());
if (painter)
function(painter, render_state_view());
},
std::move(name));
}
void Renderable::changed() noexcept {
invalidate_cache();
plot_.notify_model_dirty();
+9
View File
@@ -6,6 +6,7 @@
#include <renderive/renderable/base/Renderable_Base.hpp>
#include <atomic>
#include <functional>
#include <mutex>
#include <string>
@@ -40,11 +41,19 @@ public:
void render(const ::Scene_Render_Context& context) final;
protected:
using Paint_Task_Function =
std::function<void(detail::Painter&, const Render_State_View&)>;
virtual void paint(detail::Painter& painter, const Render_State_View& state) = 0;
virtual void build_paint_task_graph(Renderable_Task_Graph& graph);
Renderable_Task_Graph::Task add_paint_task(Renderable_Task_Graph& graph,
std::string name,
Paint_Task_Function function);
void changed() noexcept;
[[nodiscard]] Size viewport_size() const noexcept;
private:
void build_task_graph(Renderable_Task_Graph& graph) final;
friend class detail::Renderable_State_Observer;
Plot_Core& plot_;
mutable std::mutex metadata_mutex_;