| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| struct TexturesContainer { |
| MeshTexturizer |
| m_texturizer; |
| tcg::list<QString> m_keys; |
| |
| public: |
| TexturesContainer() {} |
| |
| private: |
| TexturesContainer(const TexturesContainer &); |
| TexturesContainer &operator=(const TexturesContainer &); |
| }; |
| |
| |
| |
| |
| |
| namespace { |
| |
| QMutex l_mutex(QMutex::Recursive); |
| |
| |
| std::map<int, TexturesContainer *> |
| l_texturesContainers; |
| QCache<QString, DrawableTextureDataP> l_objects(500 * 1024); |
| |
| |
| |
| |
| |
| |
| } |
| |
| |
| |
| |
| |
| namespace { |
| |
| inline QString textureString(int dlSpaceId, const std::string &texId) { |
| return QString::number(dlSpaceId) + "_" + QString::fromStdString(texId); |
| } |
| |
| |
| |
| inline void deleteTexturesContainer( |
| const std::pair<int, TexturesContainer *> &pair) { |
| delete pair.second; |
| } |
| } |
| |
| |
| |
| |
| |
| DrawableTextureData::~DrawableTextureData() { |
| QMutexLocker locker(&l_mutex); |
| |
| TexturesContainer *texContainer = l_texturesContainers[m_dlSpaceId]; |
| |
| if (m_dlSpaceId >= 0) { |
| |
| |
| TGLDisplayListsProxy *proxy = |
| TGLDisplayListsManager::instance()->dlProxy(m_dlSpaceId); |
| |
| TGlContext currentContext = tglGetCurrentContext(); |
| |
| |
| { |
| QMutexLocker locker(proxy->mutex()); |
| |
| proxy->makeCurrent(); |
| texContainer->m_texturizer.unbindTexture(m_texId); |
| } |
| |
| |
| |
| tglMakeCurrent(currentContext); |
| } else |
| |
| texContainer->m_texturizer.unbindTexture(m_texId); |
| |
| texContainer->m_keys.erase(m_objIdx); |
| } |
| |
| |
| |
| |
| |
| TTexturesStorage::TTexturesStorage() { |
| |
| TGLDisplayListsManager::instance()->addObserver(this); |
| } |
| |
| |
| |
| TTexturesStorage::~TTexturesStorage() { |
| l_objects.clear(); |
| std::for_each(l_texturesContainers.begin(), l_texturesContainers.end(), |
| deleteTexturesContainer); |
| } |
| |
| |
| |
| TTexturesStorage *TTexturesStorage::instance() { |
| static TTexturesStorage theInstance; |
| return &theInstance; |
| } |
| |
| |
| |
| DrawableTextureDataP TTexturesStorage::loadTexture(const std::string &textureId, |
| const TRaster32P &ras, |
| const TRectD &geometry) { |
| |
| TGlContext currentContext = tglGetCurrentContext(); |
| int dlSpaceId = |
| TGLDisplayListsManager::instance()->displayListsSpaceId(currentContext); |
| |
| QString texString(::textureString(dlSpaceId, textureId)); |
| |
| |
| QMutexLocker locker(&l_mutex); |
| |
| |
| std::map<int, TexturesContainer *>::iterator it = |
| l_texturesContainers.find(dlSpaceId); |
| if (it == l_texturesContainers.end()) |
| it = l_texturesContainers |
| .insert(std::make_pair(dlSpaceId, new TexturesContainer)) |
| .first; |
| |
| MeshTexturizer &texturizer = it->second->m_texturizer; |
| |
| DrawableTextureDataP dataPtr = std::make_shared<DrawableTextureData>(); |
| DrawableTextureData *data = dataPtr.get(); |
| |
| data->m_dlSpaceId = dlSpaceId; |
| data->m_texId = texturizer.bindTexture(ras, geometry); |
| data->m_objIdx = it->second->m_keys.push_back(texString); |
| data->m_textureData = texturizer.getTextureData(data->m_texId); |
| |
| l_objects.insert(texString, new DrawableTextureDataP(dataPtr), |
| (ras->getLx() * ras->getLy() * ras->getPixelSize()) >> 10); |
| |
| if (dlSpaceId < 0) { |
| |
| |
| |
| l_objects.remove(texString); |
| } |
| |
| return dataPtr; |
| } |
| |
| |
| |
| void TTexturesStorage::unloadTexture(const std::string &textureId) { |
| QMutexLocker locker(&l_mutex); |
| |
| |
| std::map<int, TexturesContainer *>::iterator it, |
| iEnd(l_texturesContainers.end()); |
| for (it = l_texturesContainers.begin(); it != iEnd; ++it) |
| l_objects.remove(::textureString(it->first, textureId)); |
| } |
| |
| |
| |
| void TTexturesStorage::onDisplayListDestroyed(int dlSpaceId) { |
| QMutexLocker locker(&l_mutex); |
| |
| |
| std::map<int, TexturesContainer *>::iterator it = |
| l_texturesContainers.find(dlSpaceId); |
| if (it == l_texturesContainers.end()) return; |
| |
| tcg::list<QString>::iterator st, sEnd(it->second->m_keys.end()); |
| |
| for (st = it->second->m_keys.begin(); st != sEnd;) |
| |
| |
| l_objects.remove(*st++); |
| |
| |
| delete it->second; |
| l_texturesContainers.erase(it); |
| } |
| |
| |
| |
| DrawableTextureDataP TTexturesStorage::getTextureData( |
| const std::string &textureId) { |
| |
| TGlContext currentContext = tglGetCurrentContext(); |
| int dlSpaceId = |
| TGLDisplayListsManager::instance()->displayListsSpaceId(currentContext); |
| |
| |
| |
| if (dlSpaceId < 0) return DrawableTextureDataP(); |
| |
| QMutexLocker locker(&l_mutex); |
| |
| |
| QString texString(::textureString(dlSpaceId, textureId)); |
| if (!l_objects.contains(texString)) return DrawableTextureDataP(); |
| |
| return *l_objects.object(texString); |
| } |