aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph/util
diff options
context:
space:
mode:
authorMorten Johan Sørvig <morten.sorvig@qt.io>2018-03-08 18:35:03 +0100
committerMorten Johan Sørvig <morten.sorvig@qt.io>2018-03-08 18:35:03 +0100
commitd9ea4917ca97aeee050a86151fbfa069771b498d (patch)
tree21fd6960d8a866bf6f5a5a8f9db9be801f8065c1 /src/quick/scenegraph/util
parentf9beafddd256cd0b79bf2478a812053ef61241fc (diff)
parentc6a26c248e8abc421b87c3dd6b2466d490ea902e (diff)
Merge remote-tracking branch 'gerrit/5.11' into wip/webassembly
Diffstat (limited to 'src/quick/scenegraph/util')
-rw-r--r--src/quick/scenegraph/util/qsgareaallocator.cpp18
-rw-r--r--src/quick/scenegraph/util/qsgareaallocator_p.h2
-rw-r--r--src/quick/scenegraph/util/qsgatlastexture.cpp336
-rw-r--r--src/quick/scenegraph/util/qsgatlastexture_p.h88
-rw-r--r--src/quick/scenegraph/util/qsgdefaultpainternode.cpp14
-rw-r--r--src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp6
-rw-r--r--src/quick/scenegraph/util/qsgengine.cpp6
-rw-r--r--src/quick/scenegraph/util/qsgengine.h2
-rw-r--r--src/quick/scenegraph/util/qsgflatcolormaterial.cpp6
-rw-r--r--src/quick/scenegraph/util/qsgimagenode.cpp11
-rw-r--r--src/quick/scenegraph/util/qsgimagenode.h2
-rw-r--r--src/quick/scenegraph/util/qsgninepatchnode.h2
-rw-r--r--src/quick/scenegraph/util/qsgrectanglenode.h2
-rw-r--r--src/quick/scenegraph/util/qsgshadersourcebuilder.cpp10
-rw-r--r--src/quick/scenegraph/util/qsgsimplematerial.cpp16
-rw-r--r--src/quick/scenegraph/util/qsgsimplematerial.h6
-rw-r--r--src/quick/scenegraph/util/qsgsimpletexturenode.cpp3
-rw-r--r--src/quick/scenegraph/util/qsgsimpletexturenode.h2
-rw-r--r--src/quick/scenegraph/util/qsgtexture.cpp4
-rw-r--r--src/quick/scenegraph/util/qsgtexture.h2
-rw-r--r--src/quick/scenegraph/util/qsgtexture_p.h2
-rw-r--r--src/quick/scenegraph/util/qsgtexturematerial.cpp21
-rw-r--r--src/quick/scenegraph/util/qsgtexturereader.cpp61
-rw-r--r--src/quick/scenegraph/util/qsgtexturereader_p.h21
-rw-r--r--src/quick/scenegraph/util/qsgvertexcolormaterial.cpp3
25 files changed, 407 insertions, 239 deletions
diff --git a/src/quick/scenegraph/util/qsgareaallocator.cpp b/src/quick/scenegraph/util/qsgareaallocator.cpp
index 67a9fa285a..cd270a1d63 100644
--- a/src/quick/scenegraph/util/qsgareaallocator.cpp
+++ b/src/quick/scenegraph/util/qsgareaallocator.cpp
@@ -72,8 +72,8 @@ struct QSGAreaAllocatorNode
QSGAreaAllocatorNode::QSGAreaAllocatorNode(QSGAreaAllocatorNode *parent)
: parent(parent)
- , left(0)
- , right(0)
+ , left(nullptr)
+ , right(nullptr)
, isOccupied(false)
{
}
@@ -86,14 +86,14 @@ QSGAreaAllocatorNode::~QSGAreaAllocatorNode()
bool QSGAreaAllocatorNode::isLeaf()
{
- Q_ASSERT((left != 0) == (right != 0));
+ Q_ASSERT((left != nullptr) == (right != nullptr));
return !left;
}
QSGAreaAllocator::QSGAreaAllocator(const QSize &size) : m_size(size)
{
- m_root = new QSGAreaAllocatorNode(0);
+ m_root = new QSGAreaAllocatorNode(nullptr);
}
QSGAreaAllocator::~QSGAreaAllocator()
@@ -179,13 +179,13 @@ bool QSGAreaAllocator::deallocateInNode(const QPoint &pos, QSGAreaAllocatorNode
void QSGAreaAllocator::mergeNodeWithNeighbors(QSGAreaAllocatorNode *node)
{
bool done = false;
- QSGAreaAllocatorNode *parent = 0;
- QSGAreaAllocatorNode *current = 0;
+ QSGAreaAllocatorNode *parent = nullptr;
+ QSGAreaAllocatorNode *current = nullptr;
QSGAreaAllocatorNode *sibling;
while (!done) {
Q_ASSERT(node->isLeaf());
Q_ASSERT(!node->isOccupied);
- if (node->parent == 0)
+ if (node->parent == nullptr)
return; // No neighbours.
SplitType splitType = SplitType(node->parent->splitType);
@@ -238,7 +238,7 @@ void QSGAreaAllocator::mergeNodeWithNeighbors(QSGAreaAllocatorNode *node)
}
sibling->parent = parent->parent;
*nodeRef = sibling;
- parent->left = parent->right = 0;
+ parent->left = parent->right = nullptr;
delete parent;
delete neighbor;
done = false;
@@ -276,7 +276,7 @@ void QSGAreaAllocator::mergeNodeWithNeighbors(QSGAreaAllocatorNode *node)
}
sibling->parent = parent->parent;
*nodeRef = sibling;
- parent->left = parent->right = 0;
+ parent->left = parent->right = nullptr;
delete parent;
delete neighbor;
done = false;
diff --git a/src/quick/scenegraph/util/qsgareaallocator_p.h b/src/quick/scenegraph/util/qsgareaallocator_p.h
index aa40ff0a6e..8bc05a5a5b 100644
--- a/src/quick/scenegraph/util/qsgareaallocator_p.h
+++ b/src/quick/scenegraph/util/qsgareaallocator_p.h
@@ -67,7 +67,7 @@ public:
QRect allocate(const QSize &size);
bool deallocate(const QRect &rect);
- bool isEmpty() const { return m_root == 0; }
+ bool isEmpty() const { return m_root == nullptr; }
QSize size() const { return m_size; }
private:
bool allocateInNode(const QSize &size, QPoint &result, const QRect &currentRect, QSGAreaAllocatorNode *node);
diff --git a/src/quick/scenegraph/util/qsgatlastexture.cpp b/src/quick/scenegraph/util/qsgatlastexture.cpp
index 22f0b13f46..7608a81ddc 100644
--- a/src/quick/scenegraph/util/qsgatlastexture.cpp
+++ b/src/quick/scenegraph/util/qsgatlastexture.cpp
@@ -44,6 +44,7 @@
#include <QtCore/QtMath>
#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLTexture>
#include <QtGui/QOpenGLFunctions>
#include <QtGui/QGuiApplication>
#include <QtGui/QScreen>
@@ -51,7 +52,10 @@
#include <QtGui/QWindow>
#include <QtGui/qpa/qplatformnativeinterface.h>
+#include <private/qqmlglobal_p.h>
#include <private/qsgtexture_p.h>
+#include <private/qsgcompressedtexture_p.h>
+#include <private/qsgcompressedatlastexture_p.h>
#include <private/qquickprofiler_p.h>
@@ -65,11 +69,13 @@ int qt_sg_envInt(const char *name, int defaultValue);
static QElapsedTimer qsg_renderer_timer;
+DEFINE_BOOL_CONFIG_OPTION(qsgEnableCompressedAtlas, QSG_ENABLE_COMPRESSED_ATLAS)
+
namespace QSGAtlasTexture
{
Manager::Manager()
- : m_atlas(0)
+ : m_atlas(nullptr)
{
QOpenGLContext *gl = QOpenGLContext::currentContext();
Q_ASSERT(gl);
@@ -99,7 +105,8 @@ Manager::Manager()
Manager::~Manager()
{
- Q_ASSERT(m_atlas == 0);
+ Q_ASSERT(m_atlas == nullptr);
+ Q_ASSERT(m_atlases.isEmpty());
}
void Manager::invalidate()
@@ -107,13 +114,21 @@ void Manager::invalidate()
if (m_atlas) {
m_atlas->invalidate();
m_atlas->deleteLater();
- m_atlas = 0;
+ m_atlas = nullptr;
+ }
+
+ QHash<unsigned int, QSGCompressedAtlasTexture::Atlas*>::iterator i = m_atlases.begin();
+ while (i != m_atlases.end()) {
+ i.value()->invalidate();
+ i.value()->deleteLater();
+ ++i;
}
+ m_atlases.clear();
}
QSGTexture *Manager::create(const QImage &image, bool hasAlphaChannel)
{
- Texture *t = 0;
+ Texture *t = nullptr;
if (image.width() < m_atlas_size_limit && image.height() < m_atlas_size_limit) {
if (!m_atlas)
m_atlas = new Atlas(m_atlas_size);
@@ -125,13 +140,147 @@ QSGTexture *Manager::create(const QImage &image, bool hasAlphaChannel)
return t;
}
-Atlas::Atlas(const QSize &size)
+QSGTexture *Manager::create(const QSGCompressedTextureFactory *factory)
+{
+ QSGTexture *t = nullptr;
+ if (!qsgEnableCompressedAtlas() || !factory->m_textureData || !factory->m_textureData->isValid())
+ return t;
+
+ // TODO: further abstract the atlas and remove this restriction
+ unsigned int format = factory->m_textureData->format;
+ switch (format) {
+ case QOpenGLTexture::RGB8_ETC1:
+ case QOpenGLTexture::RGB8_ETC2:
+ case QOpenGLTexture::RGBA8_ETC2_EAC:
+ case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2:
+ break;
+ default:
+ return t;
+ }
+
+ QSize size = factory->m_textureData->size;
+ if (size.width() < m_atlas_size_limit && size.height() < m_atlas_size_limit) {
+ QHash<unsigned int, QSGCompressedAtlasTexture::Atlas*>::iterator i = m_atlases.find(format);
+ if (i == m_atlases.end())
+ i = m_atlases.insert(format, new QSGCompressedAtlasTexture::Atlas(m_atlas_size, format));
+ // must be multiple of 4
+ QSize paddedSize(((size.width() + 3) / 4) * 4, ((size.height() + 3) / 4) * 4);
+ QByteArray data = factory->m_textureData->data;
+ t = i.value()->create(data, factory->m_textureData->sizeInBytes(), factory->m_textureData->dataOffset, size, paddedSize);
+ }
+ return t;
+}
+
+AtlasBase::AtlasBase(const QSize &size)
: m_allocator(size)
, m_texture_id(0)
, m_size(size)
- , m_atlas_transient_image_threshold(0)
, m_allocated(false)
{
+}
+
+AtlasBase::~AtlasBase()
+{
+ Q_ASSERT(!m_texture_id);
+}
+
+void AtlasBase::invalidate()
+{
+ if (m_texture_id && QOpenGLContext::currentContext())
+ QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &m_texture_id);
+ m_texture_id = 0;
+}
+
+int AtlasBase::textureId() const
+{
+ if (!m_texture_id) {
+ Q_ASSERT(QOpenGLContext::currentContext());
+ QOpenGLContext::currentContext()->functions()->glGenTextures(1, &const_cast<AtlasBase *>(this)->m_texture_id);
+ }
+
+ return m_texture_id;
+}
+
+void AtlasBase::bind(QSGTexture::Filtering filtering)
+{
+ QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
+ if (!m_allocated) {
+ m_allocated = true;
+
+ while (funcs->glGetError() != GL_NO_ERROR) ;
+
+ funcs->glGenTextures(1, &m_texture_id);
+ funcs->glBindTexture(GL_TEXTURE_2D, m_texture_id);
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+#if !defined(QT_OPENGL_ES_2)
+ if (!QOpenGLContext::currentContext()->isOpenGLES())
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
+#endif
+ generateTexture();
+
+ GLenum errorCode = funcs->glGetError();
+ if (errorCode == GL_OUT_OF_MEMORY) {
+ qDebug("QSGTextureAtlas: texture atlas allocation failed, out of memory");
+ funcs->glDeleteTextures(1, &m_texture_id);
+ m_texture_id = 0;
+ } else if (errorCode != GL_NO_ERROR) {
+ qDebug("QSGTextureAtlas: texture atlas allocation failed, code=%x", errorCode);
+ funcs->glDeleteTextures(1, &m_texture_id);
+ m_texture_id = 0;
+ }
+ } else {
+ funcs->glBindTexture(GL_TEXTURE_2D, m_texture_id);
+ }
+
+ if (m_texture_id == 0)
+ return;
+
+ // Upload all pending images..
+ for (int i=0; i<m_pending_uploads.size(); ++i) {
+
+ bool profileFrames = QSG_LOG_TIME_TEXTURE().isDebugEnabled();
+ if (profileFrames)
+ qsg_renderer_timer.start();
+
+ Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphTexturePrepare);
+
+ // Skip bind, convert, swizzle; they're irrelevant
+ Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare,
+ QQuickProfiler::SceneGraphTexturePrepareStart, 3);
+
+ uploadPendingTexture(i);
+
+ Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare,
+ QQuickProfiler::SceneGraphTexturePrepareUpload);
+
+ // Skip mipmap; unused
+ Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare,
+ QQuickProfiler::SceneGraphTexturePrepareUpload, 1);
+ Q_QUICK_SG_PROFILE_REPORT(QQuickProfiler::SceneGraphTexturePrepare,
+ QQuickProfiler::SceneGraphTexturePrepareMipmap);
+ }
+
+ GLenum f = filtering == QSGTexture::Nearest ? GL_NEAREST : GL_LINEAR;
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, f);
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, f);
+
+ m_pending_uploads.clear();
+}
+
+void AtlasBase::remove(TextureBase *t)
+{
+ QRect atlasRect = t->atlasSubRect();
+ m_allocator.deallocate(atlasRect);
+ m_pending_uploads.removeOne(t);
+}
+
+Atlas::Atlas(const QSize &size)
+ : AtlasBase(size)
+ , m_atlas_transient_image_threshold(0)
+{
m_internalFormat = GL_RGBA;
m_externalFormat = GL_BGRA;
@@ -188,14 +337,6 @@ Atlas::Atlas(const QSize &size)
Atlas::~Atlas()
{
- Q_ASSERT(!m_texture_id);
-}
-
-void Atlas::invalidate()
-{
- if (m_texture_id && QOpenGLContext::currentContext())
- QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &m_texture_id);
- m_texture_id = 0;
}
Texture *Atlas::create(const QImage &image)
@@ -207,18 +348,7 @@ Texture *Atlas::create(const QImage &image)
m_pending_uploads << t;
return t;
}
- return 0;
-}
-
-
-int Atlas::textureId() const
-{
- if (!m_texture_id) {
- Q_ASSERT(QOpenGLContext::currentContext());
- QOpenGLContext::currentContext()->functions()->glGenTextures(1, &const_cast<Atlas *>(this)->m_texture_id);
- }
-
- return m_texture_id;
+ return nullptr;
}
static void swizzleBGRAToRGBA(QImage *image)
@@ -334,122 +464,70 @@ void Atlas::uploadBgra(Texture *texture)
}
}
-void Atlas::bind(QSGTexture::Filtering filtering)
+void Atlas::generateTexture()
{
QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
- if (!m_allocated) {
- m_allocated = true;
-
- while (funcs->glGetError() != GL_NO_ERROR) ;
-
- funcs->glGenTextures(1, &m_texture_id);
- funcs->glBindTexture(GL_TEXTURE_2D, m_texture_id);
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-#if !defined(QT_OPENGL_ES_2)
- if (!QOpenGLContext::currentContext()->isOpenGLES())
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
-#endif
- funcs->glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_size.width(), m_size.height(), 0, m_externalFormat, GL_UNSIGNED_BYTE, 0);
+ funcs->glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_size.width(), m_size.height(), 0, m_externalFormat, GL_UNSIGNED_BYTE, nullptr);
#if 0
- QImage pink(m_size.width(), m_size.height(), QImage::Format_ARGB32_Premultiplied);
- pink.fill(0);
- QPainter p(&pink);
- QLinearGradient redGrad(0, 0, m_size.width(), 0);
- redGrad.setColorAt(0, Qt::black);
- redGrad.setColorAt(1, Qt::red);
- p.fillRect(0, 0, m_size.width(), m_size.height(), redGrad);
- p.setCompositionMode(QPainter::CompositionMode_Plus);
- QLinearGradient blueGrad(0, 0, 0, m_size.height());
- blueGrad.setColorAt(0, Qt::black);
- blueGrad.setColorAt(1, Qt::blue);
- p.fillRect(0, 0, m_size.width(), m_size.height(), blueGrad);
- p.end();
-
- funcs->glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_size.width(), m_size.height(), 0, m_externalFormat, GL_UNSIGNED_BYTE, pink.constBits());
+ QImage pink(m_size.width(), m_size.height(), QImage::Format_ARGB32_Premultiplied);
+ pink.fill(0);
+ QPainter p(&pink);
+ QLinearGradient redGrad(0, 0, m_size.width(), 0);
+ redGrad.setColorAt(0, Qt::black);
+ redGrad.setColorAt(1, Qt::red);
+ p.fillRect(0, 0, m_size.width(), m_size.height(), redGrad);
+ p.setCompositionMode(QPainter::CompositionMode_Plus);
+ QLinearGradient blueGrad(0, 0, 0, m_size.height());
+ blueGrad.setColorAt(0, Qt::black);
+ blueGrad.setColorAt(1, Qt::blue);
+ p.fillRect(0, 0, m_size.width(), m_size.height(), blueGrad);
+ p.end();
+
+ funcs->glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_size.width(), m_size.height(), 0, m_externalFormat, GL_UNSIGNED_BYTE, pink.constBits());
#endif
+}
- GLenum errorCode = funcs->glGetError();
- if (errorCode == GL_OUT_OF_MEMORY) {
- qDebug("QSGTextureAtlas: texture atlas allocation failed, out of memory");
- funcs->glDeleteTextures(1, &m_texture_id);
- m_texture_id = 0;
- } else if (errorCode != GL_NO_ERROR) {
- qDebug("QSGTextureAtlas: texture atlas allocation failed, code=%x", errorCode);
- funcs->glDeleteTextures(1, &m_texture_id);
- m_texture_id = 0;
- }
+void Atlas::uploadPendingTexture(int i)
+{
+ Texture *t = static_cast<Texture*>(m_pending_uploads.at(i));
+ if (m_externalFormat == GL_BGRA &&
+ !m_use_bgra_fallback) {
+ uploadBgra(t);
} else {
- funcs->glBindTexture(GL_TEXTURE_2D, m_texture_id);
+ upload(t);
}
-
- if (m_texture_id == 0)
- return;
-
- // Upload all pending images..
- for (int i=0; i<m_pending_uploads.size(); ++i) {
-
- bool profileFrames = QSG_LOG_TIME_TEXTURE().isDebugEnabled();
- if (profileFrames)
- qsg_renderer_timer.start();
-
- Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphTexturePrepare);
-
- // Skip bind, convert, swizzle; they're irrelevant
- Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare,
- QQuickProfiler::SceneGraphTexturePrepareStart, 3);
-
- Texture *t = m_pending_uploads.at(i);
- if (m_externalFormat == GL_BGRA &&
- !m_use_bgra_fallback) {
- uploadBgra(t);
- } else {
- upload(t);
- }
- const QSize textureSize = t->textureSize();
- if (textureSize.width() > m_atlas_transient_image_threshold ||
- textureSize.height() > m_atlas_transient_image_threshold)
- t->releaseImage();
-
- qCDebug(QSG_LOG_TIME_TEXTURE).nospace() << "atlastexture uploaded in: " << qsg_renderer_timer.elapsed()
- << "ms (" << t->textureSize().width() << "x"
- << t->textureSize().height() << ")";
-
- Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare,
- QQuickProfiler::SceneGraphTexturePrepareUpload);
-
- // Skip mipmap; unused
- Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare,
- QQuickProfiler::SceneGraphTexturePrepareUpload, 1);
- Q_QUICK_SG_PROFILE_REPORT(QQuickProfiler::SceneGraphTexturePrepare,
- QQuickProfiler::SceneGraphTexturePrepareMipmap);
- }
-
- GLenum f = filtering == QSGTexture::Nearest ? GL_NEAREST : GL_LINEAR;
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, f);
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, f);
-
- m_pending_uploads.clear();
+ const QSize textureSize = t->textureSize();
+ if (textureSize.width() > m_atlas_transient_image_threshold ||
+ textureSize.height() > m_atlas_transient_image_threshold)
+ t->releaseImage();
+
+ qCDebug(QSG_LOG_TIME_TEXTURE, "atlastexture uploaded in: %lldms (%dx%d)",
+ qsg_renderer_timer.elapsed(),
+ t->textureSize().width(),
+ t->textureSize().height());
}
-void Atlas::remove(Texture *t)
+TextureBase::TextureBase(AtlasBase *atlas, const QRect &textureRect)
+ : m_allocated_rect(textureRect)
+ , m_atlas(atlas)
{
- QRect atlasRect = t->atlasSubRect();
- m_allocator.deallocate(atlasRect);
- m_pending_uploads.removeOne(t);
}
+TextureBase::~TextureBase()
+{
+ m_atlas->remove(this);
+}
+void TextureBase::bind()
+{
+ m_atlas->bind(filtering());
+}
Texture::Texture(Atlas *atlas, const QRect &textureRect, const QImage &image)
- : QSGTexture()
- , m_allocated_rect(textureRect)
+ : TextureBase(atlas, textureRect)
, m_image(image)
- , m_atlas(atlas)
- , m_nonatlas_texture(0)
+ , m_nonatlas_texture(nullptr)
, m_has_alpha(image.hasAlphaChannel())
{
float w = atlas->size().width();
@@ -463,16 +541,10 @@ Texture::Texture(Atlas *atlas, const QRect &textureRect, const QImage &image)
Texture::~Texture()
{
- m_atlas->remove(this);
if (m_nonatlas_texture)
delete m_nonatlas_texture;
}
-void Texture::bind()
-{
- m_atlas->bind(filtering());
-}
-
QSGTexture *Texture::removedFromAtlas() const
{
if (m_nonatlas_texture) {
@@ -508,7 +580,7 @@ QSGTexture *Texture::removedFromAtlas() const
QRect r = atlasSubRectWithoutPadding();
// and copy atlas into our texture.
while (f->glGetError() != GL_NO_ERROR) ;
- f->glCopyTexImage2D(GL_TEXTURE_2D, 0, m_atlas->internalFormat(), r.x(), r.y(), r.width(), r.height(), 0);
+ f->glCopyTexImage2D(GL_TEXTURE_2D, 0, static_cast<Atlas*>(m_atlas)->internalFormat(), r.x(), r.y(), r.width(), r.height(), 0);
// BGRA may have been rejected by some GLES implementations
if (f->glGetError() != GL_NO_ERROR)
f->glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, r.x(), r.y(), r.width(), r.height(), 0);
diff --git a/src/quick/scenegraph/util/qsgatlastexture_p.h b/src/quick/scenegraph/util/qsgatlastexture_p.h
index 3dee539547..14dc8f7958 100644
--- a/src/quick/scenegraph/util/qsgatlastexture_p.h
+++ b/src/quick/scenegraph/util/qsgatlastexture_p.h
@@ -61,10 +61,16 @@
QT_BEGIN_NAMESPACE
+namespace QSGCompressedAtlasTexture {
+ class Atlas;
+}
+class QSGCompressedTextureFactory;
+
namespace QSGAtlasTexture
{
class Texture;
+class TextureBase;
class Atlas;
class Manager : public QObject
@@ -76,93 +82,121 @@ public:
~Manager();
QSGTexture *create(const QImage &image, bool hasAlphaChannel);
+ QSGTexture *create(const QSGCompressedTextureFactory *factory);
void invalidate();
private:
Atlas *m_atlas;
+ // set of atlases for different compressed formats
+ QHash<unsigned int, QSGCompressedAtlasTexture::Atlas*> m_atlases;
QSize m_atlas_size;
int m_atlas_size_limit;
};
-class Atlas : public QObject
+class AtlasBase : public QObject
{
+ Q_OBJECT
public:
- Atlas(const QSize &size);
- ~Atlas();
+ AtlasBase(const QSize &size);
+ ~AtlasBase();
void invalidate();
int textureId() const;
void bind(QSGTexture::Filtering filtering);
+ void remove(TextureBase *t);
+
+ QSize size() const { return m_size; }
+
+protected:
+ virtual void generateTexture() = 0;
+ virtual void uploadPendingTexture(int i) = 0;
+
+protected:
+ QSGAreaAllocator m_allocator;
+ unsigned int m_texture_id;
+ QSize m_size;
+ QList<TextureBase *> m_pending_uploads;
+
+private:
+ bool m_allocated;
+};
+
+class Atlas : public AtlasBase
+{
+public:
+ Atlas(const QSize &size);
+ ~Atlas();
+
+ void generateTexture() override;
+ void uploadPendingTexture(int i) override;
+
void upload(Texture *texture);
void uploadBgra(Texture *texture);
Texture *create(const QImage &image);
- void remove(Texture *t);
-
- QSize size() const { return m_size; }
uint internalFormat() const { return m_internalFormat; }
uint externalFormat() const { return m_externalFormat; }
private:
- QSGAreaAllocator m_allocator;
- unsigned int m_texture_id;
- QSize m_size;
- QList<Texture *> m_pending_uploads;
-
uint m_internalFormat;
uint m_externalFormat;
int m_atlas_transient_image_threshold;
- uint m_allocated : 1;
uint m_use_bgra_fallback: 1;
-
uint m_debug_overlay : 1;
};
-class Texture : public QSGTexture
+class TextureBase : public QSGTexture
+{
+ Q_OBJECT
+public:
+ TextureBase(AtlasBase *atlas, const QRect &textureRect);
+ ~TextureBase();
+
+ int textureId() const override { return m_atlas->textureId(); }
+ bool isAtlasTexture() const override { return true; }
+
+ QRect atlasSubRect() const { return m_allocated_rect; }
+
+ void bind() override;
+
+protected:
+ QRect m_allocated_rect;
+ AtlasBase *m_atlas;
+};
+
+class Texture : public TextureBase
{
Q_OBJECT
public:
Texture(Atlas *atlas, const QRect &textureRect, const QImage &image);
~Texture();
- int textureId() const override { return m_atlas->textureId(); }
QSize textureSize() const override { return atlasSubRectWithoutPadding().size(); }
void setHasAlphaChannel(bool alpha) { m_has_alpha = alpha; }
bool hasAlphaChannel() const override { return m_has_alpha; }
bool hasMipmaps() const override { return false; }
- bool isAtlasTexture() const override { return true; }
QRectF normalizedTextureSubRect() const override { return m_texture_coords_rect; }
QRect atlasSubRect() const { return m_allocated_rect; }
QRect atlasSubRectWithoutPadding() const { return m_allocated_rect.adjusted(1, 1, -1, -1); }
- bool isTexture() const { return true; }
-
QSGTexture *removedFromAtlas() const override;
void releaseImage() { m_image = QImage(); }
const QImage &image() const { return m_image; }
- void bind() override;
-
private:
- QRect m_allocated_rect;
QRectF m_texture_coords_rect;
-
QImage m_image;
-
- Atlas *m_atlas;
-
mutable QSGPlainTexture *m_nonatlas_texture;
-
- uint m_has_alpha : 1;
+ bool m_has_alpha;
};
}
diff --git a/src/quick/scenegraph/util/qsgdefaultpainternode.cpp b/src/quick/scenegraph/util/qsgdefaultpainternode.cpp
index 9ffd1b4b08..981ea089be 100644
--- a/src/quick/scenegraph/util/qsgdefaultpainternode.cpp
+++ b/src/quick/scenegraph/util/qsgdefaultpainternode.cpp
@@ -78,11 +78,11 @@ QSGDefaultPainterNode::QSGDefaultPainterNode(QQuickPaintedItem *item)
, m_preferredRenderTarget(QQuickPaintedItem::Image)
, m_actualRenderTarget(QQuickPaintedItem::Image)
, m_item(item)
- , m_fbo(0)
- , m_multisampledFbo(0)
+ , m_fbo(nullptr)
+ , m_multisampledFbo(nullptr)
, m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)
- , m_texture(0)
- , m_gl_device(0)
+ , m_texture(nullptr)
+ , m_gl_device(nullptr)
, m_fillColor(Qt::transparent)
, m_contentsScale(1.0)
, m_dirtyContents(false)
@@ -260,8 +260,8 @@ void QSGDefaultPainterNode::updateRenderTarget()
delete m_fbo;
delete m_multisampledFbo;
delete m_gl_device;
- m_fbo = m_multisampledFbo = 0;
- m_gl_device = 0;
+ m_fbo = m_multisampledFbo = nullptr;
+ m_gl_device = nullptr;
}
if (m_actualRenderTarget == QQuickPaintedItem::FramebufferObject ||
@@ -275,7 +275,7 @@ void QSGDefaultPainterNode::updateRenderTarget()
delete m_fbo;
delete m_multisampledFbo;
- m_fbo = m_multisampledFbo = 0;
+ m_fbo = m_multisampledFbo = nullptr;
if (m_gl_device)
m_gl_device->setSize(m_fboSize);
diff --git a/src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp b/src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp
index ba0207aca8..56508af152 100644
--- a/src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp
+++ b/src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp
@@ -43,7 +43,7 @@ QT_BEGIN_NAMESPACE
QSGDepthStencilBuffer::QSGDepthStencilBuffer(QOpenGLContext *context, const Format &format)
: m_functions(context)
- , m_manager(0)
+ , m_manager(nullptr)
, m_format(format)
, m_depthBuffer(0)
, m_stencilBuffer(0)
@@ -160,7 +160,7 @@ QSGDepthStencilBufferManager::~QSGDepthStencilBufferManager()
for (Hash::const_iterator it = m_buffers.constBegin(), cend = m_buffers.constEnd(); it != cend; ++it) {
QSGDepthStencilBuffer *buffer = it.value().data();
buffer->free();
- buffer->m_manager = 0;
+ buffer->m_manager = nullptr;
}
}
@@ -174,7 +174,7 @@ QSharedPointer<QSGDepthStencilBuffer> QSGDepthStencilBufferManager::bufferForFor
void QSGDepthStencilBufferManager::insertBuffer(const QSharedPointer<QSGDepthStencilBuffer> &buffer)
{
- Q_ASSERT(buffer->m_manager == 0);
+ Q_ASSERT(buffer->m_manager == nullptr);
Q_ASSERT(!m_buffers.contains(buffer->m_format));
buffer->m_manager = this;
m_buffers.insert(buffer->m_format, buffer.toWeakRef());
diff --git a/src/quick/scenegraph/util/qsgengine.cpp b/src/quick/scenegraph/util/qsgengine.cpp
index dffe199224..91fa46033c 100644
--- a/src/quick/scenegraph/util/qsgengine.cpp
+++ b/src/quick/scenegraph/util/qsgengine.cpp
@@ -157,7 +157,7 @@ QSGAbstractRenderer *QSGEngine::createRenderer() const
{
Q_D(const QSGEngine);
if (!d->sgRenderContext->isValid())
- return 0;
+ return nullptr;
QSGRenderer *renderer = d->sgRenderContext->createRenderer();
renderer->setCustomRenderMode(qgetenv("QSG_VISUALIZE"));
@@ -178,7 +178,7 @@ QSGTexture *QSGEngine::createTextureFromImage(const QImage &image, CreateTexture
{
Q_D(const QSGEngine);
if (!d->sgRenderContext->isValid())
- return 0;
+ return nullptr;
uint flags = 0;
if (options & TextureCanUseAtlas) flags |= QSGRenderContext::CreateTexture_Atlas;
if (!(options & TextureIsOpaque)) flags |= QSGRenderContext::CreateTexture_Alpha;
@@ -206,7 +206,7 @@ QSGTexture *QSGEngine::createTextureFromId(uint id, const QSize &size, CreateTex
texture->setTextureSize(size);
return texture;
}
- return 0;
+ return nullptr;
}
/*!
diff --git a/src/quick/scenegraph/util/qsgengine.h b/src/quick/scenegraph/util/qsgengine.h
index 514e6e8c2b..e9e01dc710 100644
--- a/src/quick/scenegraph/util/qsgengine.h
+++ b/src/quick/scenegraph/util/qsgengine.h
@@ -68,7 +68,7 @@ public:
Q_DECLARE_FLAGS(CreateTextureOptions, CreateTextureOption)
explicit QSGEngine(QObject *parent = nullptr);
- ~QSGEngine();
+ ~QSGEngine() override;
void initialize(QOpenGLContext *context);
void invalidate();
diff --git a/src/quick/scenegraph/util/qsgflatcolormaterial.cpp b/src/quick/scenegraph/util/qsgflatcolormaterial.cpp
index a0c71b5340..28f6113a60 100644
--- a/src/quick/scenegraph/util/qsgflatcolormaterial.cpp
+++ b/src/quick/scenegraph/util/qsgflatcolormaterial.cpp
@@ -77,13 +77,13 @@ FlatColorMaterialShader::FlatColorMaterialShader()
void FlatColorMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
{
#if QT_CONFIG(opengl)
- Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type());
+ Q_ASSERT(oldEffect == nullptr || newEffect->type() == oldEffect->type());
QSGFlatColorMaterial *oldMaterial = static_cast<QSGFlatColorMaterial *>(oldEffect);
QSGFlatColorMaterial *newMaterial = static_cast<QSGFlatColorMaterial *>(newEffect);
const QColor &c = newMaterial->color();
- if (oldMaterial == 0 || c != oldMaterial->color() || state.isOpacityDirty()) {
+ if (oldMaterial == nullptr || c != oldMaterial->color() || state.isOpacityDirty()) {
float opacity = state.opacity() * c.alphaF();
QVector4D v(c.redF() * opacity,
c.greenF() * opacity,
@@ -103,7 +103,7 @@ void FlatColorMaterialShader::updateState(const RenderState &state, QSGMaterial
char const *const *FlatColorMaterialShader::attributeNames() const
{
- static char const *const attr[] = { "vCoord", 0 };
+ static char const *const attr[] = { "vCoord", nullptr };
return attr;
}
diff --git a/src/quick/scenegraph/util/qsgimagenode.cpp b/src/quick/scenegraph/util/qsgimagenode.cpp
index c03c91d1cb..b154023247 100644
--- a/src/quick/scenegraph/util/qsgimagenode.cpp
+++ b/src/quick/scenegraph/util/qsgimagenode.cpp
@@ -168,7 +168,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QSGImageNode::TextureCoordinatesTransformMode textureCoordinatesTransform() const
+ \fn QSGImageNode::TextureCoordinatesTransformMode QSGImageNode::textureCoordinatesTransform() const
Returns the mode used to generate texture coordinates for this node.
*/
@@ -187,6 +187,15 @@ QT_BEGIN_NAMESPACE
\return \c true if the node takes ownership of the texture; otherwise \c false.
*/
+/*!
+ Updates the geometry \a g with the \a texture, the coordinates
+ in \a rect, and the texture coordinates from \a sourceRect.
+
+ \a g is assumed to be a triangle strip of four vertices of type
+ QSGGeometry::TexturedPoint2D.
+
+ \a texCoordMode is used for normalizing the \a sourceRect.
+ */
void QSGImageNode::rebuildGeometry(QSGGeometry *g,
QSGTexture *texture,
const QRectF &rect,
diff --git a/src/quick/scenegraph/util/qsgimagenode.h b/src/quick/scenegraph/util/qsgimagenode.h
index 0e053c307f..526f52b7e5 100644
--- a/src/quick/scenegraph/util/qsgimagenode.h
+++ b/src/quick/scenegraph/util/qsgimagenode.h
@@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE
class Q_QUICK_EXPORT QSGImageNode : public QSGGeometryNode
{
public:
- virtual ~QSGImageNode() { }
+ ~QSGImageNode() override { }
virtual void setRect(const QRectF &rect) = 0;
inline void setRect(qreal x, qreal y, qreal w, qreal h) { setRect(QRectF(x, y, w, h)); }
diff --git a/src/quick/scenegraph/util/qsgninepatchnode.h b/src/quick/scenegraph/util/qsgninepatchnode.h
index 8509cbd326..e76afd3c4a 100644
--- a/src/quick/scenegraph/util/qsgninepatchnode.h
+++ b/src/quick/scenegraph/util/qsgninepatchnode.h
@@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE
class Q_QUICK_EXPORT QSGNinePatchNode : public QSGGeometryNode
{
public:
- virtual ~QSGNinePatchNode() { }
+ ~QSGNinePatchNode() override { }
virtual void setTexture(QSGTexture *texture) = 0;
virtual void setBounds(const QRectF &bounds) = 0;
diff --git a/src/quick/scenegraph/util/qsgrectanglenode.h b/src/quick/scenegraph/util/qsgrectanglenode.h
index 8e0da1d9c7..ba52b65b07 100644
--- a/src/quick/scenegraph/util/qsgrectanglenode.h
+++ b/src/quick/scenegraph/util/qsgrectanglenode.h
@@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE
class Q_QUICK_EXPORT QSGRectangleNode : public QSGGeometryNode
{
public:
- virtual ~QSGRectangleNode() { }
+ ~QSGRectangleNode() override { }
virtual void setRect(const QRectF &rect) = 0;
inline void setRect(qreal x, qreal y, qreal w, qreal h) { setRect(QRectF(x, y, w, h)); }
diff --git a/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp b/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp
index e134a5d4d3..93fc213f2e 100644
--- a/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp
+++ b/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp
@@ -262,8 +262,8 @@ void QSGShaderSourceBuilder::addDefinition(const QByteArray &definition)
tok.initialize(input);
// First find #version, #extension's and "void main() { ... "
- const char *versionPos = 0;
- const char *extensionPos = 0;
+ const char *versionPos = nullptr;
+ const char *extensionPos = nullptr;
bool inSingleLineComment = false;
bool inMultiLineComment = false;
bool foundVersionStart = false;
@@ -325,8 +325,8 @@ void QSGShaderSourceBuilder::removeVersion()
tok.initialize(input);
// First find #version beginning and end (if present)
- const char *versionStartPos = 0;
- const char *versionEndPos = 0;
+ const char *versionStartPos = nullptr;
+ const char *versionEndPos = nullptr;
bool inSingleLineComment = false;
bool inMultiLineComment = false;
bool foundVersionStart = false;
@@ -361,7 +361,7 @@ void QSGShaderSourceBuilder::removeVersion()
t = tok.next();
}
- if (versionStartPos == 0)
+ if (versionStartPos == nullptr)
return;
// Construct a new shader string, inserting the definition
diff --git a/src/quick/scenegraph/util/qsgsimplematerial.cpp b/src/quick/scenegraph/util/qsgsimplematerial.cpp
index f29c58ad9e..376f7dce5c 100644
--- a/src/quick/scenegraph/util/qsgsimplematerial.cpp
+++ b/src/quick/scenegraph/util/qsgsimplematerial.cpp
@@ -173,17 +173,17 @@
/*!
- \fn char const *const *QSGSimpleMaterialShader::attributeNames() const
+ \fn template <typename State> char const *const *QSGSimpleMaterialShader<State>::attributeNames() const
\internal
*/
/*!
- \fn void QSGSimpleMaterialShader::initialize()
+ \fn template <typename State> void QSGSimpleMaterialShader<State>::initialize()
\internal
*/
/*!
- \fn void QSGSimpleMaterialShader::resolveUniforms()
+ \fn template <typename State> void QSGSimpleMaterialShader<State>::resolveUniforms()
Reimplement this function to resolve the location of named uniforms
in the shader program.
@@ -192,34 +192,34 @@
*/
/*!
- \fn const char *QSGSimpleMaterialShader::uniformMatrixName() const
+ \fn template <typename State> const char *QSGSimpleMaterialShader<State>::uniformMatrixName() const
Returns the name for the transform matrix uniform of this item.
The default value is \c qt_Matrix.
*/
/*!
- \fn const char *QSGSimpleMaterialShader::uniformOpacityName() const
+ \fn template <typename State> const char *QSGSimpleMaterialShader<State>::uniformOpacityName() const
Returns the name for the opacity uniform of this item.
The default value is \c qt_Opacity.
*/
/*!
- \fn void QSGSimpleMaterialShader::updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
+ \fn template <typename State> void QSGSimpleMaterialShader<State>::updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
\internal
*/
/*!
- \fn QList<QByteArray> QSGSimpleMaterialShader::attributes() const
+ \fn template <typename State> QList<QByteArray> QSGSimpleMaterialShader<State>::attributes() const
Returns a list of names, declaring the vertex attributes in the
vertex shader.
*/
/*!
- \fn void QSGSimpleMaterialShader::updateState(const State *newState, const State *oldState)
+ \fn template <typename State> void QSGSimpleMaterialShader<State>::updateState(const State *newState, const State *oldState)
Called whenever the state of this shader should be updated from
\a oldState to \a newState, typical for each new set of
diff --git a/src/quick/scenegraph/util/qsgsimplematerial.h b/src/quick/scenegraph/util/qsgsimplematerial.h
index b5b8815b4a..79180ca8e2 100644
--- a/src/quick/scenegraph/util/qsgsimplematerial.h
+++ b/src/quick/scenegraph/util/qsgsimplematerial.h
@@ -138,7 +138,7 @@ template <typename State>
class QSGSimpleMaterial : public QSGMaterial
{
public:
-#ifndef qdoc
+#ifndef Q_CLANG_QDOC
QSGSimpleMaterial(const State &aState, PtrShaderCreateFunc func)
: m_state(aState)
, m_func(func)
@@ -185,7 +185,7 @@ public:
QSGSimpleMaterialComparableMaterial(PtrShaderCreateFunc func)
: QSGSimpleMaterial<State>(func) {}
- int compare(const QSGMaterial *other) const {
+ int compare(const QSGMaterial *other) const override {
return QSGSimpleMaterialComparableMaterial<State>::state()->compare(static_cast<const QSGSimpleMaterialComparableMaterial<State> *>(other)->state());
}
};
@@ -207,7 +207,7 @@ Q_INLINE_TEMPLATE void QSGSimpleMaterialShader<State>::updateState(const RenderS
Q_UNUSED(state)
#endif
State *ns = static_cast<QSGSimpleMaterial<State> *>(newMaterial)->state();
- State *old = 0;
+ State *old = nullptr;
if (oldMaterial)
old = static_cast<QSGSimpleMaterial<State> *>(oldMaterial)->state();
updateState(ns, old);
diff --git a/src/quick/scenegraph/util/qsgsimpletexturenode.cpp b/src/quick/scenegraph/util/qsgsimpletexturenode.cpp
index 6ce37de7cb..0c49ca9aa5 100644
--- a/src/quick/scenegraph/util/qsgsimpletexturenode.cpp
+++ b/src/quick/scenegraph/util/qsgsimpletexturenode.cpp
@@ -47,8 +47,7 @@ class QSGSimpleTextureNodePrivate : public QSGGeometryNodePrivate
{
public:
QSGSimpleTextureNodePrivate()
- : QSGGeometryNodePrivate()
- , texCoordMode(QSGSimpleTextureNode::NoTransform)
+ : texCoordMode(QSGSimpleTextureNode::NoTransform)
, isAtlasTexture(false)
, ownsTexture(false)
{}
diff --git a/src/quick/scenegraph/util/qsgsimpletexturenode.h b/src/quick/scenegraph/util/qsgsimpletexturenode.h
index 09e4277c66..010463d3c6 100644
--- a/src/quick/scenegraph/util/qsgsimpletexturenode.h
+++ b/src/quick/scenegraph/util/qsgsimpletexturenode.h
@@ -52,7 +52,7 @@ class Q_QUICK_EXPORT QSGSimpleTextureNode : public QSGGeometryNode
{
public:
QSGSimpleTextureNode();
- ~QSGSimpleTextureNode();
+ ~QSGSimpleTextureNode() override;
void setRect(const QRectF &rect);
inline void setRect(qreal x, qreal y, qreal w, qreal h) { setRect(QRectF(x, y, w, h)); }
diff --git a/src/quick/scenegraph/util/qsgtexture.cpp b/src/quick/scenegraph/util/qsgtexture.cpp
index 4f11d95e70..fea92a5121 100644
--- a/src/quick/scenegraph/util/qsgtexture.cpp
+++ b/src/quick/scenegraph/util/qsgtexture.cpp
@@ -53,7 +53,7 @@
#endif
#include <private/qsgmaterialshader_p.h>
-#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) && !defined(__UCLIBC__)
+#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) && defined(__GLIBC__)
#define CAN_BACKTRACE_EXECINFO
#endif
@@ -399,7 +399,7 @@ QSGTexture::~QSGTexture()
QSGTexture *QSGTexture::removedFromAtlas() const
{
Q_ASSERT_X(!isAtlasTexture(), "QSGTexture::removedFromAtlas()", "Called on a non-atlas texture");
- return 0;
+ return nullptr;
}
/*!
diff --git a/src/quick/scenegraph/util/qsgtexture.h b/src/quick/scenegraph/util/qsgtexture.h
index 032129434e..7bd57a16e3 100644
--- a/src/quick/scenegraph/util/qsgtexture.h
+++ b/src/quick/scenegraph/util/qsgtexture.h
@@ -54,7 +54,7 @@ class Q_QUICK_EXPORT QSGTexture : public QObject
public:
QSGTexture();
- ~QSGTexture();
+ ~QSGTexture() override;
enum WrapMode {
Repeat,
diff --git a/src/quick/scenegraph/util/qsgtexture_p.h b/src/quick/scenegraph/util/qsgtexture_p.h
index 52dc6db2d0..18dd5eff68 100644
--- a/src/quick/scenegraph/util/qsgtexture_p.h
+++ b/src/quick/scenegraph/util/qsgtexture_p.h
@@ -83,7 +83,7 @@ class Q_QUICK_PRIVATE_EXPORT QSGPlainTexture : public QSGTexture
Q_OBJECT
public:
QSGPlainTexture();
- virtual ~QSGPlainTexture();
+ ~QSGPlainTexture() override;
void setOwnsTexture(bool owns) { m_owns_texture = owns; }
bool ownsTexture() const { return m_owns_texture; }
diff --git a/src/quick/scenegraph/util/qsgtexturematerial.cpp b/src/quick/scenegraph/util/qsgtexturematerial.cpp
index fbc8f27a63..7b1d5abb26 100644
--- a/src/quick/scenegraph/util/qsgtexturematerial.cpp
+++ b/src/quick/scenegraph/util/qsgtexturematerial.cpp
@@ -57,7 +57,6 @@ inline static bool isPowerOfTwo(int x)
QSGMaterialType QSGOpaqueTextureMaterialShader::type;
QSGOpaqueTextureMaterialShader::QSGOpaqueTextureMaterialShader()
- : QSGMaterialShader()
{
#if QT_CONFIG(opengl)
setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/opaquetexture.vert"));
@@ -67,7 +66,7 @@ QSGOpaqueTextureMaterialShader::QSGOpaqueTextureMaterialShader()
char const *const *QSGOpaqueTextureMaterialShader::attributeNames() const
{
- static char const *const attr[] = { "qt_VertexPosition", "qt_VertexTexCoord", 0 };
+ static char const *const attr[] = { "qt_VertexPosition", "qt_VertexTexCoord", nullptr };
return attr;
}
@@ -80,7 +79,7 @@ void QSGOpaqueTextureMaterialShader::initialize()
void QSGOpaqueTextureMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
{
- Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type());
+ Q_ASSERT(oldEffect == nullptr || newEffect->type() == oldEffect->type());
QSGOpaqueTextureMaterial *tx = static_cast<QSGOpaqueTextureMaterial *>(newEffect);
QSGOpaqueTextureMaterial *oldTx = static_cast<QSGOpaqueTextureMaterial *>(oldEffect);
@@ -112,7 +111,7 @@ void QSGOpaqueTextureMaterialShader::updateState(const RenderState &state, QSGMa
t->setMipmapFiltering(tx->mipmapFiltering());
t->setAnisotropyLevel(tx->anisotropyLevel());
- if (oldTx == 0 || oldTx->texture()->textureId() != t->textureId())
+ if (oldTx == nullptr || oldTx->texture()->textureId() != t->textureId())
t->bind();
else
t->updateBindOptions();
@@ -169,7 +168,7 @@ void QSGOpaqueTextureMaterialShader::updateState(const RenderState &state, QSGMa
*/
QSGOpaqueTextureMaterial::QSGOpaqueTextureMaterial()
- : m_texture(0)
+ : m_texture(nullptr)
, m_filtering(QSGTexture::Nearest)
, m_mipmap_filtering(QSGTexture::None)
, m_horizontal_wrap(QSGTexture::ClampToEdge)
@@ -304,7 +303,17 @@ void QSGOpaqueTextureMaterial::setTexture(QSGTexture *texture)
The default vertical wrap mode is \c QSGTexture::ClampToEdge.
*/
+/*!
+ \fn void QSGOpaqueTextureMaterial::setAnisotropyLevel(QSGTexture::AnisotropyLevel level)
+
+ Sets this material's anistropy level to \a level.
+*/
+
+/*!
+ \fn QSGTexture::AnisotropyLevel QSGOpaqueTextureMaterial::anisotropyLevel() const
+ Returns this material's anistropy level.
+*/
/*!
\internal
@@ -388,7 +397,7 @@ QSGTextureMaterialShader::QSGTextureMaterialShader()
void QSGTextureMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
{
- Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type());
+ Q_ASSERT(oldEffect == nullptr || newEffect->type() == oldEffect->type());
#if QT_CONFIG(opengl)
if (state.isOpacityDirty())
program()->setUniformValue(m_opacity_id, state.opacity());
diff --git a/src/quick/scenegraph/util/qsgtexturereader.cpp b/src/quick/scenegraph/util/qsgtexturereader.cpp
index 61729ada18..8af2c8e7cd 100644
--- a/src/quick/scenegraph/util/qsgtexturereader.cpp
+++ b/src/quick/scenegraph/util/qsgtexturereader.cpp
@@ -43,40 +43,71 @@
#if QT_CONFIG(opengl)
#include <private/qsgpkmhandler_p.h>
+#include <private/qsgktxhandler_p.h>
#endif
+#include <QFileInfo>
+
QT_BEGIN_NAMESPACE
-QSGTextureReader::QSGTextureReader()
+QSGTextureReader::QSGTextureReader(QIODevice *device, const QString &fileName)
+ : m_device(device), m_fileInfo(fileName)
{
+}
+QSGTextureReader::~QSGTextureReader()
+{
+ delete m_handler;
}
-QQuickTextureFactory *QSGTextureReader::read(QIODevice *device, const QByteArray &format)
+QQuickTextureFactory *QSGTextureReader::read()
{
#if QT_CONFIG(opengl)
- if (format == QByteArrayLiteral("pkm")) {
- QSGPkmHandler handler;
- return handler.read(device);
- }
+ if (!isTexture())
+ return nullptr;
+ return m_handler->read();
#else
- Q_UNUSED(device)
- Q_UNUSED(format)
-#endif
return nullptr;
+#endif
}
-bool QSGTextureReader::isTexture(QIODevice *device, const QByteArray &format)
+bool QSGTextureReader::isTexture()
{
#if QT_CONFIG(opengl)
- if (format == QByteArrayLiteral("pkm")) {
- return device->peek(4) == QByteArrayLiteral("PKM ");
+ if (!checked) {
+ checked = true;
+ if (!init())
+ return false;
+
+ QByteArray headerBlock = m_device->peek(64);
+ QByteArray suffix = m_fileInfo.suffix().toLower().toLatin1();
+ QByteArray logName = m_fileInfo.fileName().toUtf8();
+
+ // Currently the handlers are hardcoded; later maybe a list of plugins
+ if (QSGPkmHandler::canRead(suffix, headerBlock)) {
+ m_handler = new QSGPkmHandler(m_device, logName);
+ } else if (QSGKtxHandler::canRead(suffix, headerBlock)) {
+ m_handler = new QSGKtxHandler(m_device, logName);
+ }
+ // else if OtherHandler::canRead() ...etc.
}
+ return (m_handler != nullptr);
#else
- Q_UNUSED(device)
- Q_UNUSED(format)
-#endif
return false;
+#endif
+}
+
+QList<QByteArray> QSGTextureReader::supportedFileFormats()
+{
+ // Hardcoded for now
+ return {QByteArrayLiteral("pkm"), QByteArrayLiteral("ktx")};
+}
+
+bool QSGTextureReader::init()
+{
+ if (!m_device)
+ return false;
+ return m_device->isReadable();
}
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgtexturereader_p.h b/src/quick/scenegraph/util/qsgtexturereader_p.h
index 7d2fc314a6..19e33bf5c3 100644
--- a/src/quick/scenegraph/util/qsgtexturereader_p.h
+++ b/src/quick/scenegraph/util/qsgtexturereader_p.h
@@ -52,19 +52,34 @@
//
#include <QString>
+#include <QFileInfo>
QT_BEGIN_NAMESPACE
class QIODevice;
class QQuickTextureFactory;
+class QSGTextureFileHandler;
class QSGTextureReader
{
public:
- QSGTextureReader();
+ QSGTextureReader(QIODevice *device, const QString &fileName = QString());
+ ~QSGTextureReader();
- static QQuickTextureFactory *read(QIODevice *device, const QByteArray &format);
- static bool isTexture(QIODevice *device, const QByteArray &format);
+ QQuickTextureFactory *read();
+ bool isTexture();
+
+ // TBD access function to params
+ // TBD ask for identified fmt
+
+ static QList<QByteArray> supportedFileFormats();
+
+private:
+ bool init();
+ QIODevice *m_device = nullptr;
+ QFileInfo m_fileInfo;
+ QSGTextureFileHandler *m_handler = nullptr;
+ bool checked = false;
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp b/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp
index 42c589b14a..cb61430e2e 100644
--- a/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp
+++ b/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp
@@ -64,7 +64,6 @@ private:
QSGMaterialType QSGVertexColorMaterialShader::type;
QSGVertexColorMaterialShader::QSGVertexColorMaterialShader()
- : QSGMaterialShader()
{
#if QT_CONFIG(opengl)
setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/vertexcolor.vert"));
@@ -87,7 +86,7 @@ void QSGVertexColorMaterialShader::updateState(const RenderState &state, QSGMate
char const *const *QSGVertexColorMaterialShader::attributeNames() const
{
- static const char *const attr[] = { "vertexCoord", "vertexColor", 0 };
+ static const char *const attr[] = { "vertexCoord", "vertexColor", nullptr };
return attr;
}