diff options
Diffstat (limited to 'src/render/texture/apitexturemanager_p.h')
-rw-r--r-- | src/render/texture/apitexturemanager_p.h | 411 |
1 files changed, 0 insertions, 411 deletions
diff --git a/src/render/texture/apitexturemanager_p.h b/src/render/texture/apitexturemanager_p.h deleted file mode 100644 index 79dc9af94..000000000 --- a/src/render/texture/apitexturemanager_p.h +++ /dev/null @@ -1,411 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_APITEXTUREMANAGER_P_H -#define QT3DRENDER_RENDER_APITEXTUREMANAGER_P_H - -#include <Qt3DRender/private/managers_p.h> -#include <Qt3DRender/private/texturedatamanager_p.h> -#include <Qt3DRender/private/textureimage_p.h> -#include <Qt3DRender/private/texture_p.h> -#include <Qt3DRender/qtexturegenerator.h> -#include <Qt3DRender/qtextureimagedatagenerator.h> - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -// Manages instances of APITexture. This includes sharing between multiple -// Texture nodes, updating APITextures and deleting abandoned instances. -template <class APITexture, class APITextureImage> -class APITextureManager -{ -public: - - explicit APITextureManager(TextureImageManager *textureImageManager, - TextureDataManager *textureDataManager, - TextureImageDataManager *textureImageDataManager) - : m_textureImageManager(textureImageManager) - , m_textureDataManager(textureDataManager) - , m_textureImageDataManager(textureImageDataManager) - { - } - - ~APITextureManager() - { - qDeleteAll(activeResources()); - m_nodeIdToGLTexture.clear(); - m_sharedTextures.clear(); - m_updatedTextures.clear(); - } - - // Used to retrieve all resources that needs to be destroyed on the GPU - QVector<APITexture *> activeResources() const - { - // Active Resources are - // all shared textures - // all unique textures - // all textures that haven't yet been destroyed - // Note: updatedTextures only referenced textures in one of these 3 vectors - return m_sharedTextures.keys().toVector() + m_uniqueTextures + m_abandonedTextures; - } - - APITexture *lookupResource(Qt3DCore::QNodeId textureId) const - { - return m_nodeIdToGLTexture.value(textureId); - } - - Qt3DCore::QNodeIdVector referencedTextureIds(APITexture *apiTexture) const - { - return m_sharedTextures.value(apiTexture); - } - - // Returns a APITexture that matches the given QTexture node. Will make sure - // that texture data generator jobs are launched, if necessary. The APITexture - // may be shared between multiple texture backend nodes - APITexture *getOrCreateShared(const Texture *node) - { - Q_ASSERT(node); - - APITexture *shared = findMatchingShared(node); - - // no matching shared texture was found; create a new one: - if (shared == nullptr) - shared = createTexture(node, false); - - // store texture node to shared texture relationship - adoptShared(shared, node); - - return shared; - } - - // Store that the shared texture references node - void adoptShared(APITexture *sharedApiTexture, const Texture *node) - { - if (!m_sharedTextures[sharedApiTexture].contains(node->peerId())) { - m_sharedTextures[sharedApiTexture].push_back(node->peerId()); - m_nodeIdToGLTexture.insert(node->peerId(), sharedApiTexture); - } - } - - // If there is already a shared texture with the properties of the given - // texture node, return this instance, else NULL. - // Note: the reference to the texture node is added if the shared texture - // wasn't referencing it already - APITexture *findMatchingShared(const Texture *node) - { - Q_ASSERT(node); - - // search for existing texture - const auto end = m_sharedTextures.end(); - for (auto it = m_sharedTextures.begin(); it != end; ++it) - if (isSameTexture(it.key(), node)) - return it.key(); - return nullptr; - } - - // Returns a APITexture that matches the given QTexture node. Will make sure - // that texture data generator jobs are launched, if necessary. - APITexture *createUnique(const Texture *node) - { - Q_ASSERT(node); - APITexture *uniqueTex = createTexture(node, true); - m_uniqueTextures.push_back(uniqueTex); - m_nodeIdToGLTexture.insert(node->peerId(), uniqueTex); - return uniqueTex; - } - - // De-associate the given APITexture from the backend node. If the texture - // is no longer referenced by any other node, it will be deleted. - void abandon(APITexture *tex, const Qt3DCore::QNodeId nodeId) - { - APITexture *apiTexture = m_nodeIdToGLTexture.take(nodeId); - Q_ASSERT(tex == apiTexture); - - if (Q_UNLIKELY(!apiTexture)) { - qWarning() << "[Qt3DRender::TextureManager] abandon: could not find Texture"; - return; - } - - if (tex->isUnique()) { - m_uniqueTextures.removeAll(apiTexture); - m_abandonedTextures.push_back(apiTexture); - } else { - QVector<Qt3DCore::QNodeId> &referencedTextureNodes = m_sharedTextures[apiTexture]; - referencedTextureNodes.removeAll(nodeId); - - // If no texture nodes is referencing the shared APITexture, remove it - if (referencedTextureNodes.empty()) { - m_abandonedTextures.push_back(apiTexture); - m_sharedTextures.remove(apiTexture); - tex->destroyResources(); - } - } - } - - // Change the properties of the given texture, if it is a non-shared texture - // Returns true, if it was changed successfully, false otherwise - bool setProperties(APITexture *tex, const TextureProperties &props) - { - Q_ASSERT(tex); - - if (isShared(tex)) - return false; - - tex->setProperties(props); - m_updatedTextures.push_back(tex); - - return true; - } - - // Change the parameters of the given texture, if it is a non-shared texture - // Returns true, if it was changed successfully, false otherwise - bool setParameters(APITexture *tex, const TextureParameters ¶ms) - { - Q_ASSERT(tex); - - if (isShared(tex)) - return false; - - tex->setParameters(params); - m_updatedTextures.push_back(tex); - - return true; - } - - // Change the texture images of the given texture, if it is a non-shared texture - // Return true, if it was changed successfully, false otherwise - bool setImages(APITexture *tex, const Qt3DCore::QNodeIdVector &imageIds) - { - Q_ASSERT(tex); - - if (isShared(tex)) - return false; - - // create Image structs - QVector<APITextureImage> texImgs = texImgsFromNodes(imageIds); - if (texImgs.size() != imageIds.size()) - return false; - - tex->setImages(texImgs); - m_updatedTextures.push_back(tex); - - return true; - } - - // Change the texture data generator for given texture, if it is a non-shared texture - // Return true, if it was changed successfully, false otherwise - bool setGenerator(APITexture *tex, const QTextureGeneratorPtr &generator) - { - Q_ASSERT(tex); - - if (isShared(tex)) - return false; - - tex->setGenerator(generator); - m_updatedTextures.push_back(tex); - - return true; - } - - // Change the texture's referenced texture Id from a shared context - bool setSharedTextureId(APITexture *tex, int textureId) - { - Q_ASSERT(tex); - - if (isShared(tex)) - return false; - - tex->setSharedTextureId(textureId); - m_updatedTextures.push_back(tex); - return true; - } - - // Retrieves abandoned textures. This should be regularly called from the OpenGL thread - // to make sure needed GL resources are de-allocated. - QVector<APITexture*> takeAbandonedTextures() - { - return std::move(m_abandonedTextures); - } - - // Retrieves textures that have been modified - QVector<APITexture*> takeUpdatedTextures() - { - return std::move(m_updatedTextures); - } - - // Returns whether the given APITexture is shared between multiple TextureNodes - bool isShared(APITexture *impl) - { - Q_ASSERT(impl); - - if (impl->isUnique()) - return false; - - auto it = m_sharedTextures.constFind(impl); - if (it == m_sharedTextures.cend()) - return false; - - return it.value().size() > 1; - } - -private: - - // Check if the given APITexture matches the TextureNode - bool isSameTexture(const APITexture *tex, const Texture *texNode) - { - // make sure there either are no texture generators, or the two are the same - if (tex->textureGenerator().isNull() != texNode->dataGenerator().isNull()) - return false; - if (!tex->textureGenerator().isNull() && !(*tex->textureGenerator() == *texNode->dataGenerator())) - return false; - - // make sure the image generators are the same - const QVector<APITextureImage> texImgGens = tex->images(); - const Qt3DCore::QNodeIdVector texImgs = texNode->textureImageIds(); - if (texImgGens.size() != texImgs.size()) - return false; - for (int i = 0; i < texImgGens.size(); ++i) { - const TextureImage *img = m_textureImageManager->lookupResource(texImgs[i]); - Q_ASSERT(img != nullptr); - if (!(*img->dataGenerator() == *texImgGens[i].generator) - || img->layer() != texImgGens[i].layer - || img->face() != texImgGens[i].face - || img->mipLevel() != texImgGens[i].mipLevel) - return false; - } - - // if the texture has a texture generator, this generator will mostly determine - // the properties of the texture. - if (!tex->textureGenerator().isNull()) - return (tex->properties().generateMipMaps == texNode->properties().generateMipMaps - && tex->parameters() == texNode->parameters()); - - // if it doesn't have a texture generator, but texture image generators, - // few more properties will influence the texture type - if (!texImgGens.empty()) - return (tex->properties().target == texNode->properties().target - && tex->properties().format == texNode->properties().format - && tex->properties().generateMipMaps == texNode->properties().generateMipMaps - && tex->parameters() == texNode->parameters()); - - // texture without images - return tex->properties() == texNode->properties() - && tex->parameters() == texNode->parameters(); - } - - // Create APITexture from given TextureNode. Also make sure the generators - // will be executed by jobs soon. - APITexture *createTexture(const Texture *node, bool unique) - { - // create Image structs - const QVector<APITextureImage> texImgs = texImgsFromNodes(node->textureImageIds()); - if (texImgs.empty() && !node->textureImageIds().empty()) - return nullptr; - - // no matching shared texture was found, create a new one - APITexture *newTex = new APITexture(m_textureDataManager, m_textureImageDataManager, node->dataGenerator(), unique); - newTex->setProperties(node->properties()); - newTex->setParameters(node->parameters()); - newTex->setImages(texImgs); - newTex->setSharedTextureId(node->sharedTextureId()); - - m_updatedTextures.push_back(newTex); - - return newTex; - } - - QVector<APITextureImage> texImgsFromNodes(const Qt3DCore::QNodeIdVector &imageIds) const - { - QVector<APITextureImage> ret; - ret.resize(imageIds.size()); - - for (int i = 0; i < imageIds.size(); ++i) { - const TextureImage *img = m_textureImageManager->lookupResource(imageIds[i]); - if (!img) { - qWarning() << "[Qt3DRender::TextureManager] invalid TextureImage handle"; - return QVector<APITextureImage>(); - } - - ret[i].generator = img->dataGenerator(); - ret[i].face = img->face(); - ret[i].layer = img->layer(); - ret[i].mipLevel = img->mipLevel(); - } - - return ret; - } - - TextureImageManager *m_textureImageManager; - TextureDataManager *m_textureDataManager; - TextureImageDataManager *m_textureImageDataManager; - - /* each non-unique texture is associated with a number of Texture nodes referencing it */ - QHash<APITexture*, QVector<Qt3DCore::QNodeId>> m_sharedTextures; - - // Texture id -> APITexture (both shared and unique ones) - QHash<Qt3DCore::QNodeId, APITexture *> m_nodeIdToGLTexture; - - QVector<APITexture*> m_uniqueTextures; - QVector<APITexture*> m_abandonedTextures; - QVector<APITexture*> m_updatedTextures; -}; - - -} // Render - -} // Qt3DRender - -QT_END_NAMESPACE - - -#endif // QT3DRENDER_RENDER_APITEXTUREMANAGER_P_H |