mirror of
https://github.com/LizardByte/Sunshine.git
synced 2025-03-29 22:20:24 +00:00
Delayed capture buffer trim
This commit is contained in:
parent
242a146712
commit
7b11b48317
@ -793,36 +793,91 @@ namespace video {
|
||||
}
|
||||
display_wp = disp;
|
||||
|
||||
constexpr auto capture_buffer_normal_size = 2;
|
||||
constexpr auto capture_buffer_size = 12;
|
||||
std::list<std::shared_ptr<platf::img_t>> imgs(capture_buffer_size);
|
||||
|
||||
std::vector<std::optional<std::chrono::steady_clock::time_point>> imgs_used_timestamps;
|
||||
const std::chrono::seconds trim_timeot = 3s;
|
||||
auto trim_imgs = [&]() {
|
||||
// count allocated and used within current pool
|
||||
size_t allocated_count = 0;
|
||||
size_t used_count = 0;
|
||||
for (const auto &img : imgs) {
|
||||
if (img) {
|
||||
allocated_count += 1;
|
||||
if (img.use_count() > 1) {
|
||||
used_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remember the timestamp of currently used count
|
||||
const auto now = std::chrono::steady_clock::now();
|
||||
if (imgs_used_timestamps.size() <= used_count) {
|
||||
imgs_used_timestamps.resize(used_count + 1);
|
||||
}
|
||||
imgs_used_timestamps[used_count] = now;
|
||||
|
||||
// decide whether to trim allocated unused above the currently used count
|
||||
// based on last used timestamp and universal timeout
|
||||
size_t trim_target = used_count;
|
||||
for (size_t i = used_count; i < imgs_used_timestamps.size(); i++) {
|
||||
if (imgs_used_timestamps[i] && now - *imgs_used_timestamps[i] < trim_timeot) {
|
||||
trim_target = i;
|
||||
}
|
||||
}
|
||||
|
||||
// trim allocated unused above the newly decided trim target
|
||||
if (allocated_count > trim_target) {
|
||||
size_t to_trim = allocated_count - trim_target;
|
||||
// prioritize trimming least recently used
|
||||
for (auto it = imgs.rbegin(); it != imgs.rend(); it++) {
|
||||
auto &img = *it;
|
||||
if (img && img.use_count() == 1) {
|
||||
img.reset();
|
||||
to_trim -= 1;
|
||||
if (to_trim == 0) break;
|
||||
}
|
||||
}
|
||||
// forget timestamps that no longer relevant
|
||||
imgs_used_timestamps.resize(trim_target + 1);
|
||||
}
|
||||
};
|
||||
|
||||
auto pull_free_image_callback = [&](std::shared_ptr<platf::img_t> &img_out) -> bool {
|
||||
img_out.reset();
|
||||
while (capture_ctx_queue->running()) {
|
||||
// pick first allocated but unused
|
||||
for (auto it = imgs.begin(); it != imgs.end(); it++) {
|
||||
// pick first unallocated or unused
|
||||
if (!*it || it->use_count() == 1) {
|
||||
if (!*it) {
|
||||
// allocate if unallocated
|
||||
*it = disp->alloc_img();
|
||||
}
|
||||
if (*it && it->use_count() == 1) {
|
||||
img_out = *it;
|
||||
if (it != imgs.begin()) {
|
||||
// move freshly allocated or unused img to the front of the list to prioritize its reusal
|
||||
// move image to the front of the list to prioritize its reusal
|
||||
imgs.erase(it);
|
||||
imgs.push_front(img_out);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (img_out) {
|
||||
// unallocate unused above normal buffer size
|
||||
size_t index = 0;
|
||||
for (auto &img : imgs) {
|
||||
if (index >= capture_buffer_normal_size && img && img.use_count() == 1) img.reset();
|
||||
index++;
|
||||
// otherwise pick first unallocated
|
||||
if (!img_out) {
|
||||
for (auto it = imgs.begin(); it != imgs.end(); it++) {
|
||||
if (!*it) {
|
||||
// allocate image
|
||||
*it = disp->alloc_img();
|
||||
img_out = *it;
|
||||
if (it != imgs.begin()) {
|
||||
// move image to the front of the list to prioritize its reusal
|
||||
imgs.erase(it);
|
||||
imgs.push_front(img_out);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (img_out) {
|
||||
// trim allocated but unused portion of the pool based on timeouts
|
||||
trim_imgs();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user