git.s-ol.nu ~forks/DiligentTools / f9f8a42
GLTFLoader: made sure that texture files are not loaded when found in the cache assiduous 11 months ago
2 changed file(s) with 85 addition(s) and 44 deletion(s). Raw diff Collapse all Expand all
684684 const auto CacheId = !gltf_image.uri.empty() ? BaseDir + gltf_image.uri : "";
685685
686686 TextureInfo TexInfo;
687 if (CacheInfo.pResourceMgr != nullptr)
688 {
689 TexInfo.pAtlasSuballocation = CacheInfo.pResourceMgr->FindAllocation(CacheId.c_str());
690 if (TexInfo.pAtlasSuballocation)
691 {
692 // Note that the texture may appear in the cache after the call to LoadImageData because
693 // it can be loaded by another thread
694 VERIFY_EXPR(gltf_image.width == -1 || gltf_image.width == static_cast<int>(TexInfo.pAtlasSuballocation->GetSize().x));
695 VERIFY_EXPR(gltf_image.height == -1 || gltf_image.height == static_cast<int>(TexInfo.pAtlasSuballocation->GetSize().y));
696 }
697 }
698 else if (pTextureCache != nullptr)
699 {
700 std::lock_guard<std::mutex> Lock{pTextureCache->TexturesMtx};
701
702 auto it = pTextureCache->Textures.find(CacheId);
703 if (it != pTextureCache->Textures.end())
704 {
705 TexInfo.pTexture = it->second.Lock();
706 if (!TexInfo.pTexture)
707 {
708 // Image width and height (or pixel_type for dds/ktx) are initialized by LoadImageData()
709 // if the texture is found in the cache.
710 if ((gltf_image.width > 0 && gltf_image.height > 0) ||
711 (gltf_image.pixel_type == IMAGE_FILE_FORMAT_DDS || gltf_image.pixel_type == IMAGE_FILE_FORMAT_KTX))
687 if (!CacheId.empty())
688 {
689 if (CacheInfo.pResourceMgr != nullptr)
690 {
691 TexInfo.pAtlasSuballocation = CacheInfo.pResourceMgr->FindAllocation(CacheId.c_str());
692 if (TexInfo.pAtlasSuballocation)
693 {
694 // Note that the texture may appear in the cache after the call to LoadImageData because
695 // it can be loaded by another thread
696 VERIFY_EXPR(gltf_image.width == -1 || gltf_image.width == static_cast<int>(TexInfo.pAtlasSuballocation->GetSize().x));
697 VERIFY_EXPR(gltf_image.height == -1 || gltf_image.height == static_cast<int>(TexInfo.pAtlasSuballocation->GetSize().y));
698 }
699 }
700 else if (pTextureCache != nullptr)
701 {
702 std::lock_guard<std::mutex> Lock{pTextureCache->TexturesMtx};
703
704 auto it = pTextureCache->Textures.find(CacheId);
705 if (it != pTextureCache->Textures.end())
706 {
707 TexInfo.pTexture = it->second.Lock();
708 if (!TexInfo.pTexture)
712709 {
713 UNEXPECTED("Stale textures should not be found in the texture cache because we hold strong references. "
714 "This must be an unexpected effect of loading resources from multiple threads or a bug.");
715 }
716 else
717 {
718 pTextureCache->Textures.erase(it);
710 // Image width and height (or pixel_type for dds/ktx) are initialized by LoadImageData()
711 // if the texture is found in the cache.
712 if ((gltf_image.width > 0 && gltf_image.height > 0) ||
713 (gltf_image.pixel_type == IMAGE_FILE_FORMAT_DDS || gltf_image.pixel_type == IMAGE_FILE_FORMAT_KTX))
714 {
715 UNEXPECTED("Stale textures should not be found in the texture cache because we hold strong references. "
716 "This must be an unexpected effect of loading resources from multiple threads or a bug.");
717 }
718 else
719 {
720 pTextureCache->Textures.erase(it);
721 }
719722 }
720723 }
721724 }
13761379 gltf_image->bits = FmtAttribs.ComponentSize * 8;
13771380 gltf_image->pixel_type = TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE;
13781381
1379 // Keep strong reference to ensure the allocation is alive.
1382 // Keep strong reference to ensure the allocation is alive (second time, but that's fine).
13801383 pLoaderData->pTextureAllocationsHold->emplace_back(std::move(pAllocation));
13811384
13821385 return true;
14021405 gltf_image->bits = FmtAttribs.ComponentSize * 8;
14031406 gltf_image->pixel_type = TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE;
14041407
1405 // Keep strong reference to ensure the texture is alive.
1408 // Keep strong reference to ensure the texture is alive (second time, but that's fine).
14061409 pLoaderData->pTextureHold->emplace_back(std::move(pTexture));
14071410
14081411 return true;
14151418 }
14161419 }
14171420 }
1421
1422 VERIFY(size != 1, "The texture was previously cached, but was not found in the cache now");
14181423
14191424 ImageLoadInfo LoadInfo;
14201425 LoadInfo.Format = Image::GetFileFormat(image_data, size);
15331538 bool ReadWholeFile(std::vector<unsigned char>* out,
15341539 std::string* err,
15351540 const std::string& filepath,
1536 void*)
1537 {
1538 FileWrapper pFile(filepath.c_str(), EFileAccessMode::Read);
1541 void* user_data)
1542 {
1543 // Try to find the file in the texture cache to avoid reading it
1544 if (auto* pLoaderData = reinterpret_cast<ImageLoaderData*>(user_data))
1545 {
1546 if (pLoaderData->pResourceMgr != nullptr)
1547 {
1548 if (auto pAllocation = pLoaderData->pResourceMgr->FindAllocation(filepath.c_str()))
1549 {
1550 // Keep strong reference to ensure the allocation is alive.
1551 pLoaderData->pTextureAllocationsHold->emplace_back(std::move(pAllocation));
1552 // Tiny GLTF checks the size of 'out', it can't be empty
1553 out->resize(1);
1554 return true;
1555 }
1556 }
1557 else if (pLoaderData->pTextureCache != nullptr)
1558 {
1559 std::lock_guard<std::mutex> Lock{pLoaderData->pTextureCache->TexturesMtx};
1560
1561 auto it = pLoaderData->pTextureCache->Textures.find(filepath.c_str());
1562 if (it != pLoaderData->pTextureCache->Textures.end())
1563 {
1564 if (auto pTexture = it->second.Lock())
1565 {
1566 // Keep strong reference to ensure the texture is alive.
1567 pLoaderData->pTextureHold->emplace_back(std::move(pTexture));
1568 // Tiny GLTF checks the size of 'out', it can't be empty
1569 out->resize(1);
1570 return true;
1571 }
1572 }
1573 }
1574 }
1575
1576 FileWrapper pFile{filepath.c_str(), EFileAccessMode::Read};
15391577 if (!pFile)
15401578 {
15411579 if (err)
16021640 fsCallbacks.FileExists = Callbacks::FileExists;
16031641 fsCallbacks.ReadWholeFile = Callbacks::ReadWholeFile;
16041642 fsCallbacks.WriteWholeFile = tinygltf::WriteWholeFile;
1605 fsCallbacks.user_data = this;
1643 fsCallbacks.user_data = &LoaderData;
16061644 gltf_context.SetFsCallbacks(fsCallbacks);
16071645
16081646 bool binary = false;
6868 {
6969 RefCntAutoPtr<ITextureAtlasSuballocation> pAllocation;
7070
71 std::lock_guard<std::mutex> Lock{m_TexAllocationsMtx};
71 if (CacheId != nullptr && *CacheId != 0)
72 {
73 std::lock_guard<std::mutex> Lock{m_TexAllocationsMtx};
7274
73 auto it = m_TexAllocations.find(CacheId);
74 if (it != m_TexAllocations.end())
75 {
76 pAllocation = it->second.Lock();
77 if (!pAllocation)
78 m_TexAllocations.erase(it);
75 auto it = m_TexAllocations.find(CacheId);
76 if (it != m_TexAllocations.end())
77 {
78 pAllocation = it->second.Lock();
79 if (!pAllocation)
80 m_TexAllocations.erase(it);
81 }
7982 }
8083
8184 return pAllocation;