Files
Renderive/render_2D/renderable/Render_Partition.h
T
2026-08-12 09:45:18 +08:00

71 lines
2.6 KiB
C++

#pragma once
#include <algorithm>
#include <chrono>
#include <cstddef>
#include <limits>
namespace renderive::detail {
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:
[[nodiscard]] int graph_partition_count(int configured_count,
int worker_count) noexcept {
if (configured_count > 0)
return configured_count;
if (automatic_count_ == 0)
automatic_count_ = std::max(1, worker_count);
automatic_count_ = std::clamp(automatic_count_, 1,
std::max(1, worker_count));
return automatic_count_;
}
int begin(int graph_partition_count, std::size_t work_size) noexcept {
const int useful = static_cast<int>(std::min<std::size_t>(
static_cast<std::size_t>(std::numeric_limits<int>::max()),
std::max<std::size_t>(1, work_size)));
started_at_ = Clock::now();
return std::clamp(graph_partition_count, 1, useful);
}
[[nodiscard]] bool finish(int configured_count, int active_count,
int worker_count, std::size_t work_size) noexcept {
if (configured_count != 0)
return false;
const auto elapsed =
std::chrono::duration_cast<std::chrono::microseconds>(Clock::now() - started_at_);
constexpr auto target = std::chrono::microseconds(1500);
const int previous = automatic_count_;
const int maximum = std::max(1, worker_count);
if (elapsed > target * 2 && active_count < maximum &&
work_size / static_cast<std::size_t>(active_count) >= 512)
automatic_count_ = std::min(maximum, active_count + 1);
else if (elapsed < target / 2 && active_count > 1)
automatic_count_ = active_count - 1;
else
automatic_count_ = active_count;
return automatic_count_ != previous;
}
private:
using Clock = std::chrono::steady_clock;
Clock::time_point started_at_{};
int automatic_count_{};
};
} // namespace renderive::detail