mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 10:53:44 +00:00
Intel Open Image Denoise 2 (Apache-2.0) behind the CMake option DLU_OIDN (off): an installed OIDN is used when found, else Intel's release package (pinned by hash) is downloaded and its libraries copied next to the servers. A denoiser only removes noise that differs from pixel to pixel; the icons' occlusion comes from the bake, per vertex, which it leaves as it is (checked: white noise 0.17 -> 0.006 relative spread, per-vertex blocks unchanged). So with denoise=oidn a model's icon is drawn from model.noao.nif (its colors before the bake) with its occlusion traced per pixel of the supersampled image (denoise_samples rays, default 4, with the bake's distance and strength and the ray backend), box filtered and denoised at the icon's size, guided by the colors and normals. The model keeps its baked occlusion. Icons drawn again from stored files use the stored model.noao.nif the same way. OIDN works on a thread of its own; its time is charged to the job's thread (UgcThrottle::Charge), so the CPU budget and the recorded CPU time include it. Check: configure with -DDLU_OIDN=ON; UgcServer --make-model x.lxfml out oidn and compare its icon.png with one made with off; an OFF build leaves icons as they were. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
50 lines
2.1 KiB
C++
50 lines
2.1 KiB
C++
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
|
|
/**
|
|
* Keeps the UGC workers' CPU use under a budget. The long loops (renders, ambient occlusion, icons) call Checkpoint
|
|
* every few milliseconds of work; it adds the calling thread's CPU time since its last call to a shared account that
|
|
* the budget fills at `budget` CPUs per second, and sleeps while the account is overdrawn. So the workers together
|
|
* average at most the budget however many there are, long jobs included, and without a budget it costs nothing.
|
|
*/
|
|
namespace UgcThrottle {
|
|
// CPUs the workers may use together on average (1.5: one and a half cores); 0 or less: no limit
|
|
void SetBudget(double cpus);
|
|
double GetBudget();
|
|
|
|
// Account the calling thread's CPU time and sleep when over the budget. Throws Cancelled once Cancel(true) was
|
|
// called, so a job stops in moments when the server shuts down.
|
|
void Checkpoint();
|
|
|
|
// Thrown by Checkpoint while cancelled: the job is abandoned, not failed (its row stays waiting)
|
|
struct Cancelled {};
|
|
// Stop (true) or allow (false) every job's work: set when the server stops, cleared when it starts
|
|
void Cancel(bool cancel);
|
|
bool IsCancelled();
|
|
|
|
// Start accounting on this thread from now (a worker starting a job), so time spent idle isn't counted
|
|
void Begin();
|
|
|
|
struct Stats {
|
|
uint64_t sleptMs{}; // since start
|
|
int64_t lastSleepUnixMs{}; // when it last slept, 0 never
|
|
};
|
|
Stats GetStats();
|
|
|
|
// This thread's CPU time in seconds
|
|
double ThreadCpuSeconds();
|
|
|
|
// CPU time a library spent for this thread on threads of its own (Open Image Denoise's), counted as this thread's:
|
|
// by the budget at the next Checkpoint and in JobCpuSeconds
|
|
void Charge(double seconds);
|
|
// This thread's CPU time with what was charged to it, in seconds (a job's CPU time is the difference)
|
|
double JobCpuSeconds();
|
|
|
|
// Parses "18-23" (from 18:00 to 23:59; may wrap past midnight, "22-6") into from and to; false when it isn't that
|
|
bool ParseHours(const std::string& text, int& from, int& to);
|
|
// Whether `hour` (0-23) is inside the range; never when from or to is negative
|
|
bool InHours(int hour, int from, int to);
|
|
}
|