diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2016-08-05 12:51:56 +0200 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2016-11-14 13:55:58 +0000 |
commit | b2b31d4ee04e92cb41cb8249bb5f440fb321be0c (patch) | |
tree | 0cee751bd009f8d90c08734fffd451e51da1b699 /src/render/backend/renderer.cpp | |
parent | 338af9c0ff9f3fa3c0d5965b07fe6b7dcec2a93d (diff) |
Texture: further refactoring
Remove deep coupling between Texture and GLTexture
The renderer is the only link between the two which should
allow to reuse Texture with various renderers.
Change-Id: I01e0a119744b9ec589c7b45d2ff482a70ea53d3b
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src/render/backend/renderer.cpp')
-rw-r--r-- | src/render/backend/renderer.cpp | 75 |
1 files changed, 73 insertions, 2 deletions
diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp index e0ab213bd..0f9562493 100644 --- a/src/render/backend/renderer.cpp +++ b/src/render/backend/renderer.cpp @@ -326,6 +326,12 @@ void Renderer::shutdown() void Renderer::releaseGraphicsResources() { // Clean up the graphics context and any resources + const QVector<GLTexture*> activeTextures = m_nodesManager->glTextureManager()->activeResources(); + for (GLTexture *tex : activeTextures) + tex->destroyGLTexture(); + + // TO DO: Do the same thing with buffers + m_graphicsContext.reset(nullptr); qCDebug(Backend) << Q_FUNC_INFO << "Renderer properly shutdown"; } @@ -732,7 +738,9 @@ void Renderer::lookForDirtyTextures() const QVector<HTexture> activeTextureHandles = m_nodesManager->textureManager()->activeHandles(); for (HTexture handle: activeTextureHandles) { Texture *texture = m_nodesManager->textureManager()->data(handle); - if (texture->texture() == nullptr) + // Dirty meaning that something has changed on the texture + // either properties, parameters, generator or a texture image + if (texture->dirtyFlags() != Texture::NotDirty) m_dirtyTextures.push_back(handle); } } @@ -784,10 +792,73 @@ void Renderer::updateGLResources() for (HTexture handle: activeTextureHandles) { Texture *texture = m_nodesManager->textureManager()->data(handle); // Upload/Update texture - texture->texture()->getOrCreateGLTexture(); + updateTexture(texture); } } +void Renderer::updateTexture(Texture *texture) +{ + // TODO: for implementing unique, non-shared, non-cached textures. + // for now, every texture is shared by default + const bool isUnique = false; + + // Try to find the associated GLTexture for the backend Texture + GLTextureManager *glTextureManager = m_nodesManager->glTextureManager(); + GLTexture *glTexture = glTextureManager->lookupResource(texture->peerId()); + + // No GLTexture associated yet -> create it + if (glTexture == nullptr) { + if (isUnique) + glTextureManager->createUnique(texture); + else + glTextureManager->getOrCreateShared(texture); + texture->unsetDirty(); + return; + } + + // if this texture is a shared texture, we might need to look for a new TextureImpl + // and abandon the old one + if (glTextureManager->isShared(glTexture)) { + glTextureManager->abandon(glTexture, texture); + glTextureManager->getOrCreateShared(texture); + texture->unsetDirty(); + return; + } + + // this texture node is the only one referring to the GLTexture. + // we could thus directly modify the texture. Instead, for non-unique textures, + // we first see if there is already a matching texture present. + if (!isUnique) { + GLTexture *newSharedTex = glTextureManager->findMatchingShared(texture); + if (newSharedTex && newSharedTex != glTexture) { + glTextureManager->abandon(glTexture, texture); + glTextureManager->adoptShared(newSharedTex, texture); + texture->unsetDirty(); + return; + } + } + + // we hold a reference to a unique or exclusive access to a shared texture + // we can thus modify the texture directly. + const Texture::DirtyFlags dirtyFlags = texture->dirtyFlags(); + + if (dirtyFlags.testFlag(Texture::DirtyProperties) && + !glTextureManager->setProperties(glTexture, texture->properties())) + qWarning() << "[Qt3DRender::TextureNode] updateTexture: TextureImpl.setProperties failed, should be non-shared"; + + if (dirtyFlags.testFlag(Texture::DirtyParameters) && + !glTextureManager->setParameters(glTexture, texture->parameters())) + qWarning() << "[Qt3DRender::TextureNode] updateTexture: TextureImpl.setParameters failed, should be non-shared"; + + if (dirtyFlags.testFlag(Texture::DirtyGenerators) && + !glTextureManager->setImages(glTexture, texture->textureImages())) + qWarning() << "[Qt3DRender::TextureNode] updateTexture: TextureImpl.setGenerators failed, should be non-shared"; + + // Unset the dirty flag on the texture + texture->unsetDirty(); +} + + // Happens in RenderThread context when all RenderViewJobs are done // Returns the id of the last bound FBO Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Render::RenderView *> &renderViews) |