diff options
author | Wieland Hagen <wieland.hagen@kdab.com> | 2016-12-21 21:51:59 +0700 |
---|---|---|
committer | Wieland Hagen <wieland.hagen@kdab.com> | 2017-01-26 09:54:00 +0000 |
commit | b25ff28d9bc30482a3bb95788a68cca124a290dc (patch) | |
tree | b65f1afc2414c1b223655d22a19fcf76408f32ac | |
parent | 40f60c66ab538229f4f64ea8f56682ae33c5926c (diff) |
Fix updating of texture generator
Change-Id: I9cecfb7ec366b51f1a9c99f9d8297b41dda05ead
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r-- | src/render/backend/renderer.cpp | 4 | ||||
-rw-r--r-- | src/render/texture/apitexturemanager_p.h | 15 | ||||
-rw-r--r-- | src/render/texture/gltexture.cpp | 45 | ||||
-rw-r--r-- | src/render/texture/gltexture_p.h | 5 | ||||
-rw-r--r-- | src/render/texture/texture.cpp | 4 | ||||
-rw-r--r-- | src/render/texture/texture_p.h | 3 |
6 files changed, 58 insertions, 18 deletions
diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp index f169261d5..19529887a 100644 --- a/src/render/backend/renderer.cpp +++ b/src/render/backend/renderer.cpp @@ -995,6 +995,10 @@ void Renderer::updateTexture(Texture *texture) !glTextureManager->setImages(glTexture, texture->textureImages())) qWarning() << "[Qt3DRender::TextureNode] updateTexture: TextureImpl.setGenerators failed, should be non-shared"; + if (dirtyFlags.testFlag(Texture::DirtyDataGenerator) && + !glTextureManager->setGenerator(glTexture, texture->dataGenerator())) + qWarning() << "[Qt3DRender::TextureNode] updateTexture: TextureImpl.setGenerator failed, should be non-shared"; + // Unset the dirty flag on the texture texture->unsetDirty(); } diff --git a/src/render/texture/apitexturemanager_p.h b/src/render/texture/apitexturemanager_p.h index 2fd340e7e..c062f0971 100644 --- a/src/render/texture/apitexturemanager_p.h +++ b/src/render/texture/apitexturemanager_p.h @@ -237,6 +237,21 @@ public: 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; + } + // Retrieves abandoned textures. This should be regularly called from the OpenGL thread // to make sure needed GL resources are de-allocated. QVector<APITexture*> takeAbandonedTextures() diff --git a/src/render/texture/gltexture.cpp b/src/render/texture/gltexture.cpp index 0fc37891d..98af9b6f4 100644 --- a/src/render/texture/gltexture.cpp +++ b/src/render/texture/gltexture.cpp @@ -120,7 +120,7 @@ QOpenGLTexture* GLTexture::getOrCreateGLTexture() if (m_properties.target != QAbstractTexture::TargetAutomatic) qWarning() << "[Qt3DRender::GLTexture] When a texture provides a generator, it's target is expected to be TargetAutomatic"; - m_properties.target = m_textureData->target(); + m_actualTarget = m_textureData->target(); m_properties.width = m_textureData->width(); m_properties.height = m_textureData->height(); m_properties.depth = m_textureData->depth(); @@ -224,6 +224,7 @@ void GLTexture::setProperties(const TextureProperties &props) if (m_properties != props) { m_properties = props; QMutexLocker locker(&m_dirtyFlagMutex); + m_actualTarget = props.target; m_dirty |= Properties; } } @@ -278,6 +279,22 @@ void GLTexture::setImages(const QVector<Image> &images) } } +void GLTexture::setGenerator(const QTextureGeneratorPtr &generator) +{ + if (m_dataFunctor != generator) { + if (m_dataFunctor) + m_textureDataManager->releaseData(m_dataFunctor, this); + + m_textureData.reset(); + m_dataFunctor = generator; + + if (m_dataFunctor) { + m_textureDataManager->requestData(m_dataFunctor, this); + requestUpload(); + } + } +} + QOpenGLTexture *GLTexture::buildGLTexture() { QOpenGLContext *ctx = QOpenGLContext::currentContext(); @@ -286,12 +303,12 @@ QOpenGLTexture *GLTexture::buildGLTexture() return nullptr; } - if (m_properties.target == QAbstractTexture::TargetAutomatic) { + if (m_actualTarget == QAbstractTexture::TargetAutomatic) { qWarning() << Q_FUNC_INFO << "something went wrong, target shouldn't be automatic at this point"; return nullptr; } - QOpenGLTexture* glTex = new QOpenGLTexture(static_cast<QOpenGLTexture::Target>(m_properties.target)); + QOpenGLTexture* glTex = new QOpenGLTexture(static_cast<QOpenGLTexture::Target>(m_actualTarget)); // m_format may not be ES2 compatible. Now it's time to convert it, if necessary. QAbstractTexture::TextureFormat format = m_properties.format; @@ -329,16 +346,16 @@ QOpenGLTexture *GLTexture::buildGLTexture() static_cast<QOpenGLTexture::TextureFormat>(format)); glTex->setSize(m_properties.width, m_properties.height, m_properties.depth); // Set layers count if texture array - if (m_properties.target == QAbstractTexture::Target1DArray || - m_properties.target == QAbstractTexture::Target2DArray || - m_properties.target == QAbstractTexture::Target3D || - m_properties.target == QAbstractTexture::Target2DMultisampleArray || - m_properties.target == QAbstractTexture::TargetCubeMapArray) { + if (m_actualTarget == QAbstractTexture::Target1DArray || + m_actualTarget == QAbstractTexture::Target2DArray || + m_actualTarget == QAbstractTexture::Target3D || + m_actualTarget == QAbstractTexture::Target2DMultisampleArray || + m_actualTarget == QAbstractTexture::TargetCubeMapArray) { glTex->setLayers(m_properties.layers); } - if (m_properties.target == QAbstractTexture::Target2DMultisample || - m_properties.target == QAbstractTexture::Target2DMultisampleArray) { + if (m_actualTarget == QAbstractTexture::Target2DMultisample || + m_actualTarget == QAbstractTexture::Target2DMultisampleArray) { // Set samples count if multisampled texture // (multisampled textures don't have mipmaps) glTex->setSamples(m_properties.samples); @@ -410,11 +427,11 @@ void GLTexture::uploadGLTextureData() void GLTexture::updateGLTextureParameters() { m_gl->setWrapMode(QOpenGLTexture::DirectionS, static_cast<QOpenGLTexture::WrapMode>(m_parameters.wrapModeX)); - if (m_properties.target != QAbstractTexture::Target1D && - m_properties.target != QAbstractTexture::Target1DArray && - m_properties.target != QAbstractTexture::TargetBuffer) + if (m_actualTarget != QAbstractTexture::Target1D && + m_actualTarget != QAbstractTexture::Target1DArray && + m_actualTarget != QAbstractTexture::TargetBuffer) m_gl->setWrapMode(QOpenGLTexture::DirectionT, static_cast<QOpenGLTexture::WrapMode>(m_parameters.wrapModeY)); - if (m_properties.target == QAbstractTexture::Target3D) + if (m_actualTarget == QAbstractTexture::Target3D) m_gl->setWrapMode(QOpenGLTexture::DirectionR, static_cast<QOpenGLTexture::WrapMode>(m_parameters.wrapModeZ)); m_gl->setMinMagFilters(static_cast<QOpenGLTexture::Filter>(m_parameters.minificationFilter), static_cast<QOpenGLTexture::Filter>(m_parameters.magnificationFilter)); diff --git a/src/render/texture/gltexture_p.h b/src/render/texture/gltexture_p.h index 424e77854..558a22f84 100644 --- a/src/render/texture/gltexture_p.h +++ b/src/render/texture/gltexture_p.h @@ -164,11 +164,12 @@ protected: void setParameters(const TextureParameters ¶ms); void setProperties(const TextureProperties &props); void setImages(const QVector<Image> &images); + void setGenerator(const QTextureGeneratorPtr &generator); private: enum DirtyFlag { - TextureData = 0x01, // one or more generators have been executed, data needs uploading to GPU + TextureData = 0x01, // one or more image generators have been executed, data needs uploading to GPU Properties = 0x02, // texture needs to be (re-)created Parameters = 0x04 // texture parameters need to be (re-)set @@ -188,6 +189,8 @@ private: TextureDataManager *m_textureDataManager; TextureImageDataManager *m_textureImageDataManager; + // target which is actually used for GL texture + QAbstractTexture::Target m_actualTarget; TextureProperties m_properties; TextureParameters m_parameters; diff --git a/src/render/texture/texture.cpp b/src/render/texture/texture.cpp index 863733523..b793462ca 100644 --- a/src/render/texture/texture.cpp +++ b/src/render/texture/texture.cpp @@ -61,7 +61,7 @@ namespace Render { Texture::Texture() // We need backend -> frontend notifications to update the status of the texture : BackendNode(ReadWrite) - , m_dirty(DirtyGenerators|DirtyProperties|DirtyParameters) + , m_dirty(DirtyGenerators|DirtyProperties|DirtyParameters|DirtyDataGenerator) , m_textureImageManager(nullptr) { } @@ -214,7 +214,7 @@ void Texture::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) dirty = DirtyProperties; } else if (propertyChange->propertyName() == QByteArrayLiteral("generator")) { m_dataFunctor = propertyChange->value().value<QTextureGeneratorPtr>(); - dirty = DirtyGenerators; + dirty = DirtyDataGenerator; } } break; diff --git a/src/render/texture/texture_p.h b/src/render/texture/texture_p.h index 8f5300552..1ce73b0fe 100644 --- a/src/render/texture/texture_p.h +++ b/src/render/texture/texture_p.h @@ -135,7 +135,8 @@ public: NotDirty = 0, DirtyProperties = 0x1, DirtyParameters = 0x2, - DirtyGenerators = 0x4 + DirtyGenerators = 0x4, + DirtyDataGenerator = 0x8 }; Q_DECLARE_FLAGS(DirtyFlags, DirtyFlag) |