Rendering Engine 0.2.9
Modular Graphics Rendering Engine | v0.2.9
rendering_engine::TextureCache Class Reference

Manages texture loading, GPU uploading, and caching for reuse. More...

#include <texture_cache.hpp>

Inherits rendering_engine::IRendererObserver.

Public Member Functions

 TextureCache (IRenderer *renderer)
 Constructs the TextureCache with a reference to the renderer. More...
 
 ~TextureCache ()
 
void LoadTexturesFromFolder (std::string pathToFolder)
 Loads all supported texture files (*.jpg, *.png) from a specified folder into RAM and uploads them to the GPU. More...
 
void LoadTexture (std::string textureName, ImageData imageData)
 
void LoadTexturesFromPackage ()
 Loads all textures from the packed asset archive. More...
 
std::string UploadTextureToRAM (std::string path)
 Loads a single texture into RAM from the given file path. More...
 
std::string UploadTextureToRAM (std::string textureFileName, std::vector< uint8_t > const &fileBytes)
 Loads a single texture into RAM from raw file bytes. More...
 
std::string UploadTextureToRAM (std::string textureName, ImageData imageData)
 
void UploadTextureToGPU (std::string textureName)
 Uploads a texture (previously loaded into RAM) to GPU. More...
 
void ReleaseTextureFromGPU (std::string textureName)
 Releases a texture from GPU memory. More...
 
void ReleaseAllFromGPU ()
 Releases all cached textures from GPU memory. More...
 
void ReleaseAll ()
 Fully clears the texture cache, including both RAM and GPU resources. More...
 
std::shared_ptr< ImageDataGpuGetTextureResources (std::string filename)
 Retrieves the full texture resource wrapper from cache. More...
 
ITextureRenderResourcesGetTextureRenderResources (std::string filename)
 Retrieves only the GPU render resources of a cached texture. More...
 
size_t GetSizeInRAM () const
 Gets the total size of all currently cached textures in RAM. More...
 
size_t GetSizeInGPU () const
 Gets the total size of all textures currently uploaded to GPU. More...
 
- Public Member Functions inherited from rendering_engine::IRendererObserver
virtual void OnRenderResourcesRelease ()=0
 Renderer callback: release all GPU resources (used during device loss/reset). More...
 
virtual void OnRenderResourcesRebuild ()=0
 Renderer callback: re-upload or recreate all GPU resources (used after device reset/rebuild). More...
 
virtual ~IRendererObserver ()=default
 Virtual destructor. More...
 

Protected Member Functions

void OnRenderResourcesRelease () override
 Renderer callback: release all GPU resources (used during device loss/reset). More...
 
void OnRenderResourcesRebuild () override
 Renderer callback: re-upload or recreate all GPU resources (used after device reset/rebuild). More...
 

Protected Attributes

IRenderermRenderer
 
std::unordered_map< std::string, std::shared_ptr< ImageDataGpu > > mTextures
 
size_t mTotalSizeRAM
 
size_t mTotalSizeGPU
 

Detailed Description

Manages texture loading, GPU uploading, and caching for reuse.

This class handles texture resource management at runtime. It supports loading image files (JPG and PNG) from a folder or path into RAM, uploading them to GPU, and provides access to the texture resources through string identifiers (filenames without extensions).

Textures are stored using shared pointers to ImageDataGpu, and memory tracking is performed for both RAM and GPU sides.

Definition at line 31 of file texture_cache.hpp.

Constructor & Destructor Documentation

◆ TextureCache()

rendering_engine::TextureCache::TextureCache ( IRenderer renderer)

Constructs the TextureCache with a reference to the renderer.

Parameters
rendererPointer to the active rendering backend.

Definition at line 16 of file texture_cache.cpp.

17 :
18 mRenderer(renderer),
21{
22 LOG_INFO("TextureCache created.");
24}
virtual void RegisterObserver(IRendererObserver *notifier)=0
Registers an observer for rendering events.
#define LOG_INFO(msg)
Definition: logger.hpp:39

◆ ~TextureCache()

rendering_engine::TextureCache::~TextureCache ( )

Definition at line 26 of file texture_cache.cpp.

