mirror of
https://github.com/torlando-tech/pyxis.git
synced 2026-08-24 11:39:49 +00:00
115 lines
3.7 KiB
C++
115 lines
3.7 KiB
C++
// Copyright (c) 2026 Pyxis contributors
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#include "DecodedTileCache.h"
|
|
|
|
#include <cstring>
|
|
|
|
namespace Pyxis {
|
|
|
|
DecodedTileCache::DecodedTileCache(std::size_t pixel_count)
|
|
: pixel_count_(pixel_count), entries_{} {}
|
|
|
|
bool DecodedTileCache::sameKey(const Hardware::TDeck::TileKey& left,
|
|
const Hardware::TDeck::TileKey& right) {
|
|
return left.zoom == right.zoom && left.x == right.x && left.y == right.y;
|
|
}
|
|
|
|
bool DecodedTileCache::attach(std::size_t index, std::uint16_t* pixels) {
|
|
if (index >= CAPACITY || pixels == NULL) return false;
|
|
entries_[index].pixels = pixels;
|
|
entries_[index].valid = false;
|
|
entries_[index].rank = 0U;
|
|
return true;
|
|
}
|
|
|
|
int DecodedTileCache::find(const Hardware::TDeck::TileKey& key) const {
|
|
for (std::size_t index = 0U; index < CAPACITY; ++index) {
|
|
if (entries_[index].pixels != NULL && entries_[index].valid &&
|
|
sameKey(entries_[index].key, key)) {
|
|
return static_cast<int>(index);
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int DecodedTileCache::selectTarget() const {
|
|
int oldest = -1;
|
|
std::uint8_t oldest_rank = 0U;
|
|
for (std::size_t index = 0U; index < CAPACITY; ++index) {
|
|
if (entries_[index].pixels == NULL) continue;
|
|
if (!entries_[index].valid) return static_cast<int>(index);
|
|
if (oldest < 0 || entries_[index].rank > oldest_rank) {
|
|
oldest = static_cast<int>(index);
|
|
oldest_rank = entries_[index].rank;
|
|
}
|
|
}
|
|
return oldest;
|
|
}
|
|
|
|
void DecodedTileCache::touch(std::size_t index) {
|
|
const std::uint8_t previous = entries_[index].valid
|
|
? entries_[index].rank
|
|
: static_cast<std::uint8_t>(CAPACITY);
|
|
for (std::size_t other = 0U; other < CAPACITY; ++other) {
|
|
if (other == index || !entries_[other].valid ||
|
|
entries_[other].pixels == NULL) continue;
|
|
if (entries_[other].rank < previous) ++entries_[other].rank;
|
|
}
|
|
entries_[index].rank = 0U;
|
|
}
|
|
|
|
bool DecodedTileCache::get(const Hardware::TDeck::TileKey& key,
|
|
std::uint16_t* output,
|
|
std::size_t pixel_count) {
|
|
if (output == NULL || pixel_count != pixel_count_) return false;
|
|
const int found = find(key);
|
|
if (found < 0) return false;
|
|
const std::size_t index = static_cast<std::size_t>(found);
|
|
std::memcpy(output, entries_[index].pixels,
|
|
pixel_count_ * sizeof(std::uint16_t));
|
|
touch(index);
|
|
return true;
|
|
}
|
|
|
|
bool DecodedTileCache::put(const Hardware::TDeck::TileKey& key,
|
|
const std::uint16_t* input,
|
|
std::size_t pixel_count) {
|
|
if (input == NULL || pixel_count != pixel_count_) return false;
|
|
int target = find(key);
|
|
if (target < 0) target = selectTarget();
|
|
if (target < 0) return false;
|
|
const std::size_t index = static_cast<std::size_t>(target);
|
|
std::memcpy(entries_[index].pixels, input,
|
|
pixel_count_ * sizeof(std::uint16_t));
|
|
entries_[index].key = key;
|
|
touch(index);
|
|
entries_[index].valid = true;
|
|
return true;
|
|
}
|
|
|
|
void DecodedTileCache::clear() {
|
|
for (std::size_t index = 0U; index < CAPACITY; ++index) {
|
|
entries_[index].valid = false;
|
|
entries_[index].rank = 0U;
|
|
}
|
|
}
|
|
|
|
std::size_t DecodedTileCache::validCount() const {
|
|
std::size_t count = 0U;
|
|
for (std::size_t index = 0U; index < CAPACITY; ++index) {
|
|
if (entries_[index].valid && entries_[index].pixels != NULL) ++count;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
std::size_t DecodedTileCache::attachedCount() const {
|
|
std::size_t count = 0U;
|
|
for (std::size_t index = 0U; index < CAPACITY; ++index) {
|
|
if (entries_[index].pixels != NULL) ++count;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
} // namespace Pyxis
|