TextureCache.cpp 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #include "TextureCache.h"
  2. #include "AlbumTexture.h"
  3. #include "WallpaperEngine/FileSystem/Container.h"
  4. #include "CTexture.h"
  5. #include "WallpaperEngine/Assets/AssetLoadException.h"
  6. #include "WallpaperEngine/Render/Helpers/ContextAware.h"
  7. #include "WallpaperEngine/Data/Model/Project.h"
  8. #include "WallpaperEngine/Data/Parsers/TextureParser.h"
  9. #include <algorithm>
  10. #include <chrono>
  11. #include <filesystem>
  12. #include <fstream>
  13. using namespace WallpaperEngine::Render;
  14. using namespace WallpaperEngine::FileSystem;
  15. using namespace WallpaperEngine::Data::Parsers;
  16. using namespace WallpaperEngine::Data::Assets;
  17. TextureCache::TextureCache (RenderContext& context) : Helpers::ContextAware (context) {
  18. // these textures are special cases, so make sure they're created only upon request
  19. this->m_currentThumbnail = std::make_shared<AlbumTexture> (this->getContext ());
  20. #if !NDEBUG
  21. glObjectLabel (GL_TEXTURE, this->m_currentThumbnail->getTextureID (0), -1, "$mediaThumbnail");
  22. #endif
  23. this->m_previousThumbnail = std::make_shared<AlbumTexture> (this->getContext ());
  24. #if !NDEBUG
  25. glObjectLabel (GL_TEXTURE, this->m_previousThumbnail->getTextureID (0), -1, "$mediaPreviousThumbnail");
  26. #endif
  27. // load the latest texture (if available)
  28. this->m_currentThumbnail->load ();
  29. // add these to the cache and return the right one
  30. this->store ("$mediaThumbnail", this->m_currentThumbnail);
  31. this->store ("$mediaPreviousThumbnail", this->m_previousThumbnail);
  32. this->m_mediaCallback = this->getContext ().getMediaSource ().addAlbumArtListener (
  33. [this] (const Media::MediaSource::MediaInfo& data) {
  34. if (this->m_currentThumbnail->isReady ()) {
  35. // copy over pixel data and setup the new texture with the new data
  36. this->m_previousThumbnail->copyContents (*this->m_currentThumbnail);
  37. }
  38. // load the next image
  39. this->m_currentThumbnail->load ();
  40. }
  41. );
  42. }
  43. TextureCache::~TextureCache () { this->m_mediaCallback (); }
  44. std::shared_ptr<const TextureProvider> TextureCache::resolve (const std::string& filename) {
  45. if (const auto found = this->m_textureCache.find (filename); found != this->m_textureCache.end ()) {
  46. return found->second;
  47. }
  48. // search for the texture in all the different containers just in case
  49. for (const auto& project : this->getContext ().getApp ().getBackgrounds () | std::views::values) {
  50. try {
  51. const auto contents = project->assetLocator->texture (filename);
  52. auto stream = BinaryReader (contents);
  53. // Create metadata loader lambda that captures the assetLocator
  54. // so we need to construct the full path here
  55. auto metadataLoader = [&project] (const std::string& metaFilename) -> std::string {
  56. std::filesystem::path fullPath = std::filesystem::path ("materials") / metaFilename;
  57. return project->assetLocator->readString (fullPath);
  58. };
  59. auto parsedTexture = TextureParser::parse (stream, filename, metadataLoader);
  60. auto texture = std::make_shared<CTexture> (this->getContext (), std::move (parsedTexture));
  61. #if !NDEBUG
  62. glObjectLabel (GL_TEXTURE, texture->getTextureID (0), -1, filename.c_str ());
  63. #endif
  64. this->store (filename, texture);
  65. return texture;
  66. } catch (AssetLoadException&) {
  67. // ignored, this happens if we're looking at the wrong background
  68. }
  69. }
  70. // TODO: FILL IN WITH A CHECKERED PATTERN TEXTURE INSTEAD?
  71. throw AssetLoadException ("Cannot find file", filename, std::error_code ());
  72. }
  73. void TextureCache::store (const std::string& name, std::shared_ptr<const TextureProvider> texture) {
  74. this->m_textureCache.insert_or_assign (name, texture);
  75. }