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 auto i = activeTiles.find(
id);
62 if (i != activeTiles.end()) {
68bool Cogs::RasterSource::tryGetTextureHandle(
const RasterTile * tile, TextureHandle & textureHandle)
71 updateTileUsage(tile);
73 textureHandle = tile->data->textureHandle;
81void Cogs::RasterSource::updateTileUsage(
const RasterTile * tile)
84 if (tile->isOOB())
return;
87 if (tile->usage != 0)
return;
89 auto code = tile->identifier.getHashCode();
92 auto lruIt = lruMap.find(code);
93 if (lruIt != lruMap.end()) {
94 lruList.erase(lruIt->second);
98 lruList.push_front(code);
99 lruMap[code] = lruList.begin();
102void Cogs::RasterSource::refTile(RasterTile * tile)
108 auto code = tile->identifier.getHashCode();
109 auto lruIt = lruMap.find(code);
110 if (lruIt != lruMap.end()) {
111 lruList.erase(lruIt->second);
116void Cogs::RasterSource::unrefTile(RasterTile * tile)
118 assert(tile->usage &&
"Count should not be zero or less when dereferencing a tile.");
120 if (--tile->usage == 0) {
121 updateTileUsage(tile);
125void Cogs::RasterSource::removeTile(RasterTile * tile)
127 deallocateTileStorage(tile->data->data);
129 residentTiles.erase(tile->identifier.getHashCode());
131 tile->data =
nullptr;
134void Cogs::RasterSource::removeTileUsageData(
size_t code)
140void Cogs::RasterSource::evictLruTile()
142 if (!lruList.size())
return;
144 size_t code = lruList.back();
146 assert(lruMap[code] == (--lruList.end()));
148 removeTileUsageData(code);
150 auto tile = getTile(code);
152 releaseTileData(*tile->data);
157void Cogs::RasterSource::loadTileData(RasterTile * tile,
size_t requestGeneration, std::vector<uint8_t> & data, TextureHandle textureHandle, TextureFormat format,
size_t size)
159 if (tile->data && tile->data->generation < requestGeneration) {
160 releaseTileData(*tile->data);
162 if (!tile->isInvalidated()) {
163 auto &
id = tile->identifier;
165 LOG_DEBUG(logger,
"Releasing overwritten tile [%d, %d, %d].",
id.level,
id.x,
id.y);
169 tile->data = tile->data ? tile->data : &residentTiles[tile->identifier.getHashCode()];
171 if (tile->data->generation >= requestGeneration) {
174 deallocateTileStorage(data);
175 if (
HandleIsValid(textureHandle) && textureHandle != invalidTileHandle) {
176 releaseTexture(textureHandle, size);
181 tile->data->textureHandle = textureHandle;
182 tile->data->data = std::move(data);
183 tile->data->format = format;
184 tile->data->size = size;
185 tile->data->generation.store(tile->generation);
189 updateTileUsage(tile);
194void Cogs::RasterSource::invalidateTile(
const RasterTileIdentifier &
id, InvalidationFlags::EInvalidationFlags flags)
196 auto tile = getTile(
id);
199 LOG_WARNING(logger,
"Unable to invalidate tile with invalid identifier.");
205 tile->unsetRequested();
207 if (flags & InvalidationFlags::InvalidateParents) {
208 auto level =
id.level;
210 while (level-- > 0) {
211 auto parentId = RasterTileIdentifier{ level,
id.x / 2,
id.y / 2 };
213 auto parentTile = getTile(parentId);
216 LOG_WARNING(logger,
"Unable to invalidate missing parent tile.");
220 parentTile->invalidate();
221 parentTile->unsetRequested();
244 assert(!hasProcessingRequests() &&
"Cannot purge cache with requests still in processing.");
246 purgeResidentCache();
264 for (
auto & tile : residentTiles) {
265 auto & tileData = tile.second;
267 releaseTileData(tileData);
270 residentTiles.clear();
273Cogs::TextureHandle Cogs::RasterSource::loadTexture(
const unsigned char * data,
const int width,
const int height,
const TextureFormat format,
const size_t size)
275 textureBufferSize += size;
276 return device->getTextures()->loadTexture(data, width, height, format);
279void Cogs::RasterSource::releaseTexture(TextureHandle texture,
const size_t size)
281 device->getTextures()->releaseTexture(texture);
282 textureBufferSize -= size;
287 if (HandleIsValid(tileData.textureHandle) && tileData.textureHandle != invalidTileHandle) {
288 releaseTexture(tileData.textureHandle, tileData.size);
291 if (tileData.data.size()) {
292 deallocateTileStorage(tileData.data);
298 for (
auto & tileData : oldTileData) {
299 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