27{
28 LOG_DEBUG("TextureCache destroyed.");
30}
virtual void UnregisterObserver(IRendererObserver *notifier)=0
Unregisters a previously registered observer.
#define LOG_DEBUG(msg)
Definition: logger.hpp:38

Member Function Documentation

◆ GetSizeInGPU()

size_t rendering_engine::TextureCache::GetSizeInGPU ( ) const

Gets the total size of all textures currently uploaded to GPU.

Returns
GPU memory usage in bytes.

Definition at line 284 of file texture_cache.cpp.

285{
286 return mTotalSizeGPU;
287}

◆ GetSizeInRAM()

size_t rendering_engine::TextureCache::GetSizeInRAM ( ) const

Gets the total size of all currently cached textures in RAM.

Returns
Memory usage in bytes.

Definition at line 279 of file texture_cache.cpp.

280{
281 return mTotalSizeRAM;
282}

◆ GetTextureRenderResources()

ITextureRenderResources * rendering_engine::TextureCache::GetTextureRenderResources ( std::string  filename)

Retrieves only the GPU render resources of a cached texture.

Useful when the caller only needs GPU handles and does not care about image metadata.

Parameters
filenameBase filename used during loading.
Returns
Raw pointer to ITextureRenderResources, or nullptr if not found or not uploaded to GPU.

Definition at line 269 of file texture_cache.cpp.

270{
271 if (auto search = mTextures.find(filename); search == mTextures.end())
272 {
273 return nullptr;
274 }
275
276 return mTextures.at(filename)->GetTextureRenderResources();
277}
std::unordered_map< std::string, std::shared_ptr< ImageDataGpu > > mTextures

◆ GetTextureResources()

std::shared_ptr< ImageDataGpu > rendering_engine::TextureCache::GetTextureResources ( std::string  filename)

Retrieves the full texture resource wrapper from cache.

Parameters
filenameBase filename used during loading.
Returns
Shared pointer to ImageDataGpu, or nullptr if not found.

Definition at line 259 of file texture_cache.cpp.

260{
261 auto search = mTextures.find(filename);
262 if (search == mTextures.end())
263 {
264 return nullptr;
265 }
266 return search->second;
267}

◆ LoadTexture()

void rendering_engine::TextureCache::LoadTexture ( std::string  textureName,
ImageData  imageData 
)

Definition at line 63 of file texture_cache.cpp.

64{
65 // Upload to RAM with textureName + binaryFileData
66 auto textureNameUploaded = UploadTextureToRAM(textureName, imageData);
67 if (!textureNameUploaded.empty())
68 {
69 UploadTextureToGPU(textureNameUploaded);
70 }
71}
std::string UploadTextureToRAM(std::string path)
Loads a single texture into RAM from the given file path.
void UploadTextureToGPU(std::string textureName)
Uploads a texture (previously loaded into RAM) to GPU.

◆ LoadTexturesFromFolder()

void rendering_engine::TextureCache::LoadTexturesFromFolder ( std::string  pathToFolder)

Loads all supported texture files (*.jpg, *.png) from a specified folder into RAM and uploads them to the GPU.

Each texture is registered under its base filename (without extension) for later access. Invalid paths or unsupported file types are skipped silently.

Parameters
pathToFolderAbsolute or relative path to the folder containing texture files.

Definition at line 32 of file texture_cache.cpp.

33{
34 LOG_INFO("Loading textures from folder: " + pathToFolder);
35 auto start = std::chrono::steady_clock::now();
36 // 1. Check if path is valid and exist
37 boost::filesystem::path pathToDirectory = boost::filesystem::path(pathToFolder);
38 const bool isValidFolderPath = boost::filesystem::exists(boost::filesystem::path(pathToFolder)) && boost::filesystem::is_directory(boost::filesystem::path(pathToFolder));
39 if (!isValidFolderPath)
40 {
41 return;
42 }
43 // 2. Iterate through files in the folder.
44 // if file is in the list of supported extensions
45 for (boost::filesystem::directory_entry& x : boost::filesystem::directory_iterator(pathToDirectory))
46 {
47 auto textureName = UploadTextureToRAM(x.path().string());
48 if (!textureName.empty())
49 {
50 UploadTextureToGPU(textureName);
51 }
52 }
53
54 auto end = std::chrono::steady_clock::now();
55 float ms = std::chrono::duration<float, std::milli>(end - start).count();
56
57 LOG_INFO("Loaded " + std::to_string(mTextures.size()) +
58 " textures from folder in " +
59 std::to_string(ms) + " ms. RAM usage: " +
60 std::to_string(mTotalSizeRAM) + " bytes.");
61}

