1#include "Foundation/Logging/Logger.h"
2#include "TexAtlasSystem.h"
8 using namespace Cogs::Core::TexAtlas;
12 TreeIx getTreePosition(
const glm::uvec3& tileId)
14 uint64_t a = tileId.x & 0x1FFFFFFFu;
15 uint64_t b = tileId.y & 0x1FFFFFFFu;
16 uint64_t c = tileId.z & 0x0000003Fu;
17 return static_cast<TreeIx
>((c << (29 + 29)) | (b << 29) | a);
20 SlotIx tryEvictACacheSlot(
Cache& cache)
30 if (1 < cache.currentFrame - slot.lastTouched) {
32 assert(slot.treePos != NoTreeIx);
33 cache.tree.erase(slot.treePos);
35 cache.setStateNone(slot);
36 slot.treePos = NoTreeIx;
38 LOG_TRACE(logger,
"Evicted slotIx=%zu",
size_t(slotIx));
50 SlotIx tryAllocNewCacheSlot(
Cache& cache)
52 size_t o = cache.slots.size();
56 SlotIx slotIx =
static_cast<SlotIx
>(o);
61 cache.
lru.emplace_back(slotIx);
67void Cogs::Core::TexAtlas::Cache::update(uint32_t currentFrame_, uint32_t currentTime_, uint32_t minRetryDelay_, uint32_t maxItemCount_)
69 currentFrame = currentFrame_;
70 currentTime = currentTime_;
78 tree.erase(slots[i].treePos);
84 while (!slots.empty() && (100 < (currentFrame - slots.back().lastTouched))) {
85 tree.erase(slots.back().treePos);
90 if (slots.size() !=
lru.size()) {
92 size_t m = slots.size();
93 size_t n =
lru.size();
94 for (
size_t i = 0; i < n; ) {
96 std::swap(
lru[i],
lru.back());
105 assert(slots.size() ==
lru.size());
109 assert(slots.size() ==
lru.size());
110 std::sort(
lru.begin(),
lru.end(),
111 [
this](
const SlotIx& a,
const SlotIx& b) ->
bool
113 uint32_t age_a = currentFrame - slots[a].lastTouched;
114 uint32_t age_b = currentFrame - slots[b].lastTouched;
115 return age_a < age_b;
121 lruPointer =
static_cast<uint32_t
>(slots.size());
125 assert(
lru[i - 1] !=
lru[i]);
129Cogs::Core::TexAtlas::SlotIx Cogs::Core::TexAtlas::Cache::getOrAllocCacheSlot(
Context* context,
Fetcher& fetcher,
const glm::uvec3& tileId)
131 TreeIx treeIx = getTreePosition(tileId);
133 if (
auto it = tree.find(treeIx); it != tree.end()) {
134 SlotIx slotIx = it->second;
136 slot.lastTouched = currentFrame;
140 if (slot.state == Cache::Slot::State::Failed && minRetryDelay && fetcher.
canFetch()) {
141 uint32_t elapsed =
currentTime - slot.stateChangeTime;
142 uint32_t delay = minRetryDelay << slot.retries;
143 if (delay <= elapsed) {
144 if (slot.retries < 15) {
147 LOG_DEBUG(logger,
"Retrying failed tile [%u %u %u] (elapsed=%u delay=%u slot=%u, retry=%u)",
148 tileId.x, tileId.y, tileId.z, elapsed, delay, slotIx, slot.retries);
149 fetcher.
issueFetch(context, tileId, treeIx, slotIx);
150 setStateLoading(slot);
155 else if (slot.state == Cache::Slot::State::Cancelled && fetcher.
canFetch()) {
156 LOG_DEBUG(logger,
"Retrying cancelled tile [%u %u %u] (slot=%u)",
157 tileId.x, tileId.y, tileId.z, slotIx);
158 fetcher.
issueFetch(context, tileId, treeIx, slotIx);
159 setStateLoading(slot);
163 return slot.state == Cache::Slot::State::Loaded ? slotIx : NoSlotIx;
170 SlotIx slotIx = tryEvictACacheSlot(*
this);
173 if (slotIx == NoSlotIx) {
174 slotIx = tryAllocNewCacheSlot(*
this);
178 if (slotIx != NoSlotIx) {
180 slot.treePos = treeIx;
181 slot.lastTouched = currentFrame;
183 assert(tree.find(treeIx) == tree.end());
184 tree[treeIx] = slotIx;
186 fetcher.
issueFetch(context, tileId, treeIx, slotIx);
187 setStateLoading(slot);
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Log implementation class.
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
constexpr Log getLogger(const char(&name)[LEN]) noexcept
COGSFOUNDATION_API Time currentTime()
High resolution clock time (NTP / UTC time). Returns an implementation defined absolute timestamp,...
std::vector< SlotIx > lru
Slots sorted s.t. the least recently used items is at end.
uint32_t maxItemCount
Number of tiles in cache.
uint32_t minRetryDelay
Initial delay for retrying a fetch. For subsequent retries this delay is doubled each time.
uint32_t lruPointer
Points to one past the least recently and recycable item, decrements and zero means nothing to recycl...
void issueFetch(Context *context, const glm::uvec3 &tileId, TreeIx treeIx, SlotIx slotIx)