1#include "RasterSource.h"
5#include "Rendering/ITextures.h"
7#include "Foundation/Logging/Logger.h"
17Cogs::RasterSource::~RasterSource()
19 for (
auto & r : residentTiles) {
20 auto & tileData = r.second;
22 if (
HandleIsValid(tileData.textureHandle) && tileData.textureHandle != invalidTileHandle) {
23 releaseTexture(tileData.textureHandle, tileData.data.size());
28 releaseTexture(invalidTileHandle, 0);
32Cogs::RasterTile * Cogs::RasterSource::getTile(
const RasterTileIdentifier & identifier)
34 if (
static_cast<size_t>(identifier.level) > getLevels().size() - 1) {
38 const size_t hashCode = identifier.getHashCode();
39 auto tileIt = activeTiles.find(hashCode);
41 if (tileIt == activeTiles.end()) {
42 auto & level = levels[identifier.level];
43 auto & tile = activeTiles[hashCode];
45 tile.identifier = identifier;
46 tile.extent.west = identifier.x * level.getLongitudePostsPerTile();
47 tile.extent.east = std::min(tile.extent.west + level.getLongitudePostsPerTile(), level.getLongitudePosts()) - 1;
48 tile.extent.south = identifier.y * level.getLatitudePostsPerTile();
49 tile.extent.north = std::min(tile.extent.south + level.getLatitudePostsPerTile(), level.getLatitudePosts()) - 1;
50 tile.flags |= level.isTileIndexValid(identifier.x, identifier.y) ? TileFlags::None : TileFlags::OutOfBounds;
54 return &tileIt->second;
60 return &activeTiles[id];
63bool Cogs::RasterSource::tryGetTextureHandle(
const RasterTile * tile, TextureHandle & textureHandle)
66 updateTileUsage(tile);
68 textureHandle = tile->data->textureHandle;
76void Cogs::RasterSource::updateTileUsage(
const RasterTile * tile)
79 if (tile->isOOB())
return;
82 if (tile->usage != 0)
return;
84 auto code = tile->identifier.getHashCode();
87 auto lruIt = lruMap.find(code);
88 if (lruIt != lruMap.end()) {
89 lruList.erase(lruIt->second);
93 lruList.push_front(code);
94 lruMap[code] = lruList.begin();
97void Cogs::RasterSource::refTile(RasterTile * tile)
103 auto code = tile->identifier.getHashCode();
104 auto lruIt = lruMap.find(code);
105 if (lruIt != lruMap.end()) {
106 lruList.erase(lruIt->second);
111void Cogs::RasterSource::unrefTile(RasterTile * tile)
113 assert(tile->usage &&
"Count should not be zero or less when dereferencing a tile.");
115 if (--tile->usage == 0) {
116 updateTileUsage(tile);
120void Cogs::RasterSource::removeTile(RasterTile * tile)
122 deallocateTileStorage(tile->data->data);
124 residentTiles.erase(tile->identifier.getHashCode());
126 tile->data =
nullptr;
129void Cogs::RasterSource::removeTileUsageData(
size_t code)
135void Cogs::RasterSource::evictLruTile()
137 if (!lruList.size())
return;
139 size_t code = lruList.back();
141 assert(lruMap[code] == (--lruList.end()));
143 removeTileUsageData(code);
145 auto tile = getTile(code);
147 releaseTileData(*tile->data);
152void Cogs::RasterSource::loadTileData(RasterTile * tile,
size_t requestGeneration, std::vector<uint8_t> & data, TextureHandle textureHandle, TextureFormat format,
size_t size)
154 if (tile->data && tile->data->generation < requestGeneration) {
155 releaseTileData(*tile->data);
157 if (!tile->isInvalidated()) {
158 auto &
id = tile->identifier;
160 LOG_DEBUG(logger,
"Releasing overwritten tile [%d, %d, %d].",
id.level,
id.x,
id.y);
164 tile->data = tile->data ? tile->data : &residentTiles[tile->identifier.getHashCode()];
166 if (tile->data->generation >= requestGeneration) {
169 deallocateTileStorage(data);
170 if (
HandleIsValid(textureHandle) && textureHandle != invalidTileHandle) {
171 releaseTexture(textureHandle, size);
176 tile->data->textureHandle = textureHandle;
177 tile->data->data = std::move(data);
178 tile->data->format = format;
179 tile->data->size = size;
180 tile->data->generation.store(tile->generation);
184 updateTileUsage(tile);
189void Cogs::RasterSource::invalidateTile(
const RasterTileIdentifier &
id, InvalidationFlags::EInvalidationFlags flags)
191 auto tile = getTile(
id);
194 LOG_WARNING(logger,
"Unable to invalidate tile with invalid identifier.");
200 tile->unsetRequested();
202 if (flags & InvalidationFlags::InvalidateParents) {
203 auto level =
id.level;
205 while (level-- > 0) {
206 auto parentId = RasterTileIdentifier{ level,
id.x / 2,
id.y / 2 };
208 auto parentTile = getTile(parentId);
211 LOG_WARNING(logger,
"Unable to invalidate missing parent tile.");
215 parentTile->invalidate();
216 parentTile->unsetRequested();
239 assert(!hasProcessingRequests() &&
"Cannot purge cache with requests still in processing.");
241 purgeResidentCache();
259 for (
auto & tile : residentTiles) {
260 auto & tileData = tile.second;
262 releaseTileData(tileData);
265 residentTiles.clear();
268Cogs::TextureHandle Cogs::RasterSource::loadTexture(
const unsigned char * data,
const int width,
const int height,
const TextureFormat format,
const size_t size)
270 textureBufferSize += size;
271 return device->getTextures()->loadTexture(data, width, height, format);
274void Cogs::RasterSource::releaseTexture(TextureHandle texture,
const size_t size)
276 device->getTextures()->releaseTexture(texture);
277 textureBufferSize -= size;
282 if (HandleIsValid(tileData.textureHandle) && tileData.textureHandle != invalidTileHandle) {
283 releaseTexture(tileData.textureHandle, tileData.size);
286 if (tileData.data.size()) {
287 deallocateTileStorage(tileData.data);
293 for (
auto & tileData : oldTileData) {
294 releaseTileData(tileData);
Log implementation class.
void releaseTileData(RasterTileData &tileData)
Release the given tile data.
void purgeOldData()
Purges orphaned tile data that has been replaced with new contents.
void purgeResidentCache()
Purge tile data resident in memory and on the GPU.
void purgeCache()
Purge all cache, including resident data.
void cancelActiveRequests()
Cancels all active requests.
bool HandleIsValid(const ResourceHandle_t< T > &handle)
Check if the given resource is valid, that is not equal to NoHandle or InvalidHandle.
constexpr Log getLogger(const char(&name)[LEN]) noexcept