◆ LoadTexturesFromPackage()

void rendering_engine::TextureCache::LoadTexturesFromPackage ( )

Loads all textures from the packed asset archive.

This function behaves similarly to LoadTexturesFromFolder(), but instead of scanning a filesystem directory, it iterates over virtual file entries stored inside the packed content system created by the packaging tool.

Only entries located under the virtual folder: "Textures/" are considered valid texture resources.

For each entry, the raw file bytes are retrieved via Utility::ReadPackedFile(), decoded into an ImageDataGpu instance, and stored in the RAM cache. GPU uploading must still be triggered via UploadTextureToGPU().

Definition at line 73 of file texture_cache.cpp.

74{
75 LOG_INFO("Loading textures from package.");
76 auto start = std::chrono::steady_clock::now();
77 const auto& entries = Utility::GetPackEntries();
78
79 std::string folderEntry = { "Textures/" };
80 for (auto& entry : entries)
81 {
82 const std::string& virtualPath = entry.first;
83 if (virtualPath.rfind(folderEntry, 0) == 0) // starts with Textures/
84 {
85 std::string textureFileName = virtualPath.substr(folderEntry.size());
86
87 std::vector<uint8_t> binaryFileData = Utility::ReadPackedFile(virtualPath);
88 if (binaryFileData.empty())
89 {
90 LOG_ERROR("[TextureCache] Could not read packed texture: "
91 + virtualPath);
92 continue;
93 }
94
95 // Upload to RAM with textureName + binaryFileData
96 auto textureName = UploadTextureToRAM(textureFileName, binaryFileData);
97 if (!textureName.empty())
98 {
99 UploadTextureToGPU(textureName);
100 }
101 }
102 }
103 auto end = std::chrono::steady_clock::now();
104 float ms = std::chrono::duration<float, std::milli>(end - start).count();
105
106 LOG_INFO("Loaded " + std::to_string(mTextures.size()) +
107 " textures from package in " +
108 std::to_string(ms) + " ms. RAM usage: " +
109 std::to_string(mTotalSizeRAM) + " bytes.");
110}
static const PackEntries & GetPackEntries()
Returns the manifest of packed files.
Definition: utility.cpp:281
static std::vector< uint8_t > ReadPackedFile(const std::string &entryPath)
Reads raw bytes of a file stored inside Pack.bin.
Definition: utility.cpp:322
#define LOG_ERROR(msg)
Definition: logger.hpp:41

◆ OnRenderResourcesRebuild()

void rendering_engine::TextureCache::OnRenderResourcesRebuild ( )
overrideprotectedvirtual

Renderer callback: re-upload or recreate all GPU resources (used after device reset/rebuild).

This method will be called after the device or swapchain is recreated, allowing the observer to re-upload or recreate all necessary resources for rendering.

Implements rendering_engine::IRendererObserver.

Definition at line 294 of file texture_cache.cpp.

295{
296 for (auto& texture : mTextures)
297 {
298 texture.second->UploadToGPU();
299 size_t size = texture.second->GetSizeInGPU();
300 mTotalSizeGPU += size;
301 }
302}

◆ OnRenderResourcesRelease()

void rendering_engine::TextureCache::OnRenderResourcesRelease ( )
overrideprotectedvirtual

Renderer callback: release all GPU resources (used during device loss/reset).

This method will be called before any device or swapchain is destroyed, allowing the observer to safely release all handles and deallocate any GPU memory.

Implements rendering_engine::IRendererObserver.

Definition at line 289 of file texture_cache.cpp.

290{
292}
void ReleaseAllFromGPU()
Releases all cached textures from GPU memory.

◆ ReleaseAll()

