summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWieland Hagen <wieland.hagen@kdab.com>2016-12-21 21:51:59 +0700
committerWieland Hagen <wieland.hagen@kdab.com>2017-01-26 09:54:00 +0000
commitb25ff28d9bc30482a3bb95788a68cca124a290dc (patch)
treeb65f1afc2414c1b223655d22a19fcf76408f32ac
parent40f60c66ab538229f4f64ea8f56682ae33c5926c (diff)
Fix updating of texture generator
Change-Id: I9cecfb7ec366b51f1a9c99f9d8297b41dda05ead Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--src/render/backend/renderer.cpp4
-rw-r--r--src/render/texture/apitexturemanager_p.h15
-rw-r--r--src/render/texture/gltexture.cpp45
-rw-r--r--src/render/texture/gltexture_p.h5
-rw-r--r--src/render/texture/texture.cpp4
-rw-r--r--src/render/texture/texture_p.h3
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 &params);
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)