/* * Copyright 2019-2020 Diligent Graphics LLC * Copyright 2015-2019 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * In no event and under no legal theory, whether in tort (including negligence), * contract, or otherwise, unless required by applicable law (such as deliberate * and grossly negligent acts) or agreed to in writing, shall any Contributor be * liable for any damages, including any direct, indirect, special, incidental, * or consequential damages of any character arising as a result of this License or * out of the use or inability to use the software (including but not limited to damages * for loss of goodwill, work stoppage, computer failure or malfunction, or any and * all other commercial damages or losses), even if such Contributor has been advised * of the possibility of such damages. */ #include "GLTFResourceManager.hpp" #include "DefaultRawMemoryAllocator.hpp" #include "Align.hpp" #include "GraphicsAccessories.hpp" namespace Diligent { namespace GLTF { RefCntAutoPtr ResourceManager::Create(IRenderDevice* pDevice, const CreateInfo& CI) { return RefCntAutoPtr{MakeNewRCObj()(pDevice, CI)}; } ResourceManager::ResourceManager(IReferenceCounters* pRefCounters, IRenderDevice* pDevice, const CreateInfo& CI) : TBase{pRefCounters}, m_DefaultAtlasDesc{CI.DefaultAtlasDesc}, m_DefaultAtlasName{CI.DefaultAtlasDesc.Desc.Name != nullptr ? CI.DefaultAtlasDesc.Desc.Name : "GLTF texture atlas"} { m_DefaultAtlasDesc.Desc.Name = m_DefaultAtlasName.c_str(); m_BufferSuballocators.resize(CI.NumBuffSuballocators); for (Uint32 i = 0; i < CI.NumBuffSuballocators; ++i) { CreateBufferSuballocator(pDevice, CI.BuffSuballocators[i], &m_BufferSuballocators[i]); } m_Atlases.reserve(CI.NumTexAtlases); for (Uint32 i = 0; i < CI.NumTexAtlases; ++i) { RefCntAutoPtr pAtlas; CreateDynamicTextureAtlas(pDevice, CI.TexAtlases[i], &pAtlas); m_Atlases.emplace(CI.TexAtlases[i].Desc.Format, std::move(pAtlas)); } } RefCntAutoPtr ResourceManager::FindAllocation(const char* CacheId) { RefCntAutoPtr pAllocation; if (CacheId != nullptr && *CacheId != 0) { std::lock_guard Lock{m_TexAllocationsMtx}; auto it = m_TexAllocations.find(CacheId); if (it != m_TexAllocations.end()) { pAllocation = it->second.Lock(); if (!pAllocation) m_TexAllocations.erase(it); } } return pAllocation; } RefCntAutoPtr ResourceManager::AllocateTextureSpace( TEXTURE_FORMAT Fmt, Uint32 Width, Uint32 Height, const char* CacheId) { RefCntAutoPtr pAllocation; if (CacheId != nullptr && *CacheId != 0) { pAllocation = FindAllocation(CacheId); } if (!pAllocation) { decltype(m_Atlases)::iterator cache_it; // NB: can't initialize it without locking the mutex { std::lock_guard Lock{m_AtlasesMtx}; cache_it = m_Atlases.find(Fmt); if (cache_it == m_Atlases.end()) { DEV_CHECK_ERR(m_DefaultAtlasDesc.Desc.Width > 0 && m_DefaultAtlasDesc.Desc.Height > 0 && m_DefaultAtlasDesc.Desc.Type != RESOURCE_DIM_UNDEFINED, "Default texture description is not initialized"); auto AtalsCreateInfo = m_DefaultAtlasDesc; AtalsCreateInfo.Desc.Format = Fmt; RefCntAutoPtr pAtlas; CreateDynamicTextureAtlas(nullptr, AtalsCreateInfo, &pAtlas); DEV_CHECK_ERR(pAtlas, "Failed to create new texture atlas"); cache_it = m_Atlases.emplace(Fmt, std::move(pAtlas)).first; } } // Allocate outside of mutex cache_it->second->Allocate(Width, Height, &pAllocation); } if (CacheId != nullptr && *CacheId != 0) { auto inserted = m_TexAllocations.emplace(CacheId, pAllocation).second; VERIFY_EXPR(inserted); } return pAllocation; } } // namespace GLTF } // namespace Diligent