void rendering_engine::TextureCache::ReleaseAll ( )

Fully clears the texture cache, including both RAM and GPU resources.

Definition at line 247 of file texture_cache.cpp.

248{
249 LOG_INFO("Releasing all textures. RAM usage before clear: " +
250 std::to_string(mTotalSizeRAM) +
251 ", GPU usage: " +
252 std::to_string(mTotalSizeGPU));
254 mTextures.clear();
255 mTotalSizeRAM = 0;
256 mTotalSizeGPU = 0;
257}

◆ ReleaseAllFromGPU()

void rendering_engine::TextureCache::ReleaseAllFromGPU ( )

Releases all cached textures from GPU memory.

This does not affect RAM-side caching.

Definition at line 238 of file texture_cache.cpp.

239{
240 for (auto& texture : mTextures)
241 {
242 texture.second->ReleaseFromGPU();
243 }
244 mTotalSizeGPU = 0;
245}

◆ ReleaseTextureFromGPU()

void rendering_engine::TextureCache::ReleaseTextureFromGPU ( std::string  textureName)

Releases a texture from GPU memory.

The texture remains in RAM cache and can be uploaded again later.

Parameters
filenameCache key of the texture to release (base filename).

Definition at line 223 of file texture_cache.cpp.

224{
225 LOG_DEBUG("Releasing texture from GPU: " + textureName);
226 if (auto search = mTextures.find(textureName); search == mTextures.end())
227 {
228 return;
229 }
230
231 auto& texture = mTextures[textureName];
232 size_t size = texture->GetSizeInGPU();
233 texture->ReleaseFromGPU();
234
235 mTotalSizeGPU -= size;
236}

◆ UploadTextureToGPU()

void rendering_engine::TextureCache::UploadTextureToGPU ( std::string  textureName)

Uploads a texture (previously loaded into RAM) to GPU.

If the texture is not found in RAM cache, the function does nothing.

Parameters
textureNameBase texture name (no path, no extension) used as the cache key.

Definition at line 197 of file texture_cache.cpp.

198{
199 LOG_DEBUG("Uploading texture to GPU: " + textureName);
200 auto start = std::chrono::steady_clock::now();
201 // If texture is not loaded in RAM yet, skip loading to GPU.
202 if (auto search = mTextures.find(textureName); search == mTextures.end())
203 {
204 return;
205 }
206 if (mTextures[textureName]->IsOnGPU())
207 {
208 return;
209 }
210
211 mTextures[textureName]->UploadToGPU();
212 size_t size = mTextures[textureName]->GetSizeInGPU();
213 mTotalSizeGPU += size;
214
215 auto end = std::chrono::steady_clock::now();
216 float ms = std::chrono::duration<float, std::milli>(end - start).count();
217
218 LOG_DEBUG("Texture uploaded to GPU: " + textureName +
219 " (" + std::to_string(size) +
220 " bytes, " + std::to_string(ms) + " ms)");
221}

◆ UploadTextureToRAM() [1/3]

std::string rendering_engine::TextureCache::UploadTextureToRAM ( std::string  path)

Loads a single texture into RAM from the given file path.

The texture will not be uploaded to GPU automatically. The caller must use UploadTextureToGPU() after this call if GPU usage is needed.

Parameters
pathFull file path to the texture image (JPG/PNG).
Returns
The base filename used as the cache key, or an empty string if loading failed.

Definition at line 112 of file texture_cache.cpp.

113{
114 auto filePath = boost::filesystem::path(path);
115 if (!boost::filesystem::is_regular_file(filePath))
116 {
117 return std::string{};
118 }
119
120 const std::string ext = filePath.extension().string();
121 const bool isExtensionSupported = (ext == ".jpg") || (ext == ".png");
122 if (!isExtensionSupported)
123 {
124 return std::string{};
125 }
126
127 std::string filename = filePath.stem().string();
128 // If texture is already loaded into RAM yet, do not add again.
129 if (auto search = mTextures.find(filename); search != mTextures.end())
130 {
131 return std::string{};
132 }
133 LOG_DEBUG("Uploading texture to RAM: " + filename);
134 auto start = std::chrono::steady_clock::now();
135 mTextures[filename] = std::make_shared<ImageDataGpu>(path, mRenderer);
136
137 size_t size = mTextures.at(filename)->GetSizeInRAM();
138 mTotalSizeRAM += size;
139
140 auto end = std::chrono::steady_clock::now();
141 float ms = std::chrono::duration<float, std::milli>(end - start).count();
142
143 LOG_DEBUG("Texture loaded to RAM: " + filename +
144 " (" + std::to_string(size) +
145 " bytes, " + std::to_string(ms) + " ms)");
146
147 return filename;
148}

◆ UploadTextureToRAM() [2/3]

std::string rendering_engine::TextureCache::UploadTextureToRAM ( std::string  textureFileName,
std::vector< uint8_t > const &  fileBytes 
)

Loads a single texture into RAM from raw file bytes.

This overload enables texture loading from virtual files stored in a packed asset archive or from any memory-based source rather than the OS filesystem.

The fileBytes buffer must contain the complete encoded texture data (e.g., PNG or JPEG). The data is decoded and stored inside ImageDataGpu.

Parameters
textureFileNameCache key representing the virtual texture path (e.g., "Textures/myTexture.png" or simply "myTexture").
fileBytesRaw encoded texture file data (PNG/JPG).
Returns
The cache key on success, or an empty string on failure.

Definition at line 150 of file texture_cache.cpp.

151{
152 auto textureName = boost::filesystem::path(textureFileName).stem().string();
153 // If texture is already loaded into RAM yet, do not add again.
154 if (auto search = mTextures.find(textureName); search != mTextures.end())
155 {
156 return std::string{};
157 }
158 LOG_DEBUG("Uploading texture to RAM: " + textureName);
159 auto start = std::chrono::steady_clock::now();
160 mTextures[textureName] = std::make_shared<ImageDataGpu>(fileBytes, mRenderer);
161
162 size_t size = mTextures.at(textureName)->GetSizeInRAM();
163 mTotalSizeRAM += size;
164 auto end = std::chrono::steady_clock::now();
165 float ms = std::chrono::duration<float, std::milli>(end - start).count();
166
167 LOG_DEBUG("Texture loaded to RAM: " + textureName +
168 " (" + std::to_string(size) +
169 " bytes, " + std::to_string(ms) + " ms)");
170
171 return textureName;
172}

◆ UploadTextureToRAM() [3/3]

std::string rendering_engine::TextureCache::UploadTextureToRAM ( std::string  textureName,
ImageData  imageData 
)

Definition at line 174 of file texture_cache.cpp.

175{
176 // If texture is already loaded into RAM yet, do not add again.
177 if (auto search = mTextures.find(textureName); search != mTextures.end())
178 {
179 return std::string{};
180 }
181 LOG_DEBUG("Uploading texture to RAM: " + textureName);
182 auto start = std::chrono::steady_clock::now();
183 mTextures[textureName] = std::make_shared<ImageDataGpu>(imageData, mRenderer);
184
185 size_t size = mTextures.at(textureName)->GetSizeInRAM();
186 mTotalSizeRAM += size;
187 auto end = std::chrono::steady_clock::now();
188 float ms = std::chrono::duration<float, std::milli>(end - start).count();
189
190 LOG_DEBUG("Texture loaded to RAM: " + textureName +
191 " (" + std::to_string(size) +
192 " bytes, " + std::to_string(ms) + " ms)");
193
194 return textureName;
195}

Member Data Documentation

◆ mRenderer

IRenderer* rendering_engine::TextureCache::mRenderer
protected

Definition at line 170 of file texture_cache.hpp.

◆ mTextures

std::unordered_map<std::string, std::shared_ptr<ImageDataGpu> > rendering_engine::TextureCache::mTextures
protected

Definition at line 171 of file texture_cache.hpp.

◆ mTotalSizeGPU

size_t rendering_engine::TextureCache::mTotalSizeGPU
protected

Definition at line 174 of file texture_cache.hpp.

◆ mTotalSizeRAM

size_t rendering_engine::TextureCache::mTotalSizeRAM
protected

Definition at line 173 of file texture_cache.hpp.


The documentation for this class was generated from the following files: