aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/scenegraph')
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp28
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h7
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp2
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation_p.h2
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp4
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp13
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode_p.h2
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp10
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode_p.h2
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp9
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarepainternode.cpp2
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp22
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp2
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes_p.h2
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp45
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp4
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp4
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp1
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp6
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp174
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h119
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp246
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgcompressedtexture_p.h126
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgktxhandler.cpp186
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgktxhandler_p.h78
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgpkmhandler.cpp169
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgpkmhandler_p.h34
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgtexturefilehandler_p.h83
-rw-r--r--src/quick/scenegraph/coreapi/qsgabstractrenderer.cpp2
-rw-r--r--src/quick/scenegraph/coreapi/qsgabstractrenderer.h2
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp168
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h74
-rw-r--r--src/quick/scenegraph/coreapi/qsggeometry.cpp21
-rw-r--r--src/quick/scenegraph/coreapi/qsgmaterial.cpp7
-rw-r--r--src/quick/scenegraph/coreapi/qsgnode.cpp91
-rw-r--r--src/quick/scenegraph/coreapi/qsgnode.h45
-rw-r--r--src/quick/scenegraph/coreapi/qsgnode_p.h8
-rw-r--r--src/quick/scenegraph/coreapi/qsgnodeupdater.cpp6
-rw-r--r--src/quick/scenegraph/coreapi/qsgrenderer.cpp8
-rw-r--r--src/quick/scenegraph/coreapi/qsgrenderer_p.h4
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendernode.cpp26
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendernode.h2
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer_p.h46
-rw-r--r--src/quick/scenegraph/qsgbasicglyphnode.cpp6
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp23
-rw-r--r--src/quick/scenegraph/qsgcontext_p.h8
-rw-r--r--src/quick/scenegraph/qsgcontextplugin.cpp14
-rw-r--r--src/quick/scenegraph/qsgcontextplugin_p.h6
-rw-r--r--src/quick/scenegraph/qsgdefaultcontext.cpp23
-rw-r--r--src/quick/scenegraph/qsgdefaultcontext_p.h2
-rw-r--r--src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp10
-rw-r--r--src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h5
-rw-r--r--src/quick/scenegraph/qsgdefaultglyphnode_p.cpp30
-rw-r--r--src/quick/scenegraph/qsgdefaultinternalimagenode.cpp7
-rw-r--r--src/quick/scenegraph/qsgdefaultinternalrectanglenode.cpp5
-rw-r--r--src/quick/scenegraph/qsgdefaultlayer.cpp26
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext.cpp15
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext_p.h3
-rw-r--r--src/quick/scenegraph/qsgdefaultspritenode.cpp29
-rw-r--r--src/quick/scenegraph/qsgdistancefieldglyphnode.cpp12
-rw-r--r--src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp76
-rw-r--r--src/quick/scenegraph/qsgrenderloop.cpp18
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp182
-rw-r--r--src/quick/scenegraph/qsgwindowsrenderloop.cpp16
-rw-r--r--src/quick/scenegraph/scenegraph.pri13
-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
90 files changed, 2082 insertions, 985 deletions
diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp
index 02cf8209d1..d715d900ba 100644
--- a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp
@@ -193,6 +193,12 @@ QRegion QSGAbstractSoftwareRenderer::optimizeRenderList()
}
}
+ if (m_obscuredRegion.contains(m_background->rect().toAlignedRect())) {
+ m_isOpaque = true;
+ } else {
+ m_isOpaque = false;
+ }
+
// Empty dirtyRegion (for second pass)
m_dirtyRegion = QRegion();
m_obscuredRegion = QRegion();
@@ -227,11 +233,11 @@ void QSGAbstractSoftwareRenderer::setBackgroundColor(const QColor &color)
renderableNode(m_background)->markMaterialDirty();
}
-void QSGAbstractSoftwareRenderer::setBackgroundSize(const QSize &size)
+void QSGAbstractSoftwareRenderer::setBackgroundRect(const QRect &rect)
{
- if (m_background->rect().size().toSize() == size)
+ if (m_background->rect().toRect() == rect)
return;
- m_background->setRect(0.0f, 0.0f, size.width(), size.height());
+ m_background->setRect(rect);
renderableNode(m_background)->markGeometryDirty();
// Invalidate the whole scene when the background is resized
markDirty();
@@ -242,21 +248,21 @@ QColor QSGAbstractSoftwareRenderer::backgroundColor()
return m_background->color();
}
-QSize QSGAbstractSoftwareRenderer::backgroundSize()
+QRect QSGAbstractSoftwareRenderer::backgroundRect()
{
- return m_background->rect().size().toSize();
+ return m_background->rect().toRect();
}
void QSGAbstractSoftwareRenderer::nodeAdded(QSGNode *node)
{
- qCDebug(lc2DRender) << "nodeAdded" << (void*)node;
+ qCDebug(lc2DRender, "nodeAdded %p", (void*)node);
m_nodeUpdater->updateNodes(node);
}
void QSGAbstractSoftwareRenderer::nodeRemoved(QSGNode *node)
{
- qCDebug(lc2DRender) << "nodeRemoved" << (void*)node;
+ qCDebug(lc2DRender, "nodeRemoved %p", (void*)node);
auto renderable = renderableNode(node);
// remove mapping
@@ -280,7 +286,7 @@ void QSGAbstractSoftwareRenderer::nodeRemoved(QSGNode *node)
void QSGAbstractSoftwareRenderer::nodeGeometryUpdated(QSGNode *node)
{
- qCDebug(lc2DRender) << "nodeGeometryUpdated";
+ qCDebug(lc2DRender, "nodeGeometryUpdated");
// Mark node as dirty
auto renderable = renderableNode(node);
@@ -293,7 +299,7 @@ void QSGAbstractSoftwareRenderer::nodeGeometryUpdated(QSGNode *node)
void QSGAbstractSoftwareRenderer::nodeMaterialUpdated(QSGNode *node)
{
- qCDebug(lc2DRender) << "nodeMaterialUpdated";
+ qCDebug(lc2DRender, "nodeMaterialUpdated");
// Mark node as dirty
auto renderable = renderableNode(node);
@@ -306,7 +312,7 @@ void QSGAbstractSoftwareRenderer::nodeMaterialUpdated(QSGNode *node)
void QSGAbstractSoftwareRenderer::nodeMatrixUpdated(QSGNode *node)
{
- qCDebug(lc2DRender) << "nodeMaterialUpdated";
+ qCDebug(lc2DRender, "nodeMaterialUpdated");
// Update children nodes
m_nodeUpdater->updateNodes(node);
@@ -314,7 +320,7 @@ void QSGAbstractSoftwareRenderer::nodeMatrixUpdated(QSGNode *node)
void QSGAbstractSoftwareRenderer::nodeOpacityUpdated(QSGNode *node)
{
- qCDebug(lc2DRender) << "nodeOpacityUpdated";
+ qCDebug(lc2DRender, "nodeOpacityUpdated");
// Update children nodes
m_nodeUpdater->updateNodes(node);
diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h
index 04a17ea377..f6594d931a 100644
--- a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h
@@ -83,9 +83,11 @@ protected:
QRegion optimizeRenderList();
void setBackgroundColor(const QColor &color);
- void setBackgroundSize(const QSize &size);
+ void setBackgroundRect(const QRect &rect);
QColor backgroundColor();
- QSize backgroundSize();
+ QRect backgroundRect();
+ // only known after calling optimizeRenderList()
+ bool isOpaque() const { return m_isOpaque; }
private:
void nodeAdded(QSGNode *node);
@@ -102,6 +104,7 @@ private:
QRegion m_dirtyRegion;
QRegion m_obscuredRegion;
+ bool m_isOpaque = false;
QSGSoftwareRenderableNodeUpdater *m_nodeUpdater;
};
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp
index 92c02b4966..a8b5944974 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp
@@ -87,6 +87,6 @@ QSGRenderLoop *QSGSoftwareAdaptation::createWindowManager()
return new QSGSoftwareRenderLoop();
}
-QSGSoftwareContext *QSGSoftwareAdaptation::instance = 0;
+QSGSoftwareContext *QSGSoftwareAdaptation::instance = nullptr;
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation_p.h
index ffe54b5d4b..8b2a545033 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation_p.h
@@ -62,7 +62,7 @@ class QSGSoftwareContext;
class QSGSoftwareAdaptation : public QSGContextPlugin
{
public:
- QSGSoftwareAdaptation(QObject *parent = 0);
+ QSGSoftwareAdaptation(QObject *parent = nullptr);
QStringList keys() const override;
QSGContext *create(const QString &key) const override;
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
index aa850a80db..5b5bf005d8 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
@@ -205,12 +205,12 @@ QSGRendererInterface::ShaderType QSGSoftwareContext::shaderType() const
QSGRendererInterface::ShaderCompilationTypes QSGSoftwareContext::shaderCompilationType() const
{
- return 0;
+ return nullptr;
}
QSGRendererInterface::ShaderSourceTypes QSGSoftwareContext::shaderSourceType() const
{
- return 0;
+ return nullptr;
}
void *QSGSoftwareContext::getResource(QQuickWindow *window, Resource resource) const
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp
index 10291b9cb5..3b0f3c48ff 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp
@@ -318,7 +318,7 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin
QSGSoftwareInternalImageNode::QSGSoftwareInternalImageNode()
: m_innerSourceRect(0, 0, 1, 1)
, m_subSourceRect(0, 0, 1, 1)
- , m_texture(0)
+ , m_texture(nullptr)
, m_mirror(false)
, m_smooth(true)
, m_tileHorizontal(false)
@@ -462,7 +462,7 @@ void QSGSoftwareInternalImageNode::paint(QPainter *painter)
m_targetRect.right() - m_innerTargetRect.right(), m_targetRect.bottom() - m_innerTargetRect.bottom());
QSGSoftwareHelpers::QTileRules tilerules(getTileRule(m_subSourceRect.width()), getTileRule(m_subSourceRect.height()));
QSGSoftwareHelpers::qDrawBorderPixmap(painter, m_targetRect.toRect(), margins, pm, QRect(0, 0, pm.width(), pm.height()),
- margins, tilerules, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints(0));
+ margins, tilerules, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints(nullptr));
return;
}
@@ -490,12 +490,13 @@ QRectF QSGSoftwareInternalImageNode::rect() const
const QPixmap &QSGSoftwareInternalImageNode::pixmap() const
{
- if (QSGSoftwarePixmapTexture *pt = qobject_cast<QSGSoftwarePixmapTexture*>(m_texture)) {
+ if (QSGSoftwarePixmapTexture *pt = qobject_cast<QSGSoftwarePixmapTexture*>(m_texture))
return pt->pixmap();
- } else {
- QSGSoftwareLayer *layer = qobject_cast<QSGSoftwareLayer*>(m_texture);
+ if (QSGSoftwareLayer *layer = qobject_cast<QSGSoftwareLayer*>(m_texture))
return layer->pixmap();
- }
+ Q_ASSERT(m_texture == nullptr);
+ static const QPixmap nullPixmap;
+ return nullPixmap;
}
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode_p.h
index f21667fdf7..5c95eb064a 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode_p.h
@@ -124,8 +124,8 @@ public:
QRectF rect() const;
-private:
const QPixmap &pixmap() const;
+private:
QRectF m_targetRect;
QRectF m_innerTargetRect;
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp
index f6898b3879..bf3141bc32 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp
@@ -227,8 +227,8 @@ void QSGSoftwareInternalRectangleNode::paint(QPainter *painter)
{
//We can only check for a device pixel ratio change when we know what
//paint device is being used.
- if (painter->device()->devicePixelRatio() != m_devicePixelRatio) {
- m_devicePixelRatio = painter->device()->devicePixelRatio();
+ if (!qFuzzyCompare(painter->device()->devicePixelRatioF(), m_devicePixelRatio)) {
+ m_devicePixelRatio = painter->device()->devicePixelRatioF();
generateCornerPixmap();
}
@@ -245,7 +245,7 @@ void QSGSoftwareInternalRectangleNode::paint(QPainter *painter)
} else {
//Rounded Rects and Rects with Borders
//Avoids broken behaviors of QPainter::drawRect/roundedRect
- QPixmap pixmap = QPixmap(m_rect.width() * m_devicePixelRatio, m_rect.height() * m_devicePixelRatio);
+ QPixmap pixmap = QPixmap(qRound(m_rect.width() * m_devicePixelRatio), qRound(m_rect.height() * m_devicePixelRatio));
pixmap.fill(Qt::transparent);
pixmap.setDevicePixelRatio(m_devicePixelRatio);
QPainter pixmapPainter(&pixmap);
@@ -356,7 +356,7 @@ void QSGSoftwareInternalRectangleNode::paintRectangle(QPainter *painter, const Q
} else {
//blit 4 corners to border
- int scaledRadius = radius * m_devicePixelRatio;
+ int scaledRadius = qRound(radius * m_devicePixelRatio);
QRectF topLeftCorner(QPointF(rect.x(), rect.y()),
QPointF(rect.x() + radius, rect.y() + radius));
painter->drawPixmap(topLeftCorner, m_cornerPixmap, QRectF(0, 0, scaledRadius, scaledRadius));
@@ -416,7 +416,7 @@ void QSGSoftwareInternalRectangleNode::generateCornerPixmap()
//Generate new corner Pixmap
int radius = qFloor(qMin(qMin(m_rect.width(), m_rect.height()) * 0.5, m_radius));
- m_cornerPixmap = QPixmap(radius * 2 * m_devicePixelRatio, radius * 2 * m_devicePixelRatio);
+ m_cornerPixmap = QPixmap(qRound(radius * 2 * m_devicePixelRatio), qRound(radius * 2 * m_devicePixelRatio));
m_cornerPixmap.setDevicePixelRatio(m_devicePixelRatio);
m_cornerPixmap.fill(Qt::transparent);
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode_p.h
index f363e279e1..1f87424d2a 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode_p.h
@@ -95,7 +95,7 @@ private:
bool m_cornerPixmapIsDirty;
QPixmap m_cornerPixmap;
- int m_devicePixelRatio;
+ qreal m_devicePixelRatio;
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp
index bd5d8f72c0..b4301451d8 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp
@@ -45,9 +45,9 @@
QT_BEGIN_NAMESPACE
QSGSoftwareLayer::QSGSoftwareLayer(QSGRenderContext *renderContext)
- : m_item(0)
+ : m_item(nullptr)
, m_context(renderContext)
- , m_renderer(0)
+ , m_renderer(nullptr)
, m_device_pixel_ratio(1)
, m_mirrorHorizontal(false)
, m_mirrorVertical(true)
@@ -203,7 +203,7 @@ void QSGSoftwareLayer::markDirtyTexture()
void QSGSoftwareLayer::invalidated()
{
delete m_renderer;
- m_renderer = 0;
+ m_renderer = nullptr;
}
void QSGSoftwareLayer::grab()
@@ -229,9 +229,6 @@ void QSGSoftwareLayer::grab()
if (m_pixmap.size() != m_size) {
m_pixmap = QPixmap(m_size);
m_pixmap.setDevicePixelRatio(m_device_pixel_ratio);
- // This fill here is wasteful, but necessary because it is the only way
- // to force a QImage based pixmap to have an alpha channel.
- m_pixmap.fill(Qt::transparent);
}
// Render texture.
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepainternode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepainternode.cpp
index 34b0cd5b72..60ae06dd94 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepainternode.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepainternode.cpp
@@ -47,7 +47,7 @@ QSGSoftwarePainterNode::QSGSoftwarePainterNode(QQuickPaintedItem *item)
: QSGPainterNode()
, m_preferredRenderTarget(QQuickPaintedItem::Image)
, m_item(item)
- , m_texture(0)
+ , m_texture(nullptr)
, m_dirtyContents(false)
, m_opaquePainting(false)
, m_linear_filtering(false)
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp
index ad6cf39425..303f98c801 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp
@@ -79,16 +79,9 @@ void QSGSoftwarePixmapRenderer::render(QPaintDevice *target)
QElapsedTimer renderTimer;
// Setup background item
- setBackgroundSize(QSize(target->width(), target->height()));
+ setBackgroundRect(m_projectionRect);
setBackgroundColor(clearColor());
- QPainter painter(target);
- painter.setRenderHint(QPainter::Antialiasing);
- painter.setWindow(m_projectionRect);
- auto rc = static_cast<QSGSoftwareRenderContext *>(context());
- QPainter *prevPainter = rc->m_activePainter;
- rc->m_activePainter = &painter;
-
renderTimer.start();
buildRenderList();
qint64 buildRenderListTime = renderTimer.restart();
@@ -101,6 +94,19 @@ void QSGSoftwarePixmapRenderer::render(QPaintDevice *target)
optimizeRenderList();
qint64 optimizeRenderListTime = renderTimer.restart();
+ if (!isOpaque() && target->devType() == QInternal::Pixmap) {
+ // This fill here is wasteful, but necessary because it is the only way
+ // to force a QImage based pixmap to have an alpha channel.
+ static_cast<QPixmap *>(target)->fill(Qt::transparent);
+ }
+
+ QPainter painter(target);
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.setWindow(m_projectionRect);
+ auto rc = static_cast<QSGSoftwareRenderContext *>(context());
+ QPainter *prevPainter = rc->m_activePainter;
+ rc->m_activePainter = &painter;
+
QRegion paintedRegion = renderNodes(&painter);
qint64 renderTime = renderTimer.elapsed();
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp
index 77d21ec042..1463681fa3 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp
@@ -188,7 +188,7 @@ void QSGSoftwareNinePatchNode::paint(QPainter *painter)
painter->drawPixmap(m_bounds, m_pixmap, QRectF(0, 0, m_pixmap.width(), m_pixmap.height()));
else
QSGSoftwareHelpers::qDrawBorderPixmap(painter, m_bounds.toRect(), m_margins, m_pixmap, QRect(0, 0, m_pixmap.width(), m_pixmap.height()),
- m_margins, Qt::StretchTile, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints(0));
+ m_margins, Qt::StretchTile, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints(nullptr));
}
QRectF QSGSoftwareNinePatchNode::bounds() const
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes_p.h
index 9f1913205b..114137fb55 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes_p.h
@@ -133,6 +133,8 @@ public:
QRectF bounds() const;
+ bool isOpaque() const { return !m_pixmap.hasAlphaChannel(); }
+
private:
QPixmap m_pixmap;
QRectF m_bounds;
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp
index cecc6c21ca..7fb531cca3 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp
@@ -134,73 +134,58 @@ void QSGSoftwareRenderableNode::update()
{
// Update the Node properties
m_isDirty = true;
+ m_isOpaque = false;
QRectF boundingRect;
switch (m_nodeType) {
case QSGSoftwareRenderableNode::SimpleRect:
- if (m_handle.simpleRectNode->color().alpha() == 255 && !m_transform.isRotating())
+ if (m_handle.simpleRectNode->color().alpha() == 255)
m_isOpaque = true;
- else
- m_isOpaque = false;
boundingRect = m_handle.simpleRectNode->rect();
break;
case QSGSoftwareRenderableNode::SimpleTexture:
- if (!m_handle.simpleTextureNode->texture()->hasAlphaChannel() && !m_transform.isRotating())
+ if (!m_handle.simpleTextureNode->texture()->hasAlphaChannel())
m_isOpaque = true;
- else
- m_isOpaque = false;
boundingRect = m_handle.simpleTextureNode->rect();
break;
case QSGSoftwareRenderableNode::Image:
- // There isn't a way to tell, so assume it's not
- m_isOpaque = false;
+ m_isOpaque = !m_handle.imageNode->pixmap().hasAlphaChannel();
boundingRect = m_handle.imageNode->rect().toRect();
break;
case QSGSoftwareRenderableNode::Painter:
- if (m_handle.painterNode->opaquePainting() && !m_transform.isRotating())
+ if (m_handle.painterNode->opaquePainting())
m_isOpaque = true;
- else
- m_isOpaque = false;
boundingRect = QRectF(0, 0, m_handle.painterNode->size().width(), m_handle.painterNode->size().height());
break;
case QSGSoftwareRenderableNode::Rectangle:
- if (m_handle.rectangleNode->isOpaque() && !m_transform.isRotating())
+ if (m_handle.rectangleNode->isOpaque())
m_isOpaque = true;
- else
- m_isOpaque = false;
boundingRect = m_handle.rectangleNode->rect();
break;
case QSGSoftwareRenderableNode::Glyph:
// Always has alpha
- m_isOpaque = false;
-
boundingRect = m_handle.glpyhNode->boundingRect();
break;
case QSGSoftwareRenderableNode::NinePatch:
- // Difficult to tell, assume non-opaque
- m_isOpaque = false;
+ m_isOpaque = m_handle.ninePatchNode->isOpaque();
boundingRect = m_handle.ninePatchNode->bounds();
break;
case QSGSoftwareRenderableNode::SimpleRectangle:
- if (m_handle.simpleRectangleNode->color().alpha() == 255 && !m_transform.isRotating())
+ if (m_handle.simpleRectangleNode->color().alpha() == 255)
m_isOpaque = true;
- else
- m_isOpaque = false;
boundingRect = m_handle.simpleRectangleNode->rect();
break;
case QSGSoftwareRenderableNode::SimpleImage:
- if (!m_handle.simpleImageNode->texture()->hasAlphaChannel() && !m_transform.isRotating())
+ if (!m_handle.simpleImageNode->texture()->hasAlphaChannel())
m_isOpaque = true;
- else
- m_isOpaque = false;
boundingRect = m_handle.simpleImageNode->rect();
break;
@@ -211,10 +196,8 @@ void QSGSoftwareRenderableNode::update()
break;
#endif
case QSGSoftwareRenderableNode::RenderNode:
- if (m_handle.renderNode->flags().testFlag(QSGRenderNode::OpaqueRendering) && !m_transform.isRotating())
+ if (m_handle.renderNode->flags().testFlag(QSGRenderNode::OpaqueRendering))
m_isOpaque = true;
- else
- m_isOpaque = false;
boundingRect = m_handle.renderNode->rect();
break;
@@ -222,6 +205,9 @@ void QSGSoftwareRenderableNode::update()
break;
}
+ if (m_transform.isRotating())
+ m_isOpaque = false;
+
const QRectF transformedRect = m_transform.mapRect(boundingRect);
m_boundingRectMin = toRectMin(transformedRect);
m_boundingRectMax = toRectMax(transformedRect);
@@ -232,8 +218,9 @@ void QSGSoftwareRenderableNode::update()
m_boundingRectMin = QRect();
m_boundingRectMax = QRect();
} else {
- m_boundingRectMin = m_boundingRectMin.intersected(m_clipRegion.rects().constFirst());
- m_boundingRectMax = m_boundingRectMax.intersected(m_clipRegion.rects().constFirst());
+ const auto rects = m_clipRegion.begin();
+ m_boundingRectMin = m_boundingRectMin.intersected(rects[0]);
+ m_boundingRectMax = m_boundingRectMax.intersected(rects[0]);
}
}
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp
index 666f1d0616..fabecfcbb8 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp
@@ -83,7 +83,7 @@ void QSGSoftwareRenderableNodeUpdater::endVisit(QSGTransformNode *)
bool QSGSoftwareRenderableNodeUpdater::visit(QSGClipNode *node)
{
// Make sure to translate the clip rect into world coordinates
- if (m_clipState.count() == 0 || m_clipState.top().isNull()) {
+ if (m_clipState.count() == 0 || (m_clipState.count() == 1 && m_clipState.top().isNull())) {
m_clipState.push(m_transformState.top().map(QRegion(node->clipRect().toRect())));
m_hasClip = true;
} else {
@@ -97,7 +97,7 @@ bool QSGSoftwareRenderableNodeUpdater::visit(QSGClipNode *node)
void QSGSoftwareRenderableNodeUpdater::endVisit(QSGClipNode *)
{
m_clipState.pop();
- if (m_clipState.count() == 0 || m_clipState.top().isNull())
+ if (m_clipState.count() == 0 || (m_clipState.count() == 1 && m_clipState.top().isNull()))
m_hasClip = false;
}
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp
index 85d04fe136..ffcee5f56e 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp
@@ -112,7 +112,8 @@ void QSGSoftwareRenderer::render()
QElapsedTimer renderTimer;
setBackgroundColor(clearColor());
- setBackgroundSize(QSize(m_paintDevice->width() / m_paintDevice->devicePixelRatio(),
+ setBackgroundRect(QRect(0, 0,
+ m_paintDevice->width() / m_paintDevice->devicePixelRatio(),
m_paintDevice->height() / m_paintDevice->devicePixelRatio()));
// Build Renderlist
@@ -155,6 +156,7 @@ void QSGSoftwareRenderer::render()
m_flushRegion = renderNodes(&painter);
qint64 renderTime = renderTimer.elapsed();
+ painter.end();
if (m_backingStore != nullptr)
m_backingStore->endPaint();
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
index 3f0d1383b9..423f5f7321 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
@@ -97,7 +97,6 @@ void QSGSoftwareRenderLoop::windowDestroyed(QQuickWindow *window)
if (m_windows.size() == 0) {
rc->invalidate();
- QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
}
}
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
index 832b69d0cc..f8973af2fb 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
@@ -294,7 +294,7 @@ bool QSGSoftwareRenderThread::event(QEvent *e)
}
rc->invalidate();
QCoreApplication::processEvents();
- QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+ QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
if (wme->destroying)
delete wd->animationController;
}
@@ -456,7 +456,7 @@ void QSGSoftwareRenderThread::sync(bool inExpose)
// Process deferred deletes now, directly after the sync as deleteLater
// on the GUI must now also have resulted in SG changes and the delete
// is a safe operation.
- QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+ QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
}
if (!inExpose) {
@@ -523,7 +523,7 @@ void QSGSoftwareRenderThread::syncAndRender()
// rate of the current screen the window is on.
int blockTime = vsyncDelta - (int) renderThrottleTimer.elapsed();
if (blockTime > 0) {
- qCDebug(QSG_RASTER_LOG_RENDERLOOP) << "RT - blocking for " << blockTime << "ms";
+ qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - blocking for %d ms", blockTime);
msleep(blockTime);
}
renderThrottleTimer.restart();
diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp
new file mode 100644
index 0000000000..e868a4380e
--- /dev/null
+++ b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick 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$
+**
+****************************************************************************/
+
+#include "qsgcompressedatlastexture_p.h"
+
+#include <QtCore/QVarLengthArray>
+#include <QtCore/QElapsedTimer>
+#include <QtCore/QtMath>
+
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QScreen>
+#include <QtGui/QSurface>
+#include <QtGui/QWindow>
+#include <QtGui/QOpenGLFunctions>
+#include <QtGui/QOpenGLTexture>
+#include <QDebug>
+
+#include <private/qqmlglobal_p.h>
+#include <private/qquickprofiler_p.h>
+#include <private/qsgtexture_p.h>
+#include <private/qsgcompressedtexture_p.h>
+#include <private/qsgpkmhandler_p.h>
+
+QT_BEGIN_NAMESPACE
+
+static QElapsedTimer qsg_renderer_timer;
+
+namespace QSGCompressedAtlasTexture
+{
+
+Atlas::Atlas(const QSize &size, uint format)
+ : QSGAtlasTexture::AtlasBase(size)
+ , m_format(format)
+{
+}
+
+Atlas::~Atlas()
+{
+}
+
+Texture *Atlas::create(const QByteArray &data, int dataLength, int dataOffset, const QSize &size, const QSize &paddedSize)
+{
+ // No need to lock, as manager already locked it.
+ QRect rect = m_allocator.allocate(paddedSize);
+ if (rect.width() > 0 && rect.height() > 0) {
+ Texture *t = new Texture(this, rect, data, dataLength, dataOffset, size);
+ m_pending_uploads << t;
+ return t;
+ }
+ return nullptr;
+}
+
+void Atlas::generateTexture()
+{
+ QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
+ funcs->glCompressedTexImage2D(GL_TEXTURE_2D, 0, m_format,
+ m_size.width(), m_size.height(), 0,
+ (m_size.width() * m_size.height()) / 2,
+ nullptr);
+}
+
+void Atlas::uploadPendingTexture(int i)
+{
+ Texture *texture = static_cast<Texture*>(m_pending_uploads.at(i));
+
+ const QRect &r = texture->atlasSubRect();
+
+ QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
+ funcs->glCompressedTexSubImage2D(GL_TEXTURE_2D, 0,
+ r.x(), r.y(), r.width(), r.height(), m_format,
+ texture->sizeInBytes(),
+ texture->data().constData() + texture->dataOffset());
+
+ qCDebug(QSG_LOG_TIME_TEXTURE).nospace() << "compressed atlastexture uploaded in: " << qsg_renderer_timer.elapsed()
+ << "ms (" << texture->textureSize().width() << "x"
+ << texture->textureSize().height() << ")";
+
+ // TODO: consider releasing the data (as is done in the regular atlas)?
+ // The advantage of keeping this data around is that it makes it much easier
+ // to remove the texture from the atlas
+}
+
+Texture::Texture(Atlas *atlas, const QRect &textureRect, const QByteArray &data, int dataLength, int dataOffset, const QSize &size)
+ : QSGAtlasTexture::TextureBase(atlas, textureRect)
+ , m_nonatlas_texture(nullptr)
+ , m_data(data)
+ , m_size(size)
+ , m_dataLength(dataLength)
+ , m_dataOffset(dataOffset)
+{
+ float w = atlas->size().width();
+ float h = atlas->size().height();
+ QRect nopad = atlasSubRect();
+ // offset by half-pixel to prevent bleeding when scaling
+ m_texture_coords_rect = QRectF((nopad.x() + .5) / w,
+ (nopad.y() + .5) / h,
+ (nopad.width() - 1.) / w,
+ (nopad.height() - 1.) / h);
+}
+
+Texture::~Texture()
+{
+ delete m_nonatlas_texture;
+}
+
+bool Texture::hasAlphaChannel() const
+{
+ return QSGCompressedTexture::formatIsOpaque(static_cast<Atlas*>(m_atlas)->format());
+}
+
+QSGTexture *Texture::removedFromAtlas() const
+{
+ if (m_nonatlas_texture) {
+ m_nonatlas_texture->setMipmapFiltering(mipmapFiltering());
+ m_nonatlas_texture->setFiltering(filtering());
+ return m_nonatlas_texture;
+ }
+
+ if (!m_data.isEmpty()) {
+ QSGCompressedTexture::DataPtr texData(QSGCompressedTexture::DataPtr::create());
+ texData->data = m_data;
+ texData->size = m_size;
+ texData->format = static_cast<Atlas*>(m_atlas)->format();
+ texData->hasAlpha = hasAlphaChannel();
+ texData->dataLength = m_dataLength;
+ texData->dataOffset = m_dataOffset;
+ m_nonatlas_texture = new QSGCompressedTexture(texData);
+ m_nonatlas_texture->setMipmapFiltering(mipmapFiltering());
+ m_nonatlas_texture->setFiltering(filtering());
+ }
+
+ return m_nonatlas_texture;
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h
new file mode 100644
index 0000000000..59e935b623
--- /dev/null
+++ b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick 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 QSGCOMPRESSEDATLASTEXTURE_P_H
+#define QSGCOMPRESSEDATLASTEXTURE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/QSize>
+
+#include <QtGui/qopengl.h>
+
+#include <QtQuick/QSGTexture>
+#include <QtQuick/private/qsgareaallocator_p.h>
+#include <QtQuick/private/qsgatlastexture_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSGCompressedTextureFactory;
+
+namespace QSGCompressedAtlasTexture {
+
+class Texture;
+
+class Atlas : public QSGAtlasTexture::AtlasBase
+{
+public:
+ Atlas(const QSize &size, uint format);
+ ~Atlas();
+
+ void generateTexture() override;
+ void uploadPendingTexture(int i) override;
+
+ Texture *create(const QByteArray &data, int dataLength, int dataOffset, const QSize &size, const QSize &paddedSize);
+
+ uint format() const { return m_format; }
+
+private:
+ uint m_format;
+};
+
+class Texture : public QSGAtlasTexture::TextureBase
+{
+ Q_OBJECT
+public:
+ Texture(Atlas *atlas, const QRect &textureRect, const QByteArray &data, int dataLength, int dataOffset, const QSize &size);
+ ~Texture();
+
+ QSize textureSize() const override { return m_size; }
+ bool hasAlphaChannel() const override;
+ bool hasMipmaps() const override { return false; }
+
+ QRectF normalizedTextureSubRect() const override { return m_texture_coords_rect; }
+
+ QSGTexture *removedFromAtlas() const override;
+
+ const QByteArray &data() const { return m_data; }
+ int sizeInBytes() const { return m_dataLength; }
+ int dataOffset() const { return m_dataOffset; }
+
+private:
+ QRectF m_texture_coords_rect;
+ mutable QSGTexture *m_nonatlas_texture;
+ QByteArray m_data;
+ QSize m_size;
+ int m_dataLength;
+ int m_dataOffset;
+};
+
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp
new file mode 100644
index 0000000000..839c562989
--- /dev/null
+++ b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp
@@ -0,0 +1,246 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick 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$
+**
+****************************************************************************/
+
+
+#include "qsgcompressedtexture_p.h"
+#include <QOpenGLContext>
+#include <QOpenGLTexture>
+#include <QOpenGLFunctions>
+#include <QDebug>
+#include <QtQuick/private/qquickwindow_p.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(QSG_LOG_TEXTUREIO, "qt.scenegraph.textureio");
+
+bool QSGCompressedTextureData::isValid() const
+{
+ if (data.isNull() || size.isEmpty() || !format)
+ return false;
+ if (dataLength < 0 || dataOffset < 0 || dataOffset >= data.length())
+ return false;
+ if (dataLength > 0 && qint64(dataOffset) + qint64(dataLength) > qint64(data.length()))
+ return false;
+
+ return true;
+}
+
+int QSGCompressedTextureData::sizeInBytes() const
+{
+ if (!isValid())
+ return 0;
+ return dataLength > 0 ? dataLength : data.length() - dataOffset;
+}
+
+Q_QUICK_PRIVATE_EXPORT QDebug operator<<(QDebug dbg, const QSGCompressedTextureData *d)
+{
+ QDebugStateSaver saver(dbg);
+
+ dbg.nospace() << "QSGCompressedTextureData(";
+ if (d) {
+ dbg << d->logName << ' ';
+ dbg << static_cast<QOpenGLTexture::TextureFormat>(d->format)
+ << "[0x" << hex << d->format << dec << "]";
+ dbg.space() << (d->hasAlpha ? "with" : "no") << "alpha" << d->size
+ << "databuffer" << d->data.size() << "offset" << d->dataOffset << "length";
+ dbg.nospace() << d->dataLength << ")";
+ } else {
+ dbg << "null)";
+ }
+ return dbg;
+}
+
+QSGCompressedTexture::QSGCompressedTexture(const DataPtr& texData)
+ : m_textureData(texData)
+{
+ if (m_textureData) {
+ m_size = m_textureData->size;
+ m_hasAlpha = m_textureData->hasAlpha;
+ }
+}
+
+QSGCompressedTexture::~QSGCompressedTexture()
+{
+#if QT_CONFIG(opengl)
+ if (m_textureId) {
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ QOpenGLFunctions *funcs = ctx ? ctx->functions() : nullptr;
+ if (!funcs)
+ return;
+
+ funcs->glDeleteTextures(1, &m_textureId);
+ }
+#endif
+}
+
+int QSGCompressedTexture::textureId() const
+{
+#if QT_CONFIG(opengl)
+ if (!m_textureId) {
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ QOpenGLFunctions *funcs = ctx ? ctx->functions() : nullptr;
+ if (!funcs)
+ return 0;
+
+ funcs->glGenTextures(1, &m_textureId);
+ }
+#endif
+ return m_textureId;
+}
+
+QSize QSGCompressedTexture::textureSize() const
+{
+ return m_size;
+}
+
+bool QSGCompressedTexture::hasAlphaChannel() const
+{
+ return m_hasAlpha;
+}
+
+bool QSGCompressedTexture::hasMipmaps() const
+{
+ return false;
+}
+
+void QSGCompressedTexture::bind()
+{
+#if QT_CONFIG(opengl)
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ QOpenGLFunctions *funcs = ctx ? ctx->functions() : nullptr;
+ if (!funcs)
+ return;
+
+ if (!textureId())
+ return;
+
+ funcs->glBindTexture(GL_TEXTURE_2D, m_textureId);
+
+ if (m_uploaded)
+ return;
+
+ QByteArray logName(m_textureData ? m_textureData->logName : QByteArrayLiteral("(unset)"));
+
+ if (!m_textureData || !m_textureData->isValid()) {
+ qCDebug(QSG_LOG_TEXTUREIO, "Invalid texture data for %s", logName.constData());
+ funcs->glBindTexture(GL_TEXTURE_2D, 0);
+ return;
+ }
+
+ if (Q_UNLIKELY(QSG_LOG_TEXTUREIO().isDebugEnabled())) {
+ qCDebug(QSG_LOG_TEXTUREIO) << "Uploading texture" << m_textureData.data();
+ while (funcs->glGetError() != GL_NO_ERROR);
+ }
+
+ funcs->glCompressedTexImage2D(GL_TEXTURE_2D, 0, m_textureData->format,
+ m_size.width(), m_size.height(), 0, m_textureData->sizeInBytes(),
+ m_textureData->data.constData() + m_textureData->dataOffset);
+
+ if (Q_UNLIKELY(QSG_LOG_TEXTUREIO().isDebugEnabled())) {
+ GLuint error = funcs->glGetError();
+ if (error != GL_NO_ERROR) {
+ qCDebug(QSG_LOG_TEXTUREIO, "glCompressedTexImage2D failed for %s, error 0x%x", logName.constData(), error);
+ }
+ }
+
+ m_textureData.clear(); // Release this memory, not needed anymore
+
+ updateBindOptions(true);
+ m_uploaded = true;
+#endif // QT_CONFIG(opengl)
+}
+
+bool QSGCompressedTexture::formatIsOpaque(quint32 glTextureFormat)
+{
+ switch (glTextureFormat) {
+ case QOpenGLTexture::RGB_DXT1:
+ case QOpenGLTexture::R_ATI1N_UNorm:
+ case QOpenGLTexture::R_ATI1N_SNorm:
+ case QOpenGLTexture::RG_ATI2N_UNorm:
+ case QOpenGLTexture::RG_ATI2N_SNorm:
+ case QOpenGLTexture::RGB_BP_UNSIGNED_FLOAT:
+ case QOpenGLTexture::RGB_BP_SIGNED_FLOAT:
+ case QOpenGLTexture::R11_EAC_UNorm:
+ case QOpenGLTexture::R11_EAC_SNorm:
+ case QOpenGLTexture::RG11_EAC_UNorm:
+ case QOpenGLTexture::RG11_EAC_SNorm:
+ case QOpenGLTexture::RGB8_ETC2:
+ case QOpenGLTexture::SRGB8_ETC2:
+ case QOpenGLTexture::RGB8_ETC1:
+ case QOpenGLTexture::SRGB_DXT1:
+ return true;
+ break;
+ default:
+ return false;
+ }
+}
+
+QSGCompressedTextureFactory::QSGCompressedTextureFactory(const QSGCompressedTexture::DataPtr &texData)
+ : m_textureData(texData)
+{
+}
+
+QSGTexture *QSGCompressedTextureFactory::createTexture(QQuickWindow *window) const
+{
+ if (!m_textureData || !m_textureData->isValid())
+ return nullptr;
+
+ // attempt to atlas the texture
+ QSGRenderContext *context = QQuickWindowPrivate::get(window)->context;
+ QSGTexture *t = context->compressedTextureForFactory(this);
+ if (t)
+ return t;
+
+ return new QSGCompressedTexture(m_textureData);
+}
+
+int QSGCompressedTextureFactory::textureByteCount() const
+{
+ return m_textureData ? m_textureData->sizeInBytes() : 0;
+}
+
+
+QSize QSGCompressedTextureFactory::textureSize() const
+{
+ if (m_textureData && m_textureData->isValid())
+ return m_textureData->size;
+ return QSize();
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture_p.h b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture_p.h
new file mode 100644
index 0000000000..aa87316809
--- /dev/null
+++ b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture_p.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick 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 QSGCOMPRESSEDTEXTURE_P_H
+#define QSGCOMPRESSEDTEXTURE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QSGTexture>
+#include <QtQuick/private/qsgcontext_p.h>
+#include <QQuickTextureFactory>
+#include <QOpenGLFunctions>
+
+QT_BEGIN_NAMESPACE
+
+struct Q_QUICK_PRIVATE_EXPORT QSGCompressedTextureData
+{
+ QByteArray logName;
+ QByteArray data;
+ QSize size;
+ uint format = 0;
+ int dataOffset = 0;
+ int dataLength = 0;
+ bool hasAlpha = false;
+
+ bool isValid() const;
+ int sizeInBytes() const;
+};
+
+Q_QUICK_PRIVATE_EXPORT QDebug operator<<(QDebug, const QSGCompressedTextureData *);
+
+
+class Q_QUICK_PRIVATE_EXPORT QSGCompressedTexture : public QSGTexture
+{
+ Q_OBJECT
+public:
+ typedef QSharedPointer<QSGCompressedTextureData> DataPtr;
+
+ QSGCompressedTexture(const DataPtr& texData);
+ virtual ~QSGCompressedTexture();
+
+ int textureId() const override;
+ QSize textureSize() const override;
+ bool hasAlphaChannel() const override;
+ bool hasMipmaps() const override;
+
+ void bind() override;
+
+ const QSGCompressedTextureData *textureData();
+
+ static bool formatIsOpaque(quint32 glTextureFormat);
+
+protected:
+ DataPtr m_textureData;
+ QSize m_size;
+ mutable uint m_textureId = 0;
+ bool m_hasAlpha = false;
+ bool m_uploaded = false;
+};
+
+namespace QSGAtlasTexture {
+ class Manager;
+}
+
+class Q_QUICK_PRIVATE_EXPORT QSGCompressedTextureFactory : public QQuickTextureFactory
+{
+public:
+ QSGCompressedTextureFactory(const QSGCompressedTexture::DataPtr& texData);
+ QSGTexture *createTexture(QQuickWindow *) const override;
+ int textureByteCount() const override;
+ QSize textureSize() const override;
+
+protected:
+ QSGCompressedTexture::DataPtr m_textureData;
+private:
+ friend class QSGAtlasTexture::Manager;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGCOMPRESSEDTEXTURE_P_H
diff --git a/src/quick/scenegraph/compressedtexture/qsgktxhandler.cpp b/src/quick/scenegraph/compressedtexture/qsgktxhandler.cpp
new file mode 100644
index 0000000000..e3e4ca6824
--- /dev/null
+++ b/src/quick/scenegraph/compressedtexture/qsgktxhandler.cpp
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick 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$
+**
+****************************************************************************/
+
+#include "qsgktxhandler_p.h"
+#include "qsgcompressedtexture_p.h"
+#include <QOpenGLTexture>
+#include <QtEndian>
+
+//#define KTX_DEBUG
+
+QT_BEGIN_NAMESPACE
+
+#define KTX_IDENTIFIER_LENGTH 12
+static const char ktxIdentifier[KTX_IDENTIFIER_LENGTH] = { '\xAB', 'K', 'T', 'X', ' ', '1', '1', '\xBB', '\r', '\n', '\x1A', '\n' };
+static const quint32 platformEndianIdentifier = 0x04030201;
+static const quint32 inversePlatformEndianIdentifier = 0x01020304;
+
+struct KTXHeader {
+ quint8 identifier[KTX_IDENTIFIER_LENGTH]; //Must match ktxIdentifier
+ quint32 endianness; //Either platformEndianIdentifier or inversePlatformEndianIdentifier, other values not allowed.
+ quint32 glType;
+ quint32 glTypeSize;
+ quint32 glFormat;
+ quint32 glInternalFormat;
+ quint32 glBaseInternalFormat;
+ quint32 pixelWidth;
+ quint32 pixelHeight;
+ quint32 pixelDepth;
+ quint32 numberOfArrayElements;
+ quint32 numberOfFaces;
+ quint32 numberOfMipmapLevels;
+ quint32 bytesOfKeyValueData;
+};
+
+static const int headerSize = sizeof(KTXHeader);
+
+// Currently unused, declared for future reference
+struct KTXKeyValuePairItem {
+ quint32 keyAndValueByteSize;
+ /*
+ quint8 keyAndValue[keyAndValueByteSize];
+ quint8 valuePadding[3 - ((keyAndValueByteSize + 3) % 4)];
+ */
+};
+
+struct KTXMipmapLevel {
+ quint32 imageSize;
+ /*
+ for each array_element in numberOfArrayElements*
+ for each face in numberOfFaces
+ for each z_slice in pixelDepth*
+ for each row or row_of_blocks in pixelHeight*
+ for each pixel or block_of_pixels in pixelWidth
+ Byte data[format-specific-number-of-bytes]**
+ end
+ end
+ end
+ Byte cubePadding[0-3]
+ end
+ end
+ quint8 mipPadding[3 - ((imageSize + 3) % 4)]
+ */
+};
+
+bool QSGKtxHandler::canRead(const QByteArray &suffix, const QByteArray &block)
+{
+ Q_UNUSED(suffix)
+
+ return (qstrncmp(block.constData(), ktxIdentifier, KTX_IDENTIFIER_LENGTH) == 0);
+}
+
+QQuickTextureFactory *QSGKtxHandler::read()
+{
+ if (!device())
+ return nullptr;
+
+ QByteArray buf = device()->readAll();
+ if (buf.size() < headerSize || !canRead(QByteArray(), buf)) {
+ qCDebug(QSG_LOG_TEXTUREIO, "Invalid KTX file %s", logName().constData());
+ return nullptr;
+ }
+
+ const KTXHeader *header = reinterpret_cast<const KTXHeader *>(buf.constData());
+ if (!checkHeader(*header)) {
+ qCDebug(QSG_LOG_TEXTUREIO, "Unsupported KTX file format in %s", logName().constData());
+ return nullptr;
+ }
+
+ QSGCompressedTexture::DataPtr texData(QSGCompressedTexture::DataPtr::create());
+
+ texData->size = QSize(decode(header->pixelWidth), decode(header->pixelHeight));
+ texData->format = decode(header->glInternalFormat);
+ texData->hasAlpha = !QSGCompressedTexture::formatIsOpaque(texData->format);
+
+ // For now, ignore any additional mipmap levels
+ int preambleSize = headerSize + decode(header->bytesOfKeyValueData);
+ if (buf.size() >= preambleSize + int(sizeof(KTXMipmapLevel))) {
+ texData->data = buf;
+ texData->dataOffset = preambleSize + sizeof(quint32); // for the imageSize
+ const KTXMipmapLevel *level = reinterpret_cast<const KTXMipmapLevel *>(buf.constData() + preambleSize);
+ texData->dataLength = decode(level->imageSize);
+ }
+
+ if (!texData->isValid()) {
+ qCDebug(QSG_LOG_TEXTUREIO, "Invalid values in header of KTX file %s", logName().constData());
+ return nullptr;
+ }
+
+ texData->logName = logName();
+#ifdef KTX_DEBUG
+ qDebug() << "KTX file handler read" << texData.data();
+#endif
+
+ return new QSGCompressedTextureFactory(texData);
+}
+
+bool QSGKtxHandler::checkHeader(const KTXHeader &header)
+{
+ if (header.endianness != platformEndianIdentifier && header.endianness != inversePlatformEndianIdentifier)
+ return false;
+ inverseEndian = (header.endianness == inversePlatformEndianIdentifier);
+#ifdef KTX_DEBUG
+ QMetaEnum tfme = QMetaEnum::fromType<QOpenGLTexture::TextureFormat>();
+ QMetaEnum ptme = QMetaEnum::fromType<QOpenGLTexture::PixelType>();
+ qDebug("Header of %s:", logName().constData());
+ qDebug(" glType: 0x%x (%s)", decode(header.glType), ptme.valueToKey(decode(header.glType)));
+ qDebug(" glTypeSize: %u", decode(header.glTypeSize));
+ qDebug(" glFormat: 0x%x (%s)", decode(header.glFormat), tfme.valueToKey(decode(header.glFormat)));
+ qDebug(" glInternalFormat: 0x%x (%s)", decode(header.glInternalFormat), tfme.valueToKey(decode(header.glInternalFormat)));
+ qDebug(" glBaseInternalFormat: 0x%x (%s)", decode(header.glBaseInternalFormat), tfme.valueToKey(decode(header.glBaseInternalFormat)));
+ qDebug(" pixelWidth: %u", decode(header.pixelWidth));
+ qDebug(" pixelHeight: %u", decode(header.pixelHeight));
+ qDebug(" pixelDepth: %u", decode(header.pixelDepth));
+ qDebug(" numberOfArrayElements: %u", decode(header.numberOfArrayElements));
+ qDebug(" numberOfFaces: %u", decode(header.numberOfFaces));
+ qDebug(" numberOfMipmapLevels: %u", decode(header.numberOfMipmapLevels));
+ qDebug(" bytesOfKeyValueData: %u", decode(header.bytesOfKeyValueData));
+#endif
+ return ((decode(header.glType) == 0) &&
+ (decode(header.glFormat) == 0) &&
+ (decode(header.pixelDepth) == 0) &&
+ (decode(header.numberOfFaces) == 1));
+}
+
+quint32 QSGKtxHandler::decode(quint32 val)
+{
+ return inverseEndian ? qbswap<quint32>(val) : val;
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/compressedtexture/qsgktxhandler_p.h b/src/quick/scenegraph/compressedtexture/qsgktxhandler_p.h
new file mode 100644
index 0000000000..22f4db65b2
--- /dev/null
+++ b/src/quick/scenegraph/compressedtexture/qsgktxhandler_p.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick 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 QSGKTXHANDLER_H
+#define QSGKTXHANDLER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qsgtexturefilehandler_p.h"
+
+QT_BEGIN_NAMESPACE
+
+struct KTXHeader;
+
+class QSGKtxHandler : public QSGTextureFileHandler
+{
+public:
+ using QSGTextureFileHandler::QSGTextureFileHandler;
+
+ static bool canRead(const QByteArray &suffix, const QByteArray &block);
+
+ QQuickTextureFactory *read() override;
+
+private:
+ bool checkHeader(const KTXHeader &header);
+ quint32 decode(quint32 val);
+
+ bool inverseEndian = false;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGKTXHANDLER_H
diff --git a/src/quick/scenegraph/compressedtexture/qsgpkmhandler.cpp b/src/quick/scenegraph/compressedtexture/qsgpkmhandler.cpp
index bb8fce046d..618c0db045 100644
--- a/src/quick/scenegraph/compressedtexture/qsgpkmhandler.cpp
+++ b/src/quick/scenegraph/compressedtexture/qsgpkmhandler.cpp
@@ -38,172 +38,81 @@
****************************************************************************/
#include "qsgpkmhandler_p.h"
+#include "qsgcompressedtexture_p.h"
#include <QFile>
#include <QDebug>
#include <qendian.h>
#include <qopenglfunctions.h>
#include <qqmlfile.h>
+#include <QOpenGLTexture>
//#define ETC_DEBUG
-#ifndef GL_ETC1_RGB8_OES
- #define GL_ETC1_RGB8_OES 0x8d64
-#endif
-
-#ifndef GL_COMPRESSED_RGB8_ETC2
- #define GL_COMPRESSED_RGB8_ETC2 0x9274
-#endif
-
-#ifndef GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
- #define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
-#endif
-
-#ifndef GL_COMPRESSED_RGBA8_ETC2_EAC
- #define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
-#endif
-
QT_BEGIN_NAMESPACE
static const int headerSize = 16;
static unsigned int typeMap[5] = {
- GL_ETC1_RGB8_OES,
- GL_COMPRESSED_RGB8_ETC2,
- 0, // unused
- GL_COMPRESSED_RGBA8_ETC2_EAC,
- GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
+ QOpenGLTexture::RGB8_ETC1, // GL_ETC1_RGB8_OES,
+ QOpenGLTexture::RGB8_ETC2, // GL_COMPRESSED_RGB8_ETC2,
+ 0, // unused (obsolete)
+ QOpenGLTexture::RGBA8_ETC2_EAC, // GL_COMPRESSED_RGBA8_ETC2_EAC,
+ QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2 // GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
};
-QEtcTexture::QEtcTexture()
- : m_texture_id(0), m_uploaded(false)
-{
- initializeOpenGLFunctions();
-}
-
-QEtcTexture::~QEtcTexture()
-{
- if (m_texture_id)
- glDeleteTextures(1, &m_texture_id);
-}
-
-int QEtcTexture::textureId() const
-{
- if (m_texture_id == 0) {
- QEtcTexture *texture = const_cast<QEtcTexture*>(this);
- texture->glGenTextures(1, &texture->m_texture_id);
- }
- return m_texture_id;
-}
-
-bool QEtcTexture::hasAlphaChannel() const
-{
- return m_type == GL_COMPRESSED_RGBA8_ETC2_EAC ||
- m_type == GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
-}
-
-
-void QEtcTexture::bind()
+bool QSGPkmHandler::canRead(const QByteArray &suffix, const QByteArray &block)
{
- if (m_uploaded && m_texture_id) {
- glBindTexture(GL_TEXTURE_2D, m_texture_id);
- return;
- }
-
- if (m_texture_id == 0)
- glGenTextures(1, &m_texture_id);
- glBindTexture(GL_TEXTURE_2D, m_texture_id);
-
-#ifdef ETC_DEBUG
- qDebug() << "glCompressedTexImage2D, width: " << m_size.width() << "height" << m_size.height() <<
- "paddedWidth: " << m_paddedSize.width() << "paddedHeight: " << m_paddedSize.height();
-#endif
+ Q_UNUSED(suffix)
-#ifndef QT_NO_DEBUG
- while (glGetError() != GL_NO_ERROR) { }
-#endif
-
- QOpenGLContext *ctx = QOpenGLContext::currentContext();
- Q_ASSERT(ctx != 0);
- ctx->functions()->glCompressedTexImage2D(GL_TEXTURE_2D, 0, m_type,
- m_size.width(), m_size.height(), 0,
- (m_paddedSize.width() * m_paddedSize.height()) / 2,
- m_data.data() + headerSize);
-
-#ifndef QT_NO_DEBUG
- // Gracefully fail in case of an error...
- GLuint error = glGetError();
- if (error != GL_NO_ERROR) {
- qDebug () << "glCompressedTexImage2D for compressed texture failed, error: " << error;
- glBindTexture(GL_TEXTURE_2D, 0);
- glDeleteTextures(1, &m_texture_id);
- m_texture_id = 0;
- return;
- }
-#endif
-
- m_uploaded = true;
- updateBindOptions(true);
+ return block.startsWith("PKM ");
}
-class QEtcTextureFactory : public QQuickTextureFactory
-{
-public:
- QByteArray m_data;
- QSize m_size;
- QSize m_paddedSize;
- unsigned int m_type;
-
- QSize textureSize() const { return m_size; }
- int textureByteCount() const { return m_data.size(); }
-
- QSGTexture *createTexture(QQuickWindow *) const {
- QEtcTexture *texture = new QEtcTexture;
- texture->m_data = m_data;
- texture->m_size = m_size;
- texture->m_paddedSize = m_paddedSize;
- texture->m_type = m_type;
- return texture;
- }
-};
-
-QQuickTextureFactory *QSGPkmHandler::read(QIODevice *device)
+QQuickTextureFactory *QSGPkmHandler::read()
{
- QScopedPointer<QEtcTextureFactory> ret(new QEtcTextureFactory);
- ret->m_data = device->readAll();
- if (ret->m_data.isEmpty() || ret->m_data.size() < headerSize)
+ if (!device())
return nullptr;
- const char *rawData = ret->m_data.constData();
+ QSGCompressedTexture::DataPtr texData(QSGCompressedTexture::DataPtr::create());
- // magic number
- if (qstrncmp(rawData, "PKM ", 4) != 0)
+ texData->data = device()->readAll();
+ if (texData->data.size() < headerSize || !canRead(QByteArray(), texData->data)) {
+ qCDebug(QSG_LOG_TEXTUREIO, "Invalid PKM file %s", logName().constData());
return nullptr;
+ }
+
+ const char *rawData = texData->data.constData();
- // currently ignore version (rawData + 4)
+ // ignore version (rawData + 4 & 5)
// texture type
quint16 type = qFromBigEndian<quint16>(rawData + 6);
- static int typeCount = sizeof(typeMap)/sizeof(typeMap[0]);
- if (type >= typeCount)
+ if (type > sizeof(typeMap)/sizeof(typeMap[0])) {
+ qCDebug(QSG_LOG_TEXTUREIO, "Unknown compression format in PKM file %s", logName().constData());
return nullptr;
- ret->m_type = typeMap[type];
+ }
+ texData->format = typeMap[type];
+ texData->hasAlpha = !QSGCompressedTexture::formatIsOpaque(texData->format);
// texture size
- ret->m_paddedSize.setWidth(qFromBigEndian<quint16>(rawData + 8));
- ret->m_paddedSize.setHeight(qFromBigEndian<quint16>(rawData + 10));
- if ((ret->m_paddedSize.width() * ret->m_paddedSize.height()) / 2 > ret->m_data.size() - headerSize)
- return nullptr;
- ret->m_size.setWidth(qFromBigEndian<quint16>(rawData + 12));
- ret->m_size.setHeight(qFromBigEndian<quint16>(rawData + 14));
- if (ret->m_size.isEmpty())
+ const int bpb = (texData->format == QOpenGLTexture::RGBA8_ETC2_EAC) ? 16 : 8;
+ QSize paddedSize(qFromBigEndian<quint16>(rawData + 8), qFromBigEndian<quint16>(rawData + 10));
+ texData->dataLength = (paddedSize.width() / 4) * (paddedSize.height() / 4) * bpb;
+ QSize texSize(qFromBigEndian<quint16>(rawData + 12), qFromBigEndian<quint16>(rawData + 14));
+ texData->size = texSize;
+
+ texData->dataOffset = headerSize;
+
+ if (!texData->isValid()) {
+ qCDebug(QSG_LOG_TEXTUREIO, "Invalid values in header of PKM file %s", logName().constData());
return nullptr;
+ }
+ texData->logName = logName();
#ifdef ETC_DEBUG
- qDebug() << "requestTexture returning: " << ret->m_data.length() << "bytes; width: " << ret->m_size.width() << ", height: " << ret->m_size.height();
+ qDebug() << "PKM file handler read" << texData.data();
#endif
-
- return ret.take();
+ return new QSGCompressedTextureFactory(texData);
}
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/compressedtexture/qsgpkmhandler_p.h b/src/quick/scenegraph/compressedtexture/qsgpkmhandler_p.h
index eb6b2e46c0..6154c51b84 100644
--- a/src/quick/scenegraph/compressedtexture/qsgpkmhandler_p.h
+++ b/src/quick/scenegraph/compressedtexture/qsgpkmhandler_p.h
@@ -51,42 +51,18 @@
// We mean it.
//
-#include <QOpenGLFunctions>
-#include <QQuickImageProvider>
-#include <QtQuick/QSGTexture>
-#include <QUrl>
+#include "qsgtexturefilehandler_p.h"
QT_BEGIN_NAMESPACE
-class QSGPkmHandler
+class QSGPkmHandler : public QSGTextureFileHandler
{
public:
- QSGPkmHandler() {}
+ using QSGTextureFileHandler::QSGTextureFileHandler;
- QQuickTextureFactory *read(QIODevice *device);
-};
-
-class QEtcTexture : public QSGTexture, protected QOpenGLFunctions
-{
- Q_OBJECT
-public:
- QEtcTexture();
- ~QEtcTexture();
-
- void bind();
-
- QSize textureSize() const { return m_size; }
- int textureId() const;
-
- bool hasAlphaChannel() const;
- bool hasMipmaps() const { return false; }
+ static bool canRead(const QByteArray &suffix, const QByteArray &block);
- QByteArray m_data;
- QSize m_size;
- QSize m_paddedSize;
- GLuint m_texture_id;
- GLenum m_type;
- bool m_uploaded;
+ QQuickTextureFactory *read() override;
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/compressedtexture/qsgtexturefilehandler_p.h b/src/quick/scenegraph/compressedtexture/qsgtexturefilehandler_p.h
new file mode 100644
index 0000000000..8b831aebb9
--- /dev/null
+++ b/src/quick/scenegraph/compressedtexture/qsgtexturefilehandler_p.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick 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 QSGTEXTUREFILEHANDLER_P_H
+#define QSGTEXTUREFILEHANDLER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QLoggingCategory>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(QSG_LOG_TEXTUREIO)
+
+class QQuickTextureFactory;
+
+class QSGTextureFileHandler
+{
+public:
+ QSGTextureFileHandler(QIODevice *device, const QByteArray &logName = QByteArray())
+ : m_device(device)
+ {
+ m_logName = !logName.isEmpty() ? logName : QByteArrayLiteral("(unknown)");
+ }
+ virtual ~QSGTextureFileHandler() {}
+
+ virtual QQuickTextureFactory *read() = 0;
+ QIODevice *device() const { return m_device; }
+ QByteArray logName() const { return m_logName; }
+
+private:
+ QIODevice *m_device = nullptr;
+ QByteArray m_logName;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGTEXTUREFILEHANDLER_P_H
diff --git a/src/quick/scenegraph/coreapi/qsgabstractrenderer.cpp b/src/quick/scenegraph/coreapi/qsgabstractrenderer.cpp
index 3d4ce24716..fddac7ed71 100644
--- a/src/quick/scenegraph/coreapi/qsgabstractrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgabstractrenderer.cpp
@@ -97,7 +97,7 @@ QT_BEGIN_NAMESPACE
\internal
*/
QSGAbstractRendererPrivate::QSGAbstractRendererPrivate()
- : m_root_node(0)
+ : m_root_node(nullptr)
, m_clear_color(Qt::transparent)
, m_clear_mode(QSGAbstractRenderer::ClearColorBuffer | QSGAbstractRenderer::ClearDepthBuffer)
{
diff --git a/src/quick/scenegraph/coreapi/qsgabstractrenderer.h b/src/quick/scenegraph/coreapi/qsgabstractrenderer.h
index 304dc008d5..ab6fb4f317 100644
--- a/src/quick/scenegraph/coreapi/qsgabstractrenderer.h
+++ b/src/quick/scenegraph/coreapi/qsgabstractrenderer.h
@@ -62,7 +62,7 @@ public:
};
Q_DECLARE_FLAGS(ClearMode, ClearModeBit)
- virtual ~QSGAbstractRenderer();
+ ~QSGAbstractRenderer() override;
void setRootNode(QSGRootNode *node);
QSGRootNode *rootNode() const;
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index 0da35fba42..ba71551302 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -144,7 +144,7 @@ ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material)
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphContextFrame);
QSGMaterialShader *s = material->createShader();
- QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ QOpenGLContext *ctx = context->openglContext();
QSurfaceFormat::OpenGLContextProfile profile = ctx->format().profile();
QOpenGLShaderProgram *p = s->program();
@@ -155,10 +155,10 @@ ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material)
p->bindAttributeLocation(attr[i], i);
}
p->bindAttributeLocation("_qt_order", i);
- context->compileShader(s, material, qsgShaderRewriter_insertZAttributes(s->vertexShader(), profile), 0);
+ context->compileShader(s, material, qsgShaderRewriter_insertZAttributes(s->vertexShader(), profile), nullptr);
context->initializeShader(s);
if (!p->isLinked())
- return 0;
+ return nullptr;
shader = new Shader;
shader->program = s;
@@ -215,7 +215,7 @@ void ShaderManager::invalidated()
qDeleteAll(rewrittenShaders);
rewrittenShaders.clear();
delete blitProgram;
- blitProgram = 0;
+ blitProgram = nullptr;
}
void qsg_dumpShadowRoots(BatchRootInfo *i, int indent)
@@ -226,7 +226,7 @@ void qsg_dumpShadowRoots(BatchRootInfo *i, int indent)
QByteArray ind(indent + extraIndent + 10, ' ');
if (!i) {
- qDebug() << ind.constData() << "- no info";
+ qDebug("%s - no info", ind.constData());
} else {
qDebug() << ind.constData() << "- parent:" << i->parentRoot << "orders" << i->firstOrder << "->" << i->lastOrder << ", avail:" << i->availableOrders;
for (QSet<Node *>::const_iterator it = i->subRoots.constBegin();
@@ -280,7 +280,7 @@ Updater::Updater(Renderer *r)
void Updater::updateStates(QSGNode *n)
{
- m_current_clip = 0;
+ m_current_clip = nullptr;
m_added = 0;
m_transformChange = 0;
@@ -293,15 +293,15 @@ void Updater::updateStates(QSGNode *n)
qsg_dumpShadowRoots(sn);
if (Q_UNLIKELY(debug_build())) {
- qDebug() << "Updater::updateStates()";
+ qDebug("Updater::updateStates()");
if (sn->dirtyState & (QSGNode::DirtyNodeAdded << 16))
- qDebug() << " - nodes have been added";
+ qDebug(" - nodes have been added");
if (sn->dirtyState & (QSGNode::DirtyMatrix << 16))
- qDebug() << " - transforms have changed";
+ qDebug(" - transforms have changed");
if (sn->dirtyState & (QSGNode::DirtyOpacity << 16))
- qDebug() << " - opacity has changed";
+ qDebug(" - opacity has changed");
if (uint(sn->dirtyState) & uint(QSGNode::DirtyForceUpdate << 16))
- qDebug() << " - forceupdate";
+ qDebug(" - forceupdate");
}
if (Q_UNLIKELY(renderer->m_visualizeMode == Renderer::VisualizeChanges))
@@ -347,7 +347,7 @@ void Updater::visitNode(Node *n)
m_added = count;
m_force_update = force;
- n->dirtyState = 0;
+ n->dirtyState = nullptr;
}
void Updater::visitClipNode(Node *n)
@@ -473,7 +473,7 @@ void Updater::visitGeometryNode(Node *n)
if (e->root) {
BatchRootInfo *info = renderer->batchRootInfo(e->root);
- while (info != 0) {
+ while (info != nullptr) {
info->availableOrders--;
if (info->availableOrders < 0) {
renderer->m_rebuild |= Renderer::BuildRenderLists;
@@ -481,10 +481,10 @@ void Updater::visitGeometryNode(Node *n)
renderer->m_rebuild |= Renderer::BuildRenderListsForTaggedRoots;
renderer->m_taggedRoots << e->root;
}
- if (info->parentRoot != 0)
+ if (info->parentRoot != nullptr)
info = renderer->batchRootInfo(info->parentRoot);
else
- info = 0;
+ info = nullptr;
}
} else {
renderer->m_rebuild |= Renderer::FullRebuild;
@@ -680,12 +680,12 @@ void Batch::invalidate()
// the batch to do an early out..
cleanupRemovedElements();
Element *e = first;
- first = 0;
- root = 0;
+ first = nullptr;
+ root = nullptr;
while (e) {
- e->batch = 0;
+ e->batch = nullptr;
Element *n = e->nextInBatch;
- e->nextInBatch = 0;
+ e->nextInBatch = nullptr;
e = n;
}
}
@@ -756,7 +756,7 @@ Renderer::Renderer(QSGDefaultRenderContext *ctx)
, m_alphaRenderList(64)
, m_nextRenderOrder(0)
, m_partialRebuild(false)
- , m_partialRebuildRoot(0)
+ , m_partialRebuildRoot(nullptr)
, m_useDepthBuffer(true)
, m_opaqueBatches(16)
, m_alphaBatches(16)
@@ -768,17 +768,17 @@ Renderer::Renderer(QSGDefaultRenderContext *ctx)
, m_zRange(0)
, m_renderOrderRebuildLower(-1)
, m_renderOrderRebuildUpper(-1)
- , m_currentMaterial(0)
- , m_currentShader(0)
+ , m_currentMaterial(nullptr)
+ , m_currentShader(nullptr)
, m_currentStencilValue(0)
, m_clipMatrixId(0)
- , m_currentClip(0)
+ , m_currentClip(nullptr)
, m_currentClipType(NoClip)
, m_vertexUploadPool(256)
#ifdef QSG_SEPARATE_INDEX_BUFFER
, m_indexUploadPool(64)
#endif
- , m_vao(0)
+ , m_vao(nullptr)
, m_visualizeMode(VisualizeNothing)
{
initializeOpenGLFunctions();
@@ -805,8 +805,11 @@ Renderer::Renderer(QSGDefaultRenderContext *ctx)
m_batchVertexThreshold = qt_sg_envInt("QSG_RENDERER_BATCH_VERTEX_THRESHOLD", 1024);
if (Q_UNLIKELY(debug_build() || debug_render())) {
- qDebug() << "Batch thresholds: nodes:" << m_batchNodeThreshold << " vertices:" << m_batchVertexThreshold;
- qDebug() << "Using buffer strategy:" << (m_bufferStrategy == GL_STATIC_DRAW ? "static" : (m_bufferStrategy == GL_DYNAMIC_DRAW ? "dynamic" : "stream"));
+ qDebug("Batch thresholds: nodes: %d vertices: %d",
+ m_batchNodeThreshold, m_batchVertexThreshold);
+ qDebug("Using buffer strategy: %s",
+ (m_bufferStrategy == GL_STATIC_DRAW
+ ? "static" : (m_bufferStrategy == GL_DYNAMIC_DRAW ? "dynamic" : "stream")));
}
// If rendering with an OpenGL Core profile context, we need to create a VAO
@@ -913,7 +916,7 @@ void Renderer::unmap(Buffer *buffer, bool isIndexBuf)
glBufferData(target, buffer->size, buffer->data, m_bufferStrategy);
if (!m_context->hasBrokenIndexBufferObjects() && m_visualizeMode == VisualizeNothing) {
- buffer->data = 0;
+ buffer->data = nullptr;
}
}
@@ -941,7 +944,7 @@ void Renderer::removeBatchRootFromParent(Node *childRoot)
Q_ASSERT(parentInfo->subRoots.contains(childRoot));
parentInfo->subRoots.remove(childRoot);
- childInfo->parentRoot = 0;
+ childInfo->parentRoot = nullptr;
}
void Renderer::registerBatchRoot(Node *subRoot, Node *parentRoot)
@@ -1069,7 +1072,7 @@ void Renderer::nodeWasRemoved(Node *node)
if (e) {
e->removed = true;
m_elementsToDelete.add(e);
- e->node = 0;
+ e->node = nullptr;
if (e->root) {
BatchRootInfo *info = batchRootInfo(e->root);
info->availableOrders++;
@@ -1112,7 +1115,7 @@ void Renderer::nodeWasRemoved(Node *node)
void Renderer::turnNodeIntoBatchRoot(Node *node)
{
- if (Q_UNLIKELY(debug_change())) qDebug() << " - new batch root";
+ if (Q_UNLIKELY(debug_change())) qDebug(" - new batch root");
m_rebuild |= FullRebuild;
node->isBatchRoot = true;
node->becameBatchRoot = true;
@@ -1182,7 +1185,7 @@ void Renderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state)
return;
}
if (node == rootNode())
- nodeWasAdded(node, 0);
+ nodeWasAdded(node, nullptr);
else
nodeWasAdded(node, m_nodes.value(node->parent()));
}
@@ -1435,7 +1438,7 @@ void Renderer::buildRenderListsForTaggedRoots()
}
}
m_partialRebuild = false;
- m_partialRebuildRoot = 0;
+ m_partialRebuildRoot = nullptr;
m_taggedRoots.clear();
m_nextRenderOrder = qMax(m_nextRenderOrder, maxRenderOrder);
@@ -2032,7 +2035,7 @@ Renderer::ClipType Renderer::updateStencilClip(const QSGClipNode *clip)
int vboSize = 0;
bool useVBO = false;
- QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ QOpenGLContext *ctx = m_context->openglContext();
QSurfaceFormat::OpenGLContextProfile profile = ctx->format().profile();
if (!ctx->isOpenGLES() && profile == QSurfaceFormat::CoreProfile) {
@@ -2141,7 +2144,7 @@ Renderer::ClipType Renderer::updateStencilClip(const QSGClipNode *clip)
glBufferSubData(GL_ARRAY_BUFFER, 0, vertexByteSize, g->vertexData());
}
- pointer = 0;
+ pointer = nullptr;
}
glVertexAttribPointer(0, a->tupleSize, a->type, GL_FALSE, g->sizeOfVertex(), pointer);
@@ -2183,7 +2186,7 @@ void Renderer::updateClip(const QSGClipNode *clipList, const Batch *batch)
m_currentClip = clipList;
// updateClip sets another program, so force-reactivate our own
if (m_currentShader)
- setActiveShader(0, 0);
+ setActiveShader(nullptr, nullptr);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
if (batch->isOpaque)
@@ -2204,8 +2207,8 @@ void Renderer::updateClip(const QSGClipNode *clipList, const Batch *batch)
*/
void Renderer::setActiveShader(QSGMaterialShader *program, ShaderManager::Shader *shader)
{
- const char * const *c = m_currentProgram ? m_currentProgram->attributeNames() : 0;
- const char * const *n = program ? program->attributeNames() : 0;
+ const char * const *c = m_currentProgram ? m_currentProgram->attributeNames() : nullptr;
+ const char * const *n = program ? program->attributeNames() : nullptr;
int cza = m_currentShader ? m_currentShader->pos_order : -1;
int nza = shader ? shader->pos_order : -1;
@@ -2216,18 +2219,18 @@ void Renderer::setActiveShader(QSGMaterialShader *program, ShaderManager::Shader
bool was = c;
if (cza == i) {
was = true;
- c = 0;
+ c = nullptr;
} else if (c && !c[i]) { // end of the attribute array names
- c = 0;
+ c = nullptr;
was = false;
}
bool is = n;
if (nza == i) {
is = true;
- n = 0;
+ n = nullptr;
} else if (n && !n[i]) {
- n = 0;
+ n = nullptr;
is = false;
}
@@ -2243,7 +2246,7 @@ void Renderer::setActiveShader(QSGMaterialShader *program, ShaderManager::Shader
m_currentProgram->deactivate();
m_currentProgram = program;
m_currentShader = shader;
- m_currentMaterial = 0;
+ m_currentMaterial = nullptr;
if (m_currentProgram) {
m_currentProgram->program()->bind();
m_currentProgram->activate();
@@ -2295,7 +2298,7 @@ void Renderer::renderMergedBatch(const Batch *batch)
glBindBuffer(GL_ARRAY_BUFFER, batch->vbo.id);
- char *indexBase = 0;
+ char *indexBase = nullptr;
#ifdef QSG_SEPARATE_INDEX_BUFFER
const Buffer *indexBuf = &batch->ibo;
#else
@@ -2319,7 +2322,7 @@ void Renderer::renderMergedBatch(const Batch *batch)
setActiveShader(program, sms);
m_current_opacity = gn->inheritedOpacity();
- if (sms->lastOpacity != m_current_opacity) {
+ if (!qFuzzyCompare(sms->lastOpacity, float(m_current_opacity))) {
dirty |= QSGMaterialShader::RenderState::DirtyOpacity;
sms->lastOpacity = m_current_opacity;
}
@@ -2328,7 +2331,7 @@ void Renderer::renderMergedBatch(const Batch *batch)
#ifndef QT_NO_DEBUG
if (qsg_test_and_clear_material_failure()) {
- qDebug() << "QSGMaterial::updateState triggered an error (merged), batch will be skipped:";
+ qDebug("QSGMaterial::updateState triggered an error (merged), batch will be skipped:");
Element *ee = e;
while (ee) {
qDebug() << " -" << ee->node;
@@ -2391,7 +2394,7 @@ void Renderer::renderUnmergedBatch(const Batch *batch)
updateClip(gn->clipList(), batch);
glBindBuffer(GL_ARRAY_BUFFER, batch->vbo.id);
- char *indexBase = 0;
+ char *indexBase = nullptr;
#ifdef QSG_SEPARATE_INDEX_BUFFER
const Buffer *indexBuf = &batch->ibo;
#else
@@ -2449,7 +2452,7 @@ void Renderer::renderUnmergedBatch(const Batch *batch)
#ifndef QT_NO_DEBUG
if (qsg_test_and_clear_material_failure()) {
- qDebug() << "QSGMaterial::updateState() triggered an error (unmerged), batch will be skipped:";
+ qDebug("QSGMaterial::updateState() triggered an error (unmerged), batch will be skipped:");
qDebug() << " - offending node is" << e->node;
QSGNodeDumper::dump(rootNode());
qFatal("Aborting: scene graph is invalid...");
@@ -2494,18 +2497,21 @@ void Renderer::updateLineWidth(QSGGeometry *g)
if (g->drawingMode() == GL_LINE_STRIP || g->drawingMode() == GL_LINE_LOOP || g->drawingMode() == GL_LINES)
glLineWidth(g->lineWidth());
#if !defined(QT_OPENGL_ES_2)
- else if (!QOpenGLContext::currentContext()->isOpenGLES() && g->drawingMode() == GL_POINTS) {
- QOpenGLFunctions_1_0 *gl1funcs = 0;
- QOpenGLFunctions_3_2_Core *gl3funcs = 0;
- if (QOpenGLContext::currentContext()->format().profile() == QSurfaceFormat::CoreProfile)
- gl3funcs = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_2_Core>();
- else
- gl1funcs = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_1_0>();
- Q_ASSERT(gl1funcs || gl3funcs);
- if (gl1funcs)
- gl1funcs->glPointSize(g->lineWidth());
- else
- gl3funcs->glPointSize(g->lineWidth());
+ else {
+ QOpenGLContext *ctx = m_context->openglContext();
+ if (!ctx->isOpenGLES() && g->drawingMode() == GL_POINTS) {
+ QOpenGLFunctions_1_0 *gl1funcs = nullptr;
+ QOpenGLFunctions_3_2_Core *gl3funcs = nullptr;
+ if (ctx->format().profile() == QSurfaceFormat::CoreProfile)
+ gl3funcs = ctx->versionFunctions<QOpenGLFunctions_3_2_Core>();
+ else
+ gl1funcs = ctx->versionFunctions<QOpenGLFunctions_1_0>();
+ Q_ASSERT(gl1funcs || gl3funcs);
+ if (gl1funcs)
+ gl1funcs->glPointSize(g->lineWidth());
+ else
+ gl3funcs->glPointSize(g->lineWidth());
+ }
}
#endif
}
@@ -2540,10 +2546,10 @@ void Renderer::renderBatches()
bindable()->clear(clearMode());
m_current_opacity = 1;
- m_currentMaterial = 0;
- m_currentShader = 0;
- m_currentProgram = 0;
- m_currentClip = 0;
+ m_currentMaterial = nullptr;
+ m_currentShader = nullptr;
+ m_currentProgram = nullptr;
+ m_currentClip = nullptr;
bool renderOpaque = !debug_noopaque();
bool renderAlpha = !debug_noalpha();
@@ -2576,8 +2582,8 @@ void Renderer::renderBatches()
}
if (m_currentShader)
- setActiveShader(0, 0);
- updateStencilClip(0);
+ setActiveShader(nullptr, nullptr);
+ updateStencilClip(nullptr);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDepthMask(true);
@@ -2591,12 +2597,12 @@ void Renderer::deleteRemovedElements()
for (int i=0; i<m_opaqueRenderList.size(); ++i) {
Element **e = m_opaqueRenderList.data() + i;
if (*e && (*e)->removed)
- *e = 0;
+ *e = nullptr;
}
for (int i=0; i<m_alphaRenderList.size(); ++i) {
Element **e = m_alphaRenderList.data() + i;
if (*e && (*e)->removed)
- *e = 0;
+ *e = nullptr;
}
for (int i=0; i<m_elementsToDelete.size(); ++i) {
@@ -2611,6 +2617,8 @@ void Renderer::deleteRemovedElements()
void Renderer::render()
{
+ Q_ASSERT(m_context->openglContext() == QOpenGLContext::currentContext());
+
if (Q_UNLIKELY(debug_dump())) {
qDebug("\n");
QSGNodeDumper::dump(rootNode());
@@ -2655,12 +2663,12 @@ void Renderer::render()
m_rebuild |= BuildBatches;
if (Q_UNLIKELY(debug_build())) {
- qDebug() << "Opaque render lists" << (complete ? "(complete)" : "(partial)") << ":";
+ qDebug("Opaque render lists %s:", (complete ? "(complete)" : "(partial)"));
for (int i=0; i<m_opaqueRenderList.size(); ++i) {
Element *e = m_opaqueRenderList.at(i);
qDebug() << " - element:" << e << " batch:" << e->batch << " node:" << e->node << " order:" << e->order;
}
- qDebug() << "Alpha render list:" << (complete ? "(complete)" : "(partial)") << ":";
+ qDebug("Alpha render list %s:", complete ? "(complete)" : "(partial)");
for (int i=0; i<m_alphaRenderList.size(); ++i) {
Element *e = m_alphaRenderList.at(i);
qDebug() << " - element:" << e << " batch:" << e->batch << " node:" << e->node << " order:" << e->order;
@@ -2685,7 +2693,7 @@ void Renderer::render()
if (Q_UNLIKELY(debug_render())) timePrepareAlpha = timer.restart();
if (Q_UNLIKELY(debug_build())) {
- qDebug() << "Opaque Batches:";
+ qDebug("Opaque Batches:");
for (int i=0; i<m_opaqueBatches.size(); ++i) {
Batch *b = m_opaqueBatches.at(i);
qDebug() << " - Batch " << i << b << (b->needsUpload ? "upload" : "") << " root:" << b->root;
@@ -2693,7 +2701,7 @@ void Renderer::render()
qDebug() << " - element:" << e << " node:" << e->node << e->order;
}
}
- qDebug() << "Alpha Batches:";
+ qDebug("Alpha Batches:");
for (int i=0; i<m_alphaBatches.size(); ++i) {
Batch *b = m_alphaBatches.at(i);
qDebug() << " - Batch " << i << b << (b->needsUpload ? "upload" : "") << " root:" << b->root;
@@ -2731,7 +2739,7 @@ void Renderer::render()
int largestIBO = 0;
#endif
- if (Q_UNLIKELY(debug_upload())) qDebug() << "Uploading Opaque Batches:";
+ if (Q_UNLIKELY(debug_upload())) qDebug("Uploading Opaque Batches:");
for (int i=0; i<m_opaqueBatches.size(); ++i) {
Batch *b = m_opaqueBatches.at(i);
largestVBO = qMax(b->vbo.size, largestVBO);
@@ -2743,7 +2751,7 @@ void Renderer::render()
if (Q_UNLIKELY(debug_render())) timeUploadOpaque = timer.restart();
- if (Q_UNLIKELY(debug_upload())) qDebug() << "Uploading Alpha Batches:";
+ if (Q_UNLIKELY(debug_upload())) qDebug("Uploading Alpha Batches:");
for (int i=0; i<m_alphaBatches.size(); ++i) {
Batch *b = m_alphaBatches.at(i);
uploadBatch(b);
@@ -2807,11 +2815,11 @@ void Renderer::renderRenderNode(Batch *batch)
Q_ASSERT(batch->first->isRenderNode);
RenderNodeElement *e = (RenderNodeElement *) batch->first;
- setActiveShader(0, 0);
+ setActiveShader(nullptr, nullptr);
QSGNode *clip = e->renderNode->parent();
QSGRenderNodePrivate *rd = QSGRenderNodePrivate::get(e->renderNode);
- rd->m_clip_list = 0;
+ rd->m_clip_list = nullptr;
while (clip != rootNode()) {
if (clip->type() == QSGNode::ClipNodeType) {
rd->m_clip_list = static_cast<QSGClipNode *>(clip);
@@ -2875,8 +2883,8 @@ void Renderer::renderRenderNode(Batch *batch)
e->renderNode->render(&state);
- rd->m_matrix = 0;
- rd->m_clip_list = 0;
+ rd->m_matrix = nullptr;
+ rd->m_clip_list = nullptr;
if (changes & QSGRenderNode::ViewportState) {
QRect r = viewportRect();
@@ -2891,7 +2899,7 @@ void Renderer::renderRenderNode(Batch *batch)
if (changes & (QSGRenderNode::StencilState | QSGRenderNode::ScissorState)) {
glDisable(GL_SCISSOR_TEST);
- m_currentClip = 0;
+ m_currentClip = nullptr;
m_currentClipType = NoClip;
}
@@ -3061,7 +3069,7 @@ void Renderer::visualizeChanges(Node *n)
// This is because many changes don't propegate their dirty state to the
// parent so the node updater will not unset these states. They are
// not used for anything so, unsetting it should have no side effects.
- n->dirtyState = 0;
+ n->dirtyState = nullptr;
}
SHADOWNODE_TRAVERSE(n) {
@@ -3153,7 +3161,7 @@ void Renderer::visualizeOverdraw()
visualizeOverdraw_helper(m_nodes.value(rootNode()));
// Animate the view...
- QSurface *surface = QOpenGLContext::currentContext()->surface();
+ QSurface *surface = m_context->openglContext()->surface();
if (surface->surfaceClass() == QSurface::Window)
if (QQuickWindow *window = qobject_cast<QQuickWindow *>(static_cast<QWindow *>(surface)))
window->update();
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
index 5c39242029..918f3ce82c 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
@@ -125,7 +125,6 @@ template <typename Type, int PageSize> class Allocator
{
public:
Allocator()
- : m_freePage(0)
{
pages.push_back(new AllocatorPage<Type, PageSize>());
}
@@ -209,7 +208,7 @@ public:
}
QVector<AllocatorPage<Type, PageSize> *> pages;
- int m_freePage;
+ int m_freePage = 0;
};
@@ -306,12 +305,7 @@ struct Buffer {
struct Element {
Element()
- : node(0)
- , batch(0)
- , nextInBatch(0)
- , root(0)
- , order(0)
- , boundsComputed(false)
+ : boundsComputed(false)
, boundsOutsideFloatRange(false)
, translateOnlyToRoot(false)
, removed(false)
@@ -332,14 +326,14 @@ struct Element {
}
void computeBounds();
- QSGGeometryNode *node;
- Batch *batch;
- Element *nextInBatch;
- Node *root;
+ QSGGeometryNode *node = nullptr;
+ Batch *batch = nullptr;
+ Element *nextInBatch = nullptr;
+ Node *root = nullptr;
Rect bounds; // in device coordinates
- int order;
+ int order = 0;
uint boundsComputed : 1;
uint boundsOutsideFloatRange : 1;
@@ -362,12 +356,12 @@ struct RenderNodeElement : public Element {
};
struct BatchRootInfo {
- BatchRootInfo() : parentRoot(0), lastOrder(-1), firstOrder(-1), availableOrders(0) { }
+ BatchRootInfo() {}
QSet<Node *> subRoots;
- Node *parentRoot;
- int lastOrder;
- int firstOrder;
- int availableOrders;
+ Node *parentRoot = nullptr;
+ int lastOrder = -1;
+ int firstOrder = -1;
+ int availableOrders = 0;
};
struct ClipBatchRootInfo : public BatchRootInfo
@@ -381,14 +375,13 @@ struct DrawSet
: vertices(v)
, zorders(z)
, indices(i)
- , indexCount(0)
{
}
- DrawSet() : vertices(0), zorders(0), indices(0), indexCount(0) {}
- int vertices;
- int zorders;
- int indices;
- int indexCount;
+ DrawSet() {}
+ int vertices = 0;
+ int zorders = 0;
+ int indices = 0;
+ int indexCount = 0;
};
enum BatchCompatibility
@@ -410,8 +403,8 @@ struct Batch
// pseudo-constructor...
void init() {
- first = 0;
- root = 0;
+ first = nullptr;
+ root = nullptr;
vertexCount = 0;
indexCount = 0;
isOpaque = false;
@@ -440,7 +433,9 @@ struct Batch
mutable uint uploadedThisFrame : 1; // solely for debugging purposes
Buffer vbo;
+#ifdef QSG_SEPARATE_INDEX_BUFFER
Buffer ibo;
+#endif
QDataBuffer<DrawSet> drawSets;
};
@@ -461,9 +456,9 @@ struct Node
void append(Node *child) {
Q_ASSERT(child);
Q_ASSERT(!hasChild(child));
- Q_ASSERT(child->m_parent == 0);
- Q_ASSERT(child->m_next == 0);
- Q_ASSERT(child->m_prev == 0);
+ Q_ASSERT(child->m_parent == nullptr);
+ Q_ASSERT(child->m_next == nullptr);
+ Q_ASSERT(child->m_prev == nullptr);
if (!m_child) {
child->m_next = child;
@@ -484,27 +479,27 @@ struct Node
// only child..
if (child->m_next == child) {
- m_child = 0;
+ m_child = nullptr;
} else {
if (m_child == child)
m_child = child->m_next;
child->m_next->m_prev = child->m_prev;
child->m_prev->m_next = child->m_next;
}
- child->m_next = 0;
- child->m_prev = 0;
- child->setParent(0);
+ child->m_next = nullptr;
+ child->m_prev = nullptr;
+ child->setParent(nullptr);
}
Node *firstChild() const { return m_child; }
Node *sibling() const {
Q_ASSERT(m_parent);
- return m_next == m_parent->m_child ? 0 : m_next;
+ return m_next == m_parent->m_child ? nullptr : m_next;
}
void setParent(Node *p) {
- Q_ASSERT(m_parent == 0 || p == 0);
+ Q_ASSERT(m_parent == nullptr || p == nullptr);
m_parent = p;
}
@@ -589,7 +584,7 @@ public:
float lastOpacity;
};
- ShaderManager(QSGDefaultRenderContext *ctx) : visualizeProgram(0), blitProgram(0), context(ctx) { }
+ ShaderManager(QSGDefaultRenderContext *ctx) : visualizeProgram(nullptr), blitProgram(nullptr), context(ctx) { }
~ShaderManager() {
qDeleteAll(rewrittenShaders);
qDeleteAll(stockShaders);
@@ -743,7 +738,9 @@ private:
ClipType m_currentClipType;
QDataBuffer<char> m_vertexUploadPool;
+#ifdef QSG_SEPARATE_INDEX_BUFFER
QDataBuffer<char> m_indexUploadPool;
+#endif
// For minimal OpenGL core profile support
QOpenGLVertexArrayObject *m_vao;
@@ -763,7 +760,10 @@ Batch *Renderer::newBatch()
m_batchPool.resize(size - 1);
} else {
b = new Batch();
- memset(&b->vbo, 0, sizeof(Buffer) * 2); // Clear VBO & IBO
+ memset(&b->vbo, 0, sizeof(Buffer));
+#ifdef QSG_SEPARATE_INDEX_BUFFER
+ memset(&b->ibo, 0, sizeof(Buffer));
+#endif
}
b->init();
return b;
diff --git a/src/quick/scenegraph/coreapi/qsggeometry.cpp b/src/quick/scenegraph/coreapi/qsggeometry.cpp
index 69a8c21ed2..226709094d 100644
--- a/src/quick/scenegraph/coreapi/qsggeometry.cpp
+++ b/src/quick/scenegraph/coreapi/qsggeometry.cpp
@@ -430,9 +430,9 @@ QSGGeometry::QSGGeometry(const QSGGeometry::AttributeSet &attributes,
, m_index_count(0)
, m_index_type(indexType)
, m_attributes(attributes)
- , m_data(0)
+ , m_data(nullptr)
, m_index_data_offset(-1)
- , m_server_data(0)
+ , m_server_data(nullptr)
, m_owns_data(false)
, m_index_usage_pattern(AlwaysUploadPattern)
, m_vertex_usage_pattern(AlwaysUploadPattern)
@@ -529,7 +529,7 @@ QSGGeometry::~QSGGeometry()
void *QSGGeometry::indexData()
{
return m_index_data_offset < 0
- ? 0
+ ? nullptr
: ((char *) m_data + m_index_data_offset);
}
@@ -541,7 +541,7 @@ void *QSGGeometry::indexData()
const void *QSGGeometry::indexData() const
{
return m_index_data_offset < 0
- ? 0
+ ? nullptr
: ((char *) m_data + m_index_data_offset);
}
@@ -768,6 +768,19 @@ void QSGGeometry::updateColoredRectGeometry(QSGGeometry *g, const QRectF &rect)
v[3].y = rect.bottom();
}
+/*!
+ \enum QSGGeometry::AttributeType
+
+ This enum identifies several attribute types.
+
+ \value UnknownAttribute Don't care
+ \value PositionAttribute Position
+ \value ColorAttribute Color
+ \value TexCoordAttribute Texture coordinate
+ \value TexCoord1Attribute Texture coordinate 1
+ \value TexCoord2Attribute Texture coordinate 2
+
+ */
/*!
\enum QSGGeometry::DataPattern
diff --git a/src/quick/scenegraph/coreapi/qsgmaterial.cpp b/src/quick/scenegraph/coreapi/qsgmaterial.cpp
index 07dc87a643..8557de1b1f 100644
--- a/src/quick/scenegraph/coreapi/qsgmaterial.cpp
+++ b/src/quick/scenegraph/coreapi/qsgmaterial.cpp
@@ -443,7 +443,12 @@ void QSGMaterialShader::compile()
otherwise returns \c false.
*/
+/*!
+ \fn bool QSGMaterialShader::RenderState::isCachedMaterialDataDirty() const
+ Returns \c true if the dirtyStates() contains the dirty cached material state,
+ otherwise returns \c false.
+ */
/*!
\fn QSGMaterialShader::RenderState::DirtyStates QSGMaterialShader::RenderState::dirtyStates() const
@@ -636,7 +641,7 @@ static void qt_print_material_count()
*/
QSGMaterial::QSGMaterial()
- : m_flags(0)
+ : m_flags(nullptr)
{
Q_UNUSED(m_reserved);
#ifndef QT_NO_DEBUG
diff --git a/src/quick/scenegraph/coreapi/qsgnode.cpp b/src/quick/scenegraph/coreapi/qsgnode.cpp
index 22d57001fc..9717862baa 100644
--- a/src/quick/scenegraph/coreapi/qsgnode.cpp
+++ b/src/quick/scenegraph/coreapi/qsgnode.cpp
@@ -114,6 +114,10 @@ static void qt_print_node_count()
\value DirtyOpacity The opacity of a QSGOpacityNode has changed.
\value DirtySubtreeBlocked The subtree has been blocked.
+ \omitvalue DirtyForceUpdate
+ \omitvalue DirtyUsePreprocess
+ \omitvalue DirtyPropagationMask
+
\sa QSGNode::markDirty()
*/
@@ -135,6 +139,8 @@ static void qt_print_node_count()
ownership over the opaque material and will delete it when the node is
destroyed or a material is assigned.
\value InternalReserved Reserved for internal use.
+
+ \omitvalue IsVisitableNode
*/
/*!
@@ -149,6 +155,8 @@ static void qt_print_node_count()
\value OpacityNodeType The type of QSGOpacityNode
\value RenderNodeType The type of QSGRenderNode
+ \omitvalue RootNodeType
+
\sa type()
*/
@@ -236,15 +244,8 @@ static void qt_print_node_count()
* Constructs a new node
*/
QSGNode::QSGNode()
- : m_parent(0)
- , m_type(BasicNodeType)
- , m_firstChild(0)
- , m_lastChild(0)
- , m_nextSibling(0)
- , m_previousSibling(0)
- , m_subtreeRenderableCount(0)
- , m_nodeFlags(OwnedByParent)
- , m_dirtyState(0)
+ : m_nodeFlags(OwnedByParent)
+ , m_dirtyState(nullptr)
{
init();
}
@@ -255,15 +256,15 @@ QSGNode::QSGNode()
* \internal
*/
QSGNode::QSGNode(NodeType type)
- : m_parent(0)
+ : m_parent(nullptr)
, m_type(type)
- , m_firstChild(0)
- , m_lastChild(0)
- , m_nextSibling(0)
- , m_previousSibling(0)
+ , m_firstChild(nullptr)
+ , m_lastChild(nullptr)
+ , m_nextSibling(nullptr)
+ , m_previousSibling(nullptr)
, m_subtreeRenderableCount(type == GeometryNodeType || type == RenderNodeType ? 1 : 0)
, m_nodeFlags(OwnedByParent)
- , m_dirtyState(0)
+ , m_dirtyState(nullptr)
{
init();
}
@@ -274,15 +275,15 @@ QSGNode::QSGNode(NodeType type)
* \internal
*/
QSGNode::QSGNode(QSGNodePrivate &dd, NodeType type)
- : m_parent(0)
+ : m_parent(nullptr)
, m_type(type)
- , m_firstChild(0)
- , m_lastChild(0)
- , m_nextSibling(0)
- , m_previousSibling(0)
+ , m_firstChild(nullptr)
+ , m_lastChild(nullptr)
+ , m_nextSibling(nullptr)
+ , m_previousSibling(nullptr)
, m_subtreeRenderableCount(type == GeometryNodeType || type == RenderNodeType ? 1 : 0)
, m_nodeFlags(OwnedByParent)
- , m_dirtyState(0)
+ , m_dirtyState(nullptr)
, d_ptr(&dd)
{
init();
@@ -380,17 +381,17 @@ void QSGNode::destroy()
{
if (m_parent) {
m_parent->removeChildNode(this);
- Q_ASSERT(m_parent == 0);
+ Q_ASSERT(m_parent == nullptr);
}
while (m_firstChild) {
QSGNode *child = m_firstChild;
removeChildNode(child);
- Q_ASSERT(child->m_parent == 0);
+ Q_ASSERT(child->m_parent == nullptr);
if (child->flags() & OwnedByParent)
delete child;
}
- Q_ASSERT(m_firstChild == 0 && m_lastChild == 0);
+ Q_ASSERT(m_firstChild == nullptr && m_lastChild == nullptr);
}
@@ -549,11 +550,11 @@ void QSGNode::removeChildNode(QSGNode *node)
next->m_previousSibling = previous;
else
m_lastChild = previous;
- node->m_previousSibling = 0;
- node->m_nextSibling = 0;
+ node->m_previousSibling = nullptr;
+ node->m_nextSibling = nullptr;
node->markDirty(DirtyNodeRemoved);
- node->m_parent = 0;
+ node->m_parent = nullptr;
}
@@ -566,13 +567,13 @@ void QSGNode::removeAllChildNodes()
while (m_firstChild) {
QSGNode *node = m_firstChild;
m_firstChild = node->m_nextSibling;
- node->m_nextSibling = 0;
+ node->m_nextSibling = nullptr;
if (m_firstChild)
- m_firstChild->m_previousSibling = 0;
+ m_firstChild->m_previousSibling = nullptr;
else
- m_lastChild = 0;
+ m_lastChild = nullptr;
node->markDirty(DirtyNodeRemoved);
- node->m_parent = 0;
+ node->m_parent = nullptr;
}
}
@@ -706,9 +707,9 @@ void qsgnode_set_description(QSGNode *node, const QString &description)
*/
QSGBasicGeometryNode::QSGBasicGeometryNode(NodeType type)
: QSGNode(type)
- , m_geometry(0)
- , m_matrix(0)
- , m_clip_list(0)
+ , m_geometry(nullptr)
+ , m_matrix(nullptr)
+ , m_clip_list(nullptr)
{
}
@@ -718,9 +719,9 @@ QSGBasicGeometryNode::QSGBasicGeometryNode(NodeType type)
*/
QSGBasicGeometryNode::QSGBasicGeometryNode(QSGBasicGeometryNodePrivate &dd, NodeType type)
: QSGNode(dd, type)
- , m_geometry(0)
- , m_matrix(0)
- , m_clip_list(0)
+ , m_geometry(nullptr)
+ , m_matrix(nullptr)
+ , m_clip_list(nullptr)
{
}
@@ -862,10 +863,6 @@ void QSGBasicGeometryNode::setGeometry(QSGGeometry *geometry)
QSGGeometryNode::QSGGeometryNode()
: QSGBasicGeometryNode(GeometryNodeType)
- , m_render_order(0)
- , m_material(0)
- , m_opaque_material(0)
- , m_opacity(1)
{
}
@@ -876,8 +873,8 @@ QSGGeometryNode::QSGGeometryNode()
QSGGeometryNode::QSGGeometryNode(QSGGeometryNodePrivate &dd)
: QSGBasicGeometryNode(dd, GeometryNodeType)
, m_render_order(0)
- , m_material(0)
- , m_opaque_material(0)
+ , m_material(nullptr)
+ , m_opaque_material(nullptr)
, m_opacity(1)
{
}
@@ -971,7 +968,7 @@ void QSGGeometryNode::setMaterial(QSGMaterial *material)
delete m_material;
m_material = material;
#ifndef QT_NO_DEBUG
- if (m_material != 0 && m_opaque_material == m_material)
+ if (m_material != nullptr && m_opaque_material == m_material)
qWarning("QSGGeometryNode: using same material for both opaque and translucent");
#endif
markDirty(DirtyMaterial);
@@ -1002,7 +999,7 @@ void QSGGeometryNode::setOpaqueMaterial(QSGMaterial *material)
delete m_opaque_material;
m_opaque_material = material;
#ifndef QT_NO_DEBUG
- if (m_opaque_material != 0 && m_opaque_material == m_material)
+ if (m_opaque_material != nullptr && m_opaque_material == m_material)
qWarning("QSGGeometryNode: using same material for both opaque and translucent");
#endif
@@ -1266,7 +1263,7 @@ QSGRootNode::QSGRootNode()
QSGRootNode::~QSGRootNode()
{
while (!m_renderers.isEmpty())
- m_renderers.constLast()->setRootNode(0);
+ m_renderers.constLast()->setRootNode(nullptr);
destroy(); // Must call destroy() here because markDirty() casts this to QSGRootNode.
}
@@ -1318,8 +1315,6 @@ void QSGRootNode::notifyNodeChange(QSGNode *node, DirtyState state)
*/
QSGOpacityNode::QSGOpacityNode()
: QSGNode(OpacityNodeType)
- , m_opacity(1)
- , m_combined_opacity(1)
{
}
diff --git a/src/quick/scenegraph/coreapi/qsgnode.h b/src/quick/scenegraph/coreapi/qsgnode.h
index f2708b2b96..854e284c9e 100644
--- a/src/quick/scenegraph/coreapi/qsgnode.h
+++ b/src/quick/scenegraph/coreapi/qsgnode.h
@@ -77,9 +77,7 @@ public:
TransformNodeType,
ClipNodeType,
OpacityNodeType,
-#ifndef qdoc
RootNodeType,
-#endif
RenderNodeType
};
@@ -96,9 +94,8 @@ public:
OwnsOpaqueMaterial = 0x00040000,
// Uppermost 8 bits are reserved for internal use.
-#ifndef qdoc
IsVisitableNode = 0x01000000
-#else
+#ifdef Q_CLANG_QDOC
InternalReserved = 0x01000000
#endif
};
@@ -113,7 +110,6 @@ public:
DirtyMaterial = 0x2000,
DirtyOpacity = 0x4000,
-#ifndef qdoc
DirtyForceUpdate = 0x8000,
DirtyUsePreprocess = UsePreprocess,
@@ -122,7 +118,6 @@ public:
| DirtyNodeAdded
| DirtyOpacity
| DirtyForceUpdate
-#endif
};
Q_DECLARE_FLAGS(DirtyState, DirtyStateBit)
@@ -173,13 +168,13 @@ private:
void init();
void destroy();
- QSGNode *m_parent;
- NodeType m_type;
- QSGNode *m_firstChild;
- QSGNode *m_lastChild;
- QSGNode *m_nextSibling;
- QSGNode *m_previousSibling;
- int m_subtreeRenderableCount;
+ QSGNode *m_parent = nullptr;
+ NodeType m_type = BasicNodeType;
+ QSGNode *m_firstChild = nullptr;
+ QSGNode *m_lastChild = nullptr;
+ QSGNode *m_nextSibling = nullptr;
+ QSGNode *m_previousSibling = nullptr;
+ int m_subtreeRenderableCount = 0;
Flags m_nodeFlags;
DirtyState m_dirtyState; // Obsolete, remove in Qt 6
@@ -195,7 +190,7 @@ void Q_QUICK_EXPORT qsgnode_set_description(QSGNode *node, const QString &descri
class Q_QUICK_EXPORT QSGBasicGeometryNode : public QSGNode
{
public:
- ~QSGBasicGeometryNode();
+ ~QSGBasicGeometryNode() override;
void setGeometry(QSGGeometry *geometry);
const QSGGeometry *geometry() const { return m_geometry; }
@@ -229,7 +224,7 @@ class Q_QUICK_EXPORT QSGGeometryNode : public QSGBasicGeometryNode
{
public:
QSGGeometryNode();
- ~QSGGeometryNode();
+ ~QSGGeometryNode() override;
void setMaterial(QSGMaterial *material);
QSGMaterial *material() const { return m_material; }
@@ -251,18 +246,18 @@ protected:
private:
friend class QSGNodeUpdater;
- int m_render_order;
- QSGMaterial *m_material;
- QSGMaterial *m_opaque_material;
+ int m_render_order = 0;
+ QSGMaterial *m_material = nullptr;
+ QSGMaterial *m_opaque_material = nullptr;
- qreal m_opacity;
+ qreal m_opacity = 1;
};
class Q_QUICK_EXPORT QSGClipNode : public QSGBasicGeometryNode
{
public:
QSGClipNode();
- ~QSGClipNode();
+ ~QSGClipNode() override;
void setIsRectangular(bool rectHint);
bool isRectangular() const { return m_is_rectangular; }
@@ -282,7 +277,7 @@ class Q_QUICK_EXPORT QSGTransformNode : public QSGNode
{
public:
QSGTransformNode();
- ~QSGTransformNode();
+ ~QSGTransformNode() override;
void setMatrix(const QMatrix4x4 &matrix);
const QMatrix4x4 &matrix() const { return m_matrix; }
@@ -300,7 +295,7 @@ class Q_QUICK_EXPORT QSGRootNode : public QSGNode
{
public:
QSGRootNode();
- ~QSGRootNode();
+ ~QSGRootNode() override;
private:
void notifyNodeChange(QSGNode *node, DirtyState state);
@@ -317,7 +312,7 @@ class Q_QUICK_EXPORT QSGOpacityNode : public QSGNode
{
public:
QSGOpacityNode();
- ~QSGOpacityNode();
+ ~QSGOpacityNode() override;
void setOpacity(qreal opacity);
qreal opacity() const { return m_opacity; }
@@ -328,8 +323,8 @@ public:
bool isSubtreeBlocked() const override;
private:
- qreal m_opacity;
- qreal m_combined_opacity;
+ qreal m_opacity = 1;
+ qreal m_combined_opacity = 1;
};
class Q_QUICK_EXPORT QSGNodeVisitor {
diff --git a/src/quick/scenegraph/coreapi/qsgnode_p.h b/src/quick/scenegraph/coreapi/qsgnode_p.h
index 84d5477085..f81128f51a 100644
--- a/src/quick/scenegraph/coreapi/qsgnode_p.h
+++ b/src/quick/scenegraph/coreapi/qsgnode_p.h
@@ -78,18 +78,14 @@ public:
class QSGBasicGeometryNodePrivate : public QSGNodePrivate
{
public:
- QSGBasicGeometryNodePrivate()
- : QSGNodePrivate()
- {}
+ QSGBasicGeometryNodePrivate() {}
};
class QSGGeometryNodePrivate: public QSGBasicGeometryNodePrivate
{
public:
- QSGGeometryNodePrivate()
- : QSGBasicGeometryNodePrivate()
- {}
+ QSGGeometryNodePrivate() {}
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/coreapi/qsgnodeupdater.cpp b/src/quick/scenegraph/coreapi/qsgnodeupdater.cpp
index d6d533307e..8bc9ded594 100644
--- a/src/quick/scenegraph/coreapi/qsgnodeupdater.cpp
+++ b/src/quick/scenegraph/coreapi/qsgnodeupdater.cpp
@@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE
QSGNodeUpdater::QSGNodeUpdater()
: m_combined_matrix_stack(64)
, m_opacity_stack(64)
- , m_current_clip(0)
+ , m_current_clip(nullptr)
, m_force_update(0)
{
m_opacity_stack.add(1);
@@ -60,7 +60,7 @@ QSGNodeUpdater::~QSGNodeUpdater()
void QSGNodeUpdater::updateStates(QSGNode *n)
{
- m_current_clip = 0;
+ m_current_clip = nullptr;
m_force_update = 0;
Q_ASSERT(m_opacity_stack.size() == 1); // The one we added in the constructr...
@@ -82,7 +82,7 @@ void QSGNodeUpdater::updateStates(QSGNode *n)
bool QSGNodeUpdater::isNodeBlocked(QSGNode *node, QSGNode *root) const
{
- while (node != root && node != 0) {
+ while (node != root && node != nullptr) {
if (node->isSubtreeBlocked())
return true;
node = node->parent();
diff --git a/src/quick/scenegraph/coreapi/qsgrenderer.cpp b/src/quick/scenegraph/coreapi/qsgrenderer.cpp
index 3ae79a933f..e1ba001d2d 100644
--- a/src/quick/scenegraph/coreapi/qsgrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrenderer.cpp
@@ -132,8 +132,8 @@ QSGRenderer::QSGRenderer(QSGRenderContext *context)
, m_current_determinant(1)
, m_device_pixel_ratio(1)
, m_context(context)
- , m_node_updater(0)
- , m_bindable(0)
+ , m_node_updater(nullptr)
+ , m_bindable(nullptr)
, m_changed_emitted(false)
, m_is_rendering(false)
, m_is_preprocessing(false)
@@ -143,7 +143,7 @@ QSGRenderer::QSGRenderer(QSGRenderContext *context)
QSGRenderer::~QSGRenderer()
{
- setRootNode(0);
+ setRootNode(nullptr);
delete m_node_updater;
}
@@ -249,7 +249,7 @@ void QSGRenderer::renderScene(const QSGBindable &bindable)
m_is_rendering = false;
m_changed_emitted = false;
- m_bindable = 0;
+ m_bindable = nullptr;
qCDebug(QSG_LOG_TIME_RENDERER,
"time in renderer: total=%dms, preprocess=%d, updates=%d, binding=%d, rendering=%d",
diff --git a/src/quick/scenegraph/coreapi/qsgrenderer_p.h b/src/quick/scenegraph/coreapi/qsgrenderer_p.h
index ae8d9f75d2..8362ff54dc 100644
--- a/src/quick/scenegraph/coreapi/qsgrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgrenderer_p.h
@@ -168,12 +168,12 @@ class Q_QUICK_PRIVATE_EXPORT QSGNodeDumper : public QSGNodeVisitor {
public:
static void dump(QSGNode *n);
- QSGNodeDumper() : m_indent(0) {}
+ QSGNodeDumper() {}
void visitNode(QSGNode *n) override;
void visitChildren(QSGNode *n) override;
private:
- int m_indent;
+ int m_indent = 0;
};
diff --git a/src/quick/scenegraph/coreapi/qsgrendernode.cpp b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
index a8954848d6..df3fa16a32 100644
--- a/src/quick/scenegraph/coreapi/qsgrendernode.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
@@ -74,8 +74,8 @@ QSGRenderNode::~QSGRenderNode()
}
QSGRenderNodePrivate::QSGRenderNodePrivate()
- : m_matrix(0)
- , m_clip_list(0)
+ : m_matrix(nullptr)
+ , m_clip_list(nullptr)
, m_opacity(1)
{
}
@@ -119,7 +119,7 @@ QSGRenderNodePrivate::QSGRenderNodePrivate()
*/
QSGRenderNode::StateFlags QSGRenderNode::changedStates() const
{
- return 0;
+ return nullptr;
}
/*!
@@ -213,6 +213,22 @@ void QSGRenderNode::releaseResources()
}
/*!
+ \enum QSGRenderNode::StateFlag
+
+ This enum is a bit mask identifying several states.
+
+ \value DepthState Depth
+ \value StencilState Stencil
+ \value ScissorState Scissor
+ \value ColorState Color
+ \value BlendState Blend
+ \value CullState Cull
+ \value ViewportState View poirt
+ \value RenderTargetState Render target
+
+ */
+
+/*!
\enum QSGRenderNode::RenderingFlag
Possible values for the bitmask returned from flags().
@@ -251,7 +267,7 @@ void QSGRenderNode::releaseResources()
*/
QSGRenderNode::RenderingFlags QSGRenderNode::flags() const
{
- return 0;
+ return nullptr;
}
/*!
@@ -354,7 +370,7 @@ QSGRenderNode::RenderState::~RenderState()
*/
/*!
- \fn const QRegion *QSGRenderNode::clipRegion() const
+ \fn const QRegion *QSGRenderNode::RenderState::clipRegion() const
\return the current clip region or null for backends where clipping is
implemented via stencil or scissoring.
diff --git a/src/quick/scenegraph/coreapi/qsgrendernode.h b/src/quick/scenegraph/coreapi/qsgrendernode.h
index f6bc40d3ee..0fb83b080c 100644
--- a/src/quick/scenegraph/coreapi/qsgrendernode.h
+++ b/src/quick/scenegraph/coreapi/qsgrendernode.h
@@ -80,7 +80,7 @@ public:
};
QSGRenderNode();
- ~QSGRenderNode();
+ ~QSGRenderNode() override;
virtual StateFlags changedStates() const;
virtual void render(const RenderState *state) = 0;
diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h
index ba146b884f..9c88b8272c 100644
--- a/src/quick/scenegraph/qsgadaptationlayer_p.h
+++ b/src/quick/scenegraph/qsgadaptationlayer_p.h
@@ -266,19 +266,19 @@ public:
Texture // for APIs with separate texture and sampler objects
};
struct InputParameter {
- InputParameter() : semanticIndex(0) { }
+ InputParameter() {}
// Semantics use the D3D keys (POSITION, TEXCOORD).
// Attribute name based APIs can map based on pre-defined names.
QByteArray semanticName;
- int semanticIndex;
+ int semanticIndex = 0;
};
struct Variable {
- Variable() : type(Constant), offset(0), size(0), bindPoint(0) { }
- VariableType type;
+ Variable() {}
+ VariableType type = Constant;
QByteArray name;
- uint offset; // for cbuffer members
- uint size; // for cbuffer members
- int bindPoint; // for textures and samplers; for register-based APIs
+ uint offset = 0; // for cbuffer members
+ uint size = 0; // for cbuffer members
+ int bindPoint = 0; // for textures and samplers; for register-based APIs
};
QByteArray blob; // source or bytecode
@@ -329,8 +329,8 @@ public:
};
struct ShaderData {
- ShaderData() : hasShaderCode(false) { }
- bool hasShaderCode;
+ ShaderData() {}
+ bool hasShaderCode = false;
QSGGuiThreadShaderEffectManager::ShaderInfo shaderInfo;
QVector<VariableData> varData;
};
@@ -373,7 +373,7 @@ public:
HighQualitySubPixelAntialiasing
};
- QSGGlyphNode() : m_ownerElement(0) {}
+ QSGGlyphNode() {}
virtual void setGlyphs(const QPointF &position, const QGlyphRun &glyphs) = 0;
virtual void setColor(const QColor &color) = 0;
@@ -394,7 +394,7 @@ public:
void accept(QSGNodeVisitorEx *visitor) override { if (visitor->visit(this)) visitor->visitChildren(this); visitor->endVisit(this); }
protected:
QRectF m_bounding_rect;
- QQuickItem *m_ownerElement;
+ QQuickItem *m_ownerElement = nullptr;
};
class Q_QUICK_PRIVATE_EXPORT QSGDistanceFieldGlyphConsumer
@@ -421,24 +421,24 @@ public:
};
struct TexCoord {
- qreal x;
- qreal y;
- qreal width;
- qreal height;
- qreal xMargin;
- qreal yMargin;
+ qreal x = 0;
+ qreal y = 0;
+ qreal width = -1;
+ qreal height = -1;
+ qreal xMargin = 0;
+ qreal yMargin = 0;
- TexCoord() : x(0), y(0), width(-1), height(-1), xMargin(0), yMargin(0) { }
+ TexCoord() {}
bool isNull() const { return width <= 0 || height <= 0; }
bool isValid() const { return width >= 0 && height >= 0; }
};
struct Texture {
- uint textureId;
+ uint textureId = 0;
QSize size;
- Texture() : textureId(0), size(QSize()) { }
+ Texture() : size(QSize()) { }
bool operator == (const Texture &other) const { return textureId == other.textureId; }
};
@@ -478,13 +478,13 @@ protected:
};
struct GlyphData {
- Texture *texture;
+ Texture *texture = nullptr;
TexCoord texCoord;
QRectF boundingRect;
QPainterPath path;
- quint32 ref;
+ quint32 ref = 0;
- GlyphData() : texture(0), ref(0) { }
+ GlyphData() {}
};
virtual void requestGlyphs(const QSet<glyph_t> &glyphs) = 0;
diff --git a/src/quick/scenegraph/qsgbasicglyphnode.cpp b/src/quick/scenegraph/qsgbasicglyphnode.cpp
index 38f650a82c..4559b7951c 100644
--- a/src/quick/scenegraph/qsgbasicglyphnode.cpp
+++ b/src/quick/scenegraph/qsgbasicglyphnode.cpp
@@ -44,7 +44,7 @@ QT_BEGIN_NAMESPACE
QSGBasicGlyphNode::QSGBasicGlyphNode()
: m_style(QQuickText::Normal)
- , m_material(0)
+ , m_material(nullptr)
, m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 0)
{
m_geometry.setDrawingMode(QSGGeometry::DrawTriangles);
@@ -59,7 +59,7 @@ QSGBasicGlyphNode::~QSGBasicGlyphNode()
void QSGBasicGlyphNode::setColor(const QColor &color)
{
m_color = color;
- if (m_material != 0) {
+ if (m_material != nullptr) {
setMaterialColor(color);
markDirty(DirtyMaterial);
}
@@ -67,7 +67,7 @@ void QSGBasicGlyphNode::setColor(const QColor &color)
void QSGBasicGlyphNode::setGlyphs(const QPointF &position, const QGlyphRun &glyphs)
{
- if (m_material != 0)
+ if (m_material != nullptr)
delete m_material;
m_position = position;
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index fb66a6ebb1..d9ed25c099 100644
--- a/src/quick/scenegraph/qsgcontext.cpp
+++ b/src/quick/scenegraph/qsgcontext.cpp
@@ -363,13 +363,6 @@ void QSGRenderContext::registerFontengineForCleanup(QFontEngine *engine)
}
/*!
- Factory function for texture objects.
-
- If \a image is a valid image, the QSGTexture::setImage function
- will be called with \a image as argument.
- */
-
-/*!
Factory function for the scene graph renderers.
The renderers are used for the toplevel renderer and once for every
@@ -379,7 +372,7 @@ void QSGRenderContext::registerFontengineForCleanup(QFontEngine *engine)
QSGTexture *QSGRenderContext::textureForFactory(QQuickTextureFactory *factory, QQuickWindow *window)
{
if (!factory)
- return 0;
+ return nullptr;
m_mutex.lock();
QSGTexture *texture = m_textures.value(factory);
@@ -404,6 +397,20 @@ void QSGRenderContext::textureFactoryDestroyed(QObject *o)
m_mutex.unlock();
}
+/*!
+ Return the texture corresponding to a texture factory.
+
+ This may optionally manipulate the texture in some way; for example by returning
+ an atlased texture.
+
+ This function is not a replacement for textureForFactory; both should be used
+ for a single texture (this might atlas, while the other might cache).
+*/
+QSGTexture *QSGRenderContext::compressedTextureForFactory(const QSGCompressedTextureFactory *) const
+{
+ return nullptr;
+}
+
#include "qsgcontext.moc"
#include "moc_qsgcontext_p.cpp"
diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h
index 84a2523f26..6d70d7ef6b 100644
--- a/src/quick/scenegraph/qsgcontext_p.h
+++ b/src/quick/scenegraph/qsgcontext_p.h
@@ -78,6 +78,7 @@ class QSGMaterial;
class QSGRenderLoop;
class QSGLayer;
class QQuickTextureFactory;
+class QSGCompressedTextureFactory;
class QSGContext;
class QQuickPaintedItem;
class QSGRendererInterface;
@@ -109,8 +110,8 @@ public:
MsaaAntialiasing
};
- explicit QSGContext(QObject *parent = 0);
- virtual ~QSGContext();
+ explicit QSGContext(QObject *parent = nullptr);
+ ~QSGContext() override;
virtual void renderContextInitialized(QSGRenderContext *renderContext);
virtual void renderContextInvalidated(QSGRenderContext *renderContext);
@@ -158,7 +159,7 @@ public:
};
QSGRenderContext(QSGContext *context);
- virtual ~QSGRenderContext();
+ ~QSGRenderContext() override;
QSGContext *sceneGraphContext() const { return m_sg; }
virtual bool isValid() const { return true; }
@@ -173,6 +174,7 @@ public:
virtual QSGTexture *createTexture(const QImage &image, uint flags = CreateTexture_Alpha) const = 0;
virtual QSGRenderer *createRenderer() = 0;
+ virtual QSGTexture *compressedTextureForFactory(const QSGCompressedTextureFactory *) const;
virtual void setAttachToGraphicsContext(bool attach) { Q_UNUSED(attach); }
diff --git a/src/quick/scenegraph/qsgcontextplugin.cpp b/src/quick/scenegraph/qsgcontextplugin.cpp
index 1c2550d197..31f1c4c722 100644
--- a/src/quick/scenegraph/qsgcontextplugin.cpp
+++ b/src/quick/scenegraph/qsgcontextplugin.cpp
@@ -74,8 +74,8 @@ struct QSGAdaptationBackendData
{
QSGAdaptationBackendData();
- bool tried;
- QSGContextFactoryInterface *factory;
+ bool tried = false;
+ QSGContextFactoryInterface *factory = nullptr;
QString name;
QSGContextFactoryInterface::Flags flags;
@@ -85,9 +85,7 @@ struct QSGAdaptationBackendData
};
QSGAdaptationBackendData::QSGAdaptationBackendData()
- : tried(false)
- , factory(nullptr)
- , flags(0)
+ : flags(nullptr)
{
// Fill in the table with the built-in adaptations.
builtIns.append(new QSGSoftwareAdaptation);
@@ -140,7 +138,9 @@ QSGAdaptationBackendData *contextFactory()
#ifdef Q_OS_HTML5
requestedBackend = QString::fromLocal8Bit("software");
#endif
+
if (!requestedBackend.isEmpty()) {
+ qCDebug(QSG_LOG_INFO, "Loading backend %s", qUtf8Printable(requestedBackend));
// First look for a built-in adaptation.
for (QSGContextFactoryInterface *builtInBackend : qAsConst(backendData->builtIns)) {
@@ -210,7 +210,7 @@ QQuickTextureFactory *QSGContext::createTextureFactoryFromImage(const QImage &im
QSGAdaptationBackendData *backendData = contextFactory();
if (backendData->factory)
return backendData->factory->createTextureFactoryFromImage(image);
- return 0;
+ return nullptr;
}
@@ -224,7 +224,7 @@ QSGRenderLoop *QSGContext::createWindowManager()
QSGAdaptationBackendData *backendData = contextFactory();
if (backendData->factory)
return backendData->factory->createWindowManager();
- return 0;
+ return nullptr;
}
void QSGContext::setBackend(const QString &backend)
diff --git a/src/quick/scenegraph/qsgcontextplugin_p.h b/src/quick/scenegraph/qsgcontextplugin_p.h
index 02d4b79b76..d37d4df270 100644
--- a/src/quick/scenegraph/qsgcontextplugin_p.h
+++ b/src/quick/scenegraph/qsgcontextplugin_p.h
@@ -87,13 +87,13 @@ class Q_QUICK_PRIVATE_EXPORT QSGContextPlugin : public QObject, public QSGContex
Q_OBJECT
Q_INTERFACES(QSGContextFactoryInterface:QFactoryInterface)
public:
- explicit QSGContextPlugin(QObject *parent = 0);
+ explicit QSGContextPlugin(QObject *parent = nullptr);
virtual ~QSGContextPlugin();
QStringList keys() const override = 0;
- QQuickTextureFactory *createTextureFactoryFromImage(const QImage &) override { return 0; }
- QSGRenderLoop *createWindowManager() override { return 0; }
+ QQuickTextureFactory *createTextureFactoryFromImage(const QImage &) override { return nullptr; }
+ QSGRenderLoop *createWindowManager() override { return nullptr; }
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/qsgdefaultcontext.cpp b/src/quick/scenegraph/qsgdefaultcontext.cpp
index be5fec9dab..9a0ac66690 100644
--- a/src/quick/scenegraph/qsgdefaultcontext.cpp
+++ b/src/quick/scenegraph/qsgdefaultcontext.cpp
@@ -149,20 +149,23 @@ void QSGDefaultContext::renderContextInitialized(QSGRenderContext *renderContext
dumped = true;
QSurfaceFormat format = openglRenderContext->openglContext()->format();
QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
- qCDebug(QSG_LOG_INFO) << "R/G/B/A Buffers: " << format.redBufferSize() << format.greenBufferSize() << format.blueBufferSize() << format.alphaBufferSize();
- qCDebug(QSG_LOG_INFO) << "Depth Buffer: " << format.depthBufferSize();
- qCDebug(QSG_LOG_INFO) << "Stencil Buffer: " << format.stencilBufferSize();
- qCDebug(QSG_LOG_INFO) << "Samples: " << format.samples();
- qCDebug(QSG_LOG_INFO) << "GL_VENDOR: " << (const char *) funcs->glGetString(GL_VENDOR);
- qCDebug(QSG_LOG_INFO) << "GL_RENDERER: " << (const char *) funcs->glGetString(GL_RENDERER);
- qCDebug(QSG_LOG_INFO) << "GL_VERSION: " << (const char *) funcs->glGetString(GL_VERSION);
+ qCDebug(QSG_LOG_INFO, "R/G/B/A Buffers: %d %d %d %d", format.redBufferSize(),
+ format.greenBufferSize(), format.blueBufferSize(), format.alphaBufferSize());
+ qCDebug(QSG_LOG_INFO, "Depth Buffer: %d", format.depthBufferSize());
+ qCDebug(QSG_LOG_INFO, "Stencil Buffer: %d", format.stencilBufferSize());
+ qCDebug(QSG_LOG_INFO, "Samples: %d", format.samples());
+ qCDebug(QSG_LOG_INFO, "GL_VENDOR: %s", (const char*)funcs->glGetString(GL_VENDOR));
+ qCDebug(QSG_LOG_INFO, "GL_RENDERER: %s",
+ (const char*)funcs->glGetString(GL_RENDERER));
+ qCDebug(QSG_LOG_INFO, "GL_VERSION: %s", (const char*)funcs->glGetString(GL_VERSION));
QSet<QByteArray> exts = openglRenderContext->openglContext()->extensions();
QByteArray all;
for (const QByteArray &e : qAsConst(exts))
all += ' ' + e;
- qCDebug(QSG_LOG_INFO) << "GL_EXTENSIONS: " << all.constData();
- qCDebug(QSG_LOG_INFO) << "Max Texture Size: " << openglRenderContext->maxTextureSize();
- qCDebug(QSG_LOG_INFO) << "Debug context: " << format.testOption(QSurfaceFormat::DebugContext);
+ qCDebug(QSG_LOG_INFO, "GL_EXTENSIONS: %s", all.constData());
+ qCDebug(QSG_LOG_INFO, "Max Texture Size: %d", openglRenderContext->maxTextureSize());
+ qCDebug(QSG_LOG_INFO, "Debug context: %s",
+ format.testOption(QSurfaceFormat::DebugContext) ? "true" : "false");
}
m_mutex.unlock();
diff --git a/src/quick/scenegraph/qsgdefaultcontext_p.h b/src/quick/scenegraph/qsgdefaultcontext_p.h
index b2964bf403..6dfd197cf6 100644
--- a/src/quick/scenegraph/qsgdefaultcontext_p.h
+++ b/src/quick/scenegraph/qsgdefaultcontext_p.h
@@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE
class Q_QUICK_PRIVATE_EXPORT QSGDefaultContext : public QSGContext, public QSGRendererInterface
{
public:
- QSGDefaultContext(QObject *parent = 0);
+ QSGDefaultContext(QObject *parent = nullptr);
~QSGDefaultContext();
void renderContextInitialized(QSGRenderContext *renderContext) override;
diff --git a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp
index 7789ef8fb1..ef189ba461 100644
--- a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp
+++ b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp
@@ -63,12 +63,12 @@ QSGDefaultDistanceFieldGlyphCache::QSGDefaultDistanceFieldGlyphCache(QOpenGLCont
: QSGDistanceFieldGlyphCache(c, font)
, m_maxTextureSize(0)
, m_maxTextureCount(3)
- , m_blitProgram(0)
+ , m_blitProgram(nullptr)
, m_blitBuffer(QOpenGLBuffer::VertexBuffer)
- , m_fboGuard(0)
+ , m_fboGuard(nullptr)
, m_funcs(c->functions())
#if !defined(QT_OPENGL_ES_2)
- , m_coreFuncs(0)
+ , m_coreFuncs(nullptr)
#endif
{
if (Q_LIKELY(m_blitBuffer.create())) {
@@ -89,7 +89,7 @@ QSGDefaultDistanceFieldGlyphCache::~QSGDefaultDistanceFieldGlyphCache()
for (int i = 0; i < m_textures.count(); ++i)
m_funcs->glDeleteTextures(1, &m_textures[i].texture);
- if (m_fboGuard != 0)
+ if (m_fboGuard != nullptr)
m_fboGuard->free();
delete m_blitProgram;
@@ -400,7 +400,7 @@ void QSGDefaultDistanceFieldGlyphCache::resizeTexture(TextureInfo *texInfo, int
m_funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
#endif
m_funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, oldWidth, oldHeight, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
m_funcs->glBindTexture(GL_TEXTURE_2D, 0);
m_funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, tmp_texture, 0);
diff --git a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h
index fe365495c2..76c0d20647 100644
--- a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h
+++ b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h
@@ -91,10 +91,9 @@ private:
QSize size;
QRect allocatedArea;
QDistanceField image;
- int padding;
+ int padding = -1;
- TextureInfo(const QRect &preallocRect = QRect()) : texture(0), allocatedArea(preallocRect), padding(-1)
- { }
+ TextureInfo(const QRect &preallocRect = QRect()) : texture(0), allocatedArea(preallocRect) { }
};
void createTexture(TextureInfo * texInfo, int width, int height);
diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
index 0169f097bc..dc473a6640 100644
--- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
+++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
@@ -107,7 +107,7 @@ protected:
char const *const *QSGTextMaskShader::attributeNames() const
{
- static char const *const attr[] = { "vCoord", "tCoord", 0 };
+ static char const *const attr[] = { "vCoord", "tCoord", nullptr };
return attr;
}
@@ -141,13 +141,13 @@ void QSGTextMaskShader::updateState(const RenderState &state, QSGMaterial *newEf
{
QSGTextMaskMaterial *material = static_cast<QSGTextMaskMaterial *>(newEffect);
QSGTextMaskMaterial *oldMaterial = static_cast<QSGTextMaskMaterial *>(oldEffect);
- Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type());
+ Q_ASSERT(oldEffect == nullptr || newEffect->type() == oldEffect->type());
bool updated = material->ensureUpToDate();
Q_ASSERT(material->texture());
- Q_ASSERT(oldMaterial == 0 || oldMaterial->texture());
+ Q_ASSERT(oldMaterial == nullptr || oldMaterial->texture());
if (updated
- || oldMaterial == 0
+ || oldMaterial == nullptr
|| oldMaterial->texture()->textureId() != material->texture()->textureId()) {
program()->setUniformValue(m_textureScale_id, QVector2D(1.0 / material->cacheTextureWidth(),
1.0 / material->cacheTextureHeight()));
@@ -190,7 +190,7 @@ void QSG8BitTextMaskShader::updateState(const RenderState &state, QSGMaterial *n
QSGTextMaskMaterial *material = static_cast<QSGTextMaskMaterial *>(newEffect);
QSGTextMaskMaterial *oldMaterial = static_cast<QSGTextMaskMaterial *>(oldEffect);
- if (oldMaterial == 0 || material->color() != oldMaterial->color() || state.isOpacityDirty()) {
+ if (oldMaterial == nullptr || material->color() != oldMaterial->color() || state.isOpacityDirty()) {
QVector4D color = qsg_premultiply(material->color(), state.opacity());
program()->setUniformValue(m_color_id, color);
}
@@ -282,7 +282,7 @@ void QSG24BitTextMaskShader::updateState(const RenderState &state, QSGMaterial *
QSGTextMaskMaterial *material = static_cast<QSGTextMaskMaterial *>(newEffect);
QSGTextMaskMaterial *oldMaterial = static_cast<QSGTextMaskMaterial *>(oldEffect);
- if (oldMaterial == 0 || material->color() != oldMaterial->color() || state.isOpacityDirty()) {
+ if (oldMaterial == nullptr || material->color() != oldMaterial->color() || state.isOpacityDirty()) {
QVector4D color = material->color();
if (useSRGB())
color = qt_sRGB_to_linear_RGB(color);
@@ -346,20 +346,20 @@ void QSGStyledTextShader::updateState(const RenderState &state,
QSGMaterial *newEffect,
QSGMaterial *oldEffect)
{
- Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type());
+ Q_ASSERT(oldEffect == nullptr || newEffect->type() == oldEffect->type());
QSGStyledTextMaterial *material = static_cast<QSGStyledTextMaterial *>(newEffect);
QSGStyledTextMaterial *oldMaterial = static_cast<QSGStyledTextMaterial *>(oldEffect);
- if (oldMaterial == 0 || oldMaterial->styleShift() != material->styleShift())
+ if (oldMaterial == nullptr || oldMaterial->styleShift() != material->styleShift())
program()->setUniformValue(m_shift_id, material->styleShift());
- if (oldMaterial == 0 || material->color() != oldMaterial->color() || state.isOpacityDirty()) {
+ if (oldMaterial == nullptr || material->color() != oldMaterial->color() || state.isOpacityDirty()) {
QVector4D color = qsg_premultiply(material->color(), state.opacity());
program()->setUniformValue(m_color_id, color);
}
- if (oldMaterial == 0 || material->styleColor() != oldMaterial->styleColor() || state.isOpacityDirty()) {
+ if (oldMaterial == nullptr || material->styleColor() != oldMaterial->styleColor() || state.isOpacityDirty()) {
QVector4D styleColor = qsg_premultiply(material->styleColor(), state.opacity());
program()->setUniformValue(m_styleColor_id, styleColor);
}
@@ -367,9 +367,9 @@ void QSGStyledTextShader::updateState(const RenderState &state,
bool updated = material->ensureUpToDate();
Q_ASSERT(material->texture());
- Q_ASSERT(oldMaterial == 0 || oldMaterial->texture());
+ Q_ASSERT(oldMaterial == nullptr || oldMaterial->texture());
if (updated
- || oldMaterial == 0
+ || oldMaterial == nullptr
|| oldMaterial->texture()->textureId() != material->texture()->textureId()) {
program()->setUniformValue(m_textureScale_id, QVector2D(1.0 / material->cacheTextureWidth(),
1.0 / material->cacheTextureHeight()));
@@ -400,8 +400,8 @@ public:
};
QSGTextMaskMaterial::QSGTextMaskMaterial(const QRawFont &font, QFontEngine::GlyphFormat glyphFormat)
- : m_texture(0)
- , m_glyphCache(0)
+ : m_texture(nullptr)
+ , m_glyphCache(nullptr)
, m_font(font)
{
init(glyphFormat);
@@ -419,7 +419,7 @@ void QSGTextMaskMaterial::init(QFontEngine::GlyphFormat glyphFormat)
setFlag(Blending, true);
QOpenGLContext *ctx = const_cast<QOpenGLContext *>(QOpenGLContext::currentContext());
- Q_ASSERT(ctx != 0);
+ Q_ASSERT(ctx != nullptr);
// The following piece of code will read/write to the font engine's caches,
// potentially from different threads. However, this is safe because this
diff --git a/src/quick/scenegraph/qsgdefaultinternalimagenode.cpp b/src/quick/scenegraph/qsgdefaultinternalimagenode.cpp
index a5a6da06a7..5dd6eaa4ca 100644
--- a/src/quick/scenegraph/qsgdefaultinternalimagenode.cpp
+++ b/src/quick/scenegraph/qsgdefaultinternalimagenode.cpp
@@ -83,7 +83,6 @@ QSGMaterialShader *QSGSmoothTextureMaterial::createShader() const
}
SmoothTextureMaterialShader::SmoothTextureMaterialShader()
- : QSGTextureMaterialShader()
{
setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/smoothtexture.vert"));
setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/smoothtexture.frag"));
@@ -91,7 +90,7 @@ SmoothTextureMaterialShader::SmoothTextureMaterialShader()
void SmoothTextureMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
{
- if (oldEffect == 0) {
+ if (oldEffect == nullptr) {
// The viewport is constant, so set the pixel size uniform only once.
QRect r = state.viewportRect();
program()->setUniformValue(m_pixelSizeLoc, 2.0f / r.width(), 2.0f / r.height());
@@ -106,7 +105,7 @@ char const *const *SmoothTextureMaterialShader::attributeNames() const
"multiTexCoord",
"vertexOffset",
"texCoordOffset",
- 0
+ nullptr
};
return attributes;
}
@@ -171,7 +170,7 @@ void QSGDefaultInternalImageNode::updateMaterialAntialiasing()
{
if (m_antialiasing) {
setMaterial(&m_smoothMaterial);
- setOpaqueMaterial(0);
+ setOpaqueMaterial(nullptr);
} else {
setMaterial(&m_materialO);
setOpaqueMaterial(&m_material);
diff --git a/src/quick/scenegraph/qsgdefaultinternalrectanglenode.cpp b/src/quick/scenegraph/qsgdefaultinternalrectanglenode.cpp
index e52dcaad52..fd0dcebd57 100644
--- a/src/quick/scenegraph/qsgdefaultinternalrectanglenode.cpp
+++ b/src/quick/scenegraph/qsgdefaultinternalrectanglenode.cpp
@@ -67,7 +67,6 @@ private:
};
SmoothColorMaterialShader::SmoothColorMaterialShader()
- : QSGMaterialShader()
{
setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/smoothcolor.vert"));
setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/smoothcolor.frag"));
@@ -81,7 +80,7 @@ void SmoothColorMaterialShader::updateState(const RenderState &state, QSGMateria
if (state.isMatrixDirty())
program()->setUniformValue(m_matrixLoc, state.combinedMatrix());
- if (oldEffect == 0) {
+ if (oldEffect == nullptr) {
// The viewport is constant, so set the pixel size uniform only once.
QRect r = state.viewportRect();
program()->setUniformValue(m_pixelSizeLoc, 2.0f / r.width(), 2.0f / r.height());
@@ -94,7 +93,7 @@ char const *const *SmoothColorMaterialShader::attributeNames() const
"vertex",
"vertexColor",
"vertexOffset",
- 0
+ nullptr
};
return attributes;
}
diff --git a/src/quick/scenegraph/qsgdefaultlayer.cpp b/src/quick/scenegraph/qsgdefaultlayer.cpp
index cd9c4a9a90..b2b123912f 100644
--- a/src/quick/scenegraph/qsgdefaultlayer.cpp
+++ b/src/quick/scenegraph/qsgdefaultlayer.cpp
@@ -90,15 +90,15 @@ namespace
QSGDefaultLayer::QSGDefaultLayer(QSGRenderContext *context)
: QSGLayer()
- , m_item(0)
+ , m_item(nullptr)
, m_device_pixel_ratio(1)
, m_format(GL_RGBA)
- , m_renderer(0)
- , m_fbo(0)
- , m_secondaryFbo(0)
+ , m_renderer(nullptr)
+ , m_fbo(nullptr)
+ , m_secondaryFbo(nullptr)
, m_transparentTexture(0)
#ifdef QSG_DEBUG_FBO_OVERLAY
- , m_debugOverlay(0)
+ , m_debugOverlay(nullptr)
#endif
, m_samples(0)
, m_mipmap(false)
@@ -122,13 +122,13 @@ QSGDefaultLayer::~QSGDefaultLayer()
void QSGDefaultLayer::invalidated()
{
delete m_renderer;
- m_renderer = 0;
+ m_renderer = nullptr;
delete m_fbo;
delete m_secondaryFbo;
- m_fbo = m_secondaryFbo = 0;
+ m_fbo = m_secondaryFbo = nullptr;
#ifdef QSG_DEBUG_FBO_OVERLAY
delete m_debugOverlay;
- m_debugOverlay = 0;
+ m_debugOverlay = nullptr;
#endif
if (m_transparentTexture) {
QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &m_transparentTexture);
@@ -204,7 +204,7 @@ void QSGDefaultLayer::setItem(QSGNode *item)
if (m_live && !m_item) {
delete m_fbo;
delete m_secondaryFbo;
- m_fbo = m_secondaryFbo = 0;
+ m_fbo = m_secondaryFbo = nullptr;
m_depthStencilBuffer.clear();
}
@@ -228,7 +228,7 @@ void QSGDefaultLayer::setSize(const QSize &size)
if (m_live && m_size.isNull()) {
delete m_fbo;
delete m_secondaryFbo;
- m_fbo = m_secondaryFbo = 0;
+ m_fbo = m_secondaryFbo = nullptr;
m_depthStencilBuffer.clear();
}
@@ -252,7 +252,7 @@ void QSGDefaultLayer::setLive(bool live)
if (m_live && (!m_item || m_size.isNull())) {
delete m_fbo;
delete m_secondaryFbo;
- m_fbo = m_secondaryFbo = 0;
+ m_fbo = m_secondaryFbo = nullptr;
m_depthStencilBuffer.clear();
}
@@ -295,7 +295,7 @@ void QSGDefaultLayer::grab()
if (!m_item || m_size.isNull()) {
delete m_fbo;
delete m_secondaryFbo;
- m_fbo = m_secondaryFbo = 0;
+ m_fbo = m_secondaryFbo = nullptr;
m_depthStencilBuffer.clear();
m_dirtyTexture = false;
return;
@@ -362,7 +362,7 @@ void QSGDefaultLayer::grab()
delete m_fbo;
delete m_secondaryFbo;
m_fbo = new QOpenGLFramebufferObject(m_size, format);
- m_secondaryFbo = 0;
+ m_secondaryFbo = nullptr;
funcs->glBindTexture(GL_TEXTURE_2D, m_fbo->texture());
updateBindOptions(true);
m_depthStencilBuffer = m_context->depthStencilBufferForFbo(m_fbo);
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
index 95f3555994..7882496062 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp
+++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
@@ -44,6 +44,7 @@
#include <QtQuick/private/qsgbatchrenderer_p.h>
#include <QtQuick/private/qsgrenderer_p.h>
#include <QtQuick/private/qsgatlastexture_p.h>
+#include <QtQuick/private/qsgcompressedtexture_p.h>
#include <QtQuick/private/qsgdefaultdistancefieldglyphcache_p.h>
QT_BEGIN_NAMESPACE
@@ -156,14 +157,14 @@ void QSGDefaultRenderContext::invalidate()
m_fontEnginesToClean.clear();
delete m_depthStencilManager;
- m_depthStencilManager = 0;
+ m_depthStencilManager = nullptr;
qDeleteAll(m_glyphCaches);
m_glyphCaches.clear();
if (m_gl->property(QSG_RENDERCONTEXT_PROPERTY) == QVariant::fromValue(this))
m_gl->setProperty(QSG_RENDERCONTEXT_PROPERTY, QVariant());
- m_gl = 0;
+ m_gl = nullptr;
if (m_sg)
m_sg->renderContextInvalidated(this);
@@ -210,7 +211,7 @@ QSharedPointer<QSGDepthStencilBuffer> QSGDefaultRenderContext::depthStencilBuffe
QSGDepthStencilBufferManager *QSGDefaultRenderContext::depthStencilBufferManager()
{
if (!m_gl)
- return 0;
+ return nullptr;
if (!m_depthStencilManager)
m_depthStencilManager = new QSGDepthStencilBufferManager(m_gl);
return m_depthStencilManager;
@@ -243,6 +244,14 @@ QSGRenderer *QSGDefaultRenderContext::createRenderer()
return new QSGBatchRenderer::Renderer(this);
}
+QSGTexture *QSGDefaultRenderContext::compressedTextureForFactory(const QSGCompressedTextureFactory *factory) const
+{
+ // The atlas implementation is only supported from the render thread
+ if (openglContext() && QThread::currentThread() == openglContext()->thread())
+ return m_atlasManager->create(factory);
+ return nullptr;
+}
+
/*!
Compile \a shader, optionally using \a vertexCode and \a fragmentCode as
replacement for the source code supplied by \a shader.
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext_p.h b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
index 2537a06988..eb62586a94 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext_p.h
+++ b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
@@ -84,8 +84,9 @@ public:
QSGTexture *createTexture(const QImage &image, uint flags) const override;
QSGRenderer *createRenderer() override;
+ QSGTexture *compressedTextureForFactory(const QSGCompressedTextureFactory *factory) const override;
- virtual void compileShader(QSGMaterialShader *shader, QSGMaterial *material, const char *vertexCode = 0, const char *fragmentCode = 0);
+ virtual void compileShader(QSGMaterialShader *shader, QSGMaterial *material, const char *vertexCode = nullptr, const char *fragmentCode = nullptr);
virtual void initializeShader(QSGMaterialShader *shader);
void setAttachToGraphicsContext(bool attach) override;
diff --git a/src/quick/scenegraph/qsgdefaultspritenode.cpp b/src/quick/scenegraph/qsgdefaultspritenode.cpp
index 7fe6048d59..8761d99c1f 100644
--- a/src/quick/scenegraph/qsgdefaultspritenode.cpp
+++ b/src/quick/scenegraph/qsgdefaultspritenode.cpp
@@ -70,26 +70,18 @@ public:
return this - static_cast<const QQuickSpriteMaterial *>(other);
}
- QSGTexture *texture;
-
- float animT;
- float animX1;
- float animY1;
- float animX2;
- float animY2;
- float animW;
- float animH;
+ QSGTexture *texture = nullptr;
+
+ float animT = 0.0f;
+ float animX1 = 0.0f;
+ float animY1 = 0.0f;
+ float animX2 = 0.0f;
+ float animY2 = 0.0f;
+ float animW = 1.0f;
+ float animH = 1.0f;
};
QQuickSpriteMaterial::QQuickSpriteMaterial()
- : texture(0)
- , animT(0.0f)
- , animX1(0.0f)
- , animY1(0.0f)
- , animX2(0.0f)
- , animY2(0.0f)
- , animW(1.0f)
- , animH(1.0f)
{
setFlag(Blending, true);
}
@@ -103,7 +95,6 @@ class SpriteMaterialData : public QSGMaterialShader
{
public:
SpriteMaterialData()
- : QSGMaterialShader()
{
setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/sprite.vert"));
setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/sprite.frag"));
@@ -133,7 +124,7 @@ public:
static const char *attr[] = {
"vPos",
"vTex",
- 0
+ nullptr
};
return attr;
}
diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp b/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp
index 32eda2d142..ae6336718e 100644
--- a/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp
+++ b/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp
@@ -46,12 +46,12 @@ QT_BEGIN_NAMESPACE
QSGDistanceFieldGlyphNode::QSGDistanceFieldGlyphNode(QSGRenderContext *context)
: m_glyphNodeType(RootGlyphNode)
, m_context(context)
- , m_material(0)
- , m_glyph_cache(0)
+ , m_material(nullptr)
+ , m_glyph_cache(nullptr)
, m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 0)
, m_style(QQuickText::Normal)
, m_antialiasingMode(GrayAntialiasing)
- , m_texture(0)
+ , m_texture(nullptr)
, m_dirtyGeometry(false)
, m_dirtyMaterial(false)
{
@@ -80,7 +80,7 @@ QSGDistanceFieldGlyphNode::~QSGDistanceFieldGlyphNode()
void QSGDistanceFieldGlyphNode::setColor(const QColor &color)
{
m_color = color;
- if (m_material != 0) {
+ if (m_material != nullptr) {
m_material->setColor(color);
markDirty(DirtyMaterial);
} else {
@@ -113,7 +113,7 @@ void QSGDistanceFieldGlyphNode::setGlyphs(const QPointF &position, const QGlyphR
return;
if (m_glyph_cache != oldCache) {
- Q_ASSERT(ownerElement() != 0);
+ Q_ASSERT(ownerElement() != nullptr);
if (oldCache) {
oldCache->unregisterGlyphNode(this);
oldCache->unregisterOwnerElement(ownerElement());
@@ -181,7 +181,7 @@ void QSGDistanceFieldGlyphNode::updateGeometry()
// Remove previously created sub glyph nodes
// We assume all the children are sub glyph nodes
QSGNode *subnode = firstChild();
- QSGNode *nextNode = 0;
+ QSGNode *nextNode = nullptr;
while (subnode) {
nextNode = subnode->nextSibling();
delete subnode;
diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp
index a67c659c99..aa58218505 100644
--- a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp
+++ b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp
@@ -61,37 +61,27 @@ protected:
void updateColor(const QVector4D &c);
void updateTextureScale(const QVector2D &ts);
- float m_fontScale;
- float m_matrixScale;
+ float m_fontScale = 1.0;
+ float m_matrixScale = 1.0;
- int m_matrix_id;
- int m_textureScale_id;
- int m_alphaMin_id;
- int m_alphaMax_id;
- int m_color_id;
+ int m_matrix_id = -1;
+ int m_textureScale_id = -1;
+ int m_alphaMin_id = -1;
+ int m_alphaMax_id = -1;
+ int m_color_id = -1;
QVector2D m_lastTextureScale;
QVector4D m_lastColor;
- float m_lastAlphaMin;
- float m_lastAlphaMax;
+ float m_lastAlphaMin = -1;
+ float m_lastAlphaMax = -1;
};
char const *const *QSGDistanceFieldTextMaterialShader::attributeNames() const {
- static char const *const attr[] = { "vCoord", "tCoord", 0 };
+ static char const *const attr[] = { "vCoord", "tCoord", nullptr };
return attr;
}
QSGDistanceFieldTextMaterialShader::QSGDistanceFieldTextMaterialShader()
- : QSGMaterialShader(),
- m_fontScale(1.0)
- , m_matrixScale(1.0)
- , m_matrix_id(-1)
- , m_textureScale_id(-1)
- , m_alphaMin_id(-1)
- , m_alphaMax_id(-1)
- , m_color_id(-1)
- , m_lastAlphaMin(-1)
- , m_lastAlphaMax(-1)
{
setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/distancefieldtext.vert"));
setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/distancefieldtext.frag"));
@@ -166,13 +156,13 @@ void QSGDistanceFieldTextMaterialShader::initialize()
void QSGDistanceFieldTextMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
{
- Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type());
+ Q_ASSERT(oldEffect == nullptr || newEffect->type() == oldEffect->type());
QSGDistanceFieldTextMaterial *material = static_cast<QSGDistanceFieldTextMaterial *>(newEffect);
QSGDistanceFieldTextMaterial *oldMaterial = static_cast<QSGDistanceFieldTextMaterial *>(oldEffect);
bool updated = material->updateTextureSize();
- if (oldMaterial == 0
+ if (oldMaterial == nullptr
|| material->color() != oldMaterial->color()
|| state.isOpacityDirty()) {
QVector4D color = material->color();
@@ -181,7 +171,7 @@ void QSGDistanceFieldTextMaterialShader::updateState(const RenderState &state, Q
}
bool updateRange = false;
- if (oldMaterial == 0
+ if (oldMaterial == nullptr
|| material->fontScale() != oldMaterial->fontScale()) {
m_fontScale = material->fontScale();
updateRange = true;
@@ -198,12 +188,12 @@ void QSGDistanceFieldTextMaterialShader::updateState(const RenderState &state, Q
Q_ASSERT(material->glyphCache());
if (updated
- || oldMaterial == 0
+ || oldMaterial == nullptr
|| oldMaterial->texture()->textureId != material->texture()->textureId) {
updateTextureScale(QVector2D(1.0 / material->textureSize().width(),
1.0 / material->textureSize().height()));
- QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
+ QOpenGLFunctions *funcs = state.context()->functions();
funcs->glBindTexture(GL_TEXTURE_2D, material->texture()->textureId);
if (updated) {
@@ -218,8 +208,8 @@ void QSGDistanceFieldTextMaterialShader::updateState(const RenderState &state, Q
}
QSGDistanceFieldTextMaterial::QSGDistanceFieldTextMaterial()
- : m_glyph_cache(0)
- , m_texture(0)
+ : m_glyph_cache(nullptr)
+ , m_texture(nullptr)
, m_fontScale(1.0)
{
setFlag(Blending | RequiresDeterminant, true);
@@ -288,12 +278,11 @@ public:
protected:
void initialize() override;
- int m_styleColor_id;
+ int m_styleColor_id = -1;
};
DistanceFieldStyledTextMaterialShader::DistanceFieldStyledTextMaterialShader()
: QSGDistanceFieldTextMaterialShader()
- , m_styleColor_id(-1)
{
}
@@ -310,7 +299,7 @@ void DistanceFieldStyledTextMaterialShader::updateState(const RenderState &state
QSGDistanceFieldStyledTextMaterial *material = static_cast<QSGDistanceFieldStyledTextMaterial *>(newEffect);
QSGDistanceFieldStyledTextMaterial *oldMaterial = static_cast<QSGDistanceFieldStyledTextMaterial *>(oldEffect);
- if (oldMaterial == 0
+ if (oldMaterial == nullptr
|| material->styleColor() != oldMaterial->styleColor()
|| (state.isOpacityDirty())) {
QVector4D color = material->styleColor();
@@ -358,14 +347,12 @@ protected:
void updateOutlineAlphaRange(int dfRadius);
- int m_outlineAlphaMax0_id;
- int m_outlineAlphaMax1_id;
+ int m_outlineAlphaMax0_id = -1;
+ int m_outlineAlphaMax1_id = -1;
};
DistanceFieldOutlineTextMaterialShader::DistanceFieldOutlineTextMaterialShader()
: DistanceFieldStyledTextMaterialShader()
- , m_outlineAlphaMax0_id(-1)
- , m_outlineAlphaMax1_id(-1)
{
setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/distancefieldoutlinetext.frag"));
}
@@ -398,7 +385,7 @@ void DistanceFieldOutlineTextMaterialShader::updateState(const RenderState &stat
QSGDistanceFieldOutlineTextMaterial *material = static_cast<QSGDistanceFieldOutlineTextMaterial *>(newEffect);
QSGDistanceFieldOutlineTextMaterial *oldMaterial = static_cast<QSGDistanceFieldOutlineTextMaterial *>(oldEffect);
- if (oldMaterial == 0
+ if (oldMaterial == nullptr
|| material->fontScale() != oldMaterial->fontScale()
|| state.isMatrixDirty())
updateOutlineAlphaRange(material->glyphCache()->distanceFieldRadius());
@@ -438,12 +425,11 @@ protected:
void updateShift(qreal fontScale, const QPointF& shift);
- int m_shift_id;
+ int m_shift_id = -1;
};
DistanceFieldShiftedStyleTextMaterialShader::DistanceFieldShiftedStyleTextMaterialShader()
: DistanceFieldStyledTextMaterialShader()
- , m_shift_id(-1)
{
setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/distancefieldshiftedtext.vert"));
setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/distancefieldshiftedtext.frag"));
@@ -462,7 +448,7 @@ void DistanceFieldShiftedStyleTextMaterialShader::updateState(const RenderState
QSGDistanceFieldShiftedStyleTextMaterial *material = static_cast<QSGDistanceFieldShiftedStyleTextMaterial *>(newEffect);
QSGDistanceFieldShiftedStyleTextMaterial *oldMaterial = static_cast<QSGDistanceFieldShiftedStyleTextMaterial *>(oldEffect);
- if (oldMaterial == 0
+ if (oldMaterial == nullptr
|| oldMaterial->fontScale() != material->fontScale()
|| oldMaterial->shift() != material->shift()
|| oldMaterial->textureSize() != material->textureSize()) {
@@ -516,14 +502,12 @@ public:
void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
private:
- int m_fontScale_id;
- int m_vecDelta_id;
+ int m_fontScale_id = -1;
+ int m_vecDelta_id = -1;
};
QSGHiQSubPixelDistanceFieldTextMaterialShader::QSGHiQSubPixelDistanceFieldTextMaterialShader()
: QSGDistanceFieldTextMaterialShader()
- , m_fontScale_id(-1)
- , m_vecDelta_id(-1)
{
setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/hiqsubpixeldistancefieldtext.vert"));
setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/hiqsubpixeldistancefieldtext.frag"));
@@ -550,19 +534,19 @@ void QSGHiQSubPixelDistanceFieldTextMaterialShader::deactivate()
void QSGHiQSubPixelDistanceFieldTextMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
{
- Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type());
+ Q_ASSERT(oldEffect == nullptr || newEffect->type() == oldEffect->type());
QSGDistanceFieldTextMaterial *material = static_cast<QSGDistanceFieldTextMaterial *>(newEffect);
QSGDistanceFieldTextMaterial *oldMaterial = static_cast<QSGDistanceFieldTextMaterial *>(oldEffect);
- if (oldMaterial == 0 || material->color() != oldMaterial->color()) {
+ if (oldMaterial == nullptr || material->color() != oldMaterial->color()) {
QVector4D c = material->color();
state.context()->functions()->glBlendColor(c.x(), c.y(), c.z(), 1.0f);
}
- if (oldMaterial == 0 || material->fontScale() != oldMaterial->fontScale())
+ if (oldMaterial == nullptr || material->fontScale() != oldMaterial->fontScale())
program()->setUniformValue(m_fontScale_id, GLfloat(material->fontScale()));
- if (oldMaterial == 0 || state.isMatrixDirty()) {
+ if (oldMaterial == nullptr || state.isMatrixDirty()) {
int viewportWidth = state.viewportRect().width();
QMatrix4x4 mat = state.combinedMatrix().inverted();
program()->setUniformValue(m_vecDelta_id, mat.column(0) * (qreal(2) / viewportWidth));
diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp
index 58450d7a50..9e5cc27cd8 100644
--- a/src/quick/scenegraph/qsgrenderloop.cpp
+++ b/src/quick/scenegraph/qsgrenderloop.cpp
@@ -76,7 +76,7 @@ QT_BEGIN_NAMESPACE
extern bool qsg_useConsistentTiming();
extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha);
#if QT_CONFIG(opengl)
-/*!
+/*
expectations for this manager to work:
- one opengl context to render multiple windows
- OpenGL pipeline will not block for vsync in swap
@@ -88,7 +88,7 @@ extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_
DEFINE_BOOL_CONFIG_OPTION(qmlNoThreadedRenderer, QML_BAD_GUI_RENDER_LOOP);
DEFINE_BOOL_CONFIG_OPTION(qmlForceThreadedRenderer, QML_FORCE_THREADED_RENDERER); // Might trigger graphics driver threading bugs, use at own risk
#endif
-QSGRenderLoop *QSGRenderLoop::s_instance = 0;
+QSGRenderLoop *QSGRenderLoop::s_instance = nullptr;
QSGRenderLoop::~QSGRenderLoop()
{
@@ -107,11 +107,11 @@ void QSGRenderLoop::cleanup()
QQuickWindowPrivate *wd = QQuickWindowPrivate::get(w);
if (wd->windowManager == s_instance) {
s_instance->windowDestroyed(w);
- wd->windowManager = 0;
+ wd->windowManager = nullptr;
}
}
delete s_instance;
- s_instance = 0;
+ s_instance = nullptr;
}
/*!
@@ -155,7 +155,7 @@ public:
void releaseResources(QQuickWindow *) override;
- QAnimationDriver *animationDriver() const override { return 0; }
+ QAnimationDriver *animationDriver() const override { return nullptr; }
QSGContext *sceneGraphContext() const override;
QSGRenderContext *createRenderContext(QSGContext *) const override { return rc; }
@@ -282,7 +282,7 @@ void QSGRenderLoop::handleContextCreationFailure(QQuickWindow *window,
}
#if QT_CONFIG(opengl)
QSGGuiThreadRenderLoop::QSGGuiThreadRenderLoop()
- : gl(0)
+ : gl(nullptr)
{
if (qsg_useConsistentTiming()) {
QUnifiedTimer::instance(true)->setConsistentTiming(true);
@@ -334,7 +334,7 @@ void QSGGuiThreadRenderLoop::windowDestroyed(QQuickWindow *window)
current = gl->makeCurrent(surface);
}
if (Q_UNLIKELY(!current))
- qCDebug(QSG_LOG_RENDERLOOP) << "cleanup without an OpenGL context";
+ qCDebug(QSG_LOG_RENDERLOOP, "cleanup without an OpenGL context");
#if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl)
QQuickOpenGLShaderEffectMaterial::cleanupMaterialCache();
@@ -344,7 +344,7 @@ void QSGGuiThreadRenderLoop::windowDestroyed(QQuickWindow *window)
if (m_windows.size() == 0) {
rc->invalidate();
delete gl;
- gl = 0;
+ gl = nullptr;
} else if (gl && window == gl->surface() && current) {
gl->doneCurrent();
}
@@ -371,7 +371,7 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
if (!gl->create()) {
const bool isEs = gl->isOpenGLES();
delete gl;
- gl = 0;
+ gl = nullptr;
handleContextCreationFailure(window, isEs);
} else {
cd->fireOpenGLContextCreated(gl);
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index 4a712d3cdd..8262708320 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -115,7 +115,7 @@
QT_BEGIN_NAMESPACE
-#define QSG_RT_PAD " (RT)"
+#define QSG_RT_PAD " (RT) %s"
static inline int qsgrl_animation_interval() {
qreal refreshRate = QGuiApplication::primaryScreen()->refreshRate();
@@ -167,7 +167,7 @@ template <typename T> T *windowFor(const QList<T> &list, QQuickWindow *window)
if (t.window == window)
return const_cast<T *>(&t);
}
- return 0;
+ return nullptr;
}
@@ -270,13 +270,13 @@ class QSGRenderThread : public QThread
public:
QSGRenderThread(QSGThreadedRenderLoop *w, QSGRenderContext *renderContext)
: wm(w)
- , gl(0)
- , animatorDriver(0)
+ , gl(nullptr)
+ , animatorDriver(nullptr)
, pendingUpdate(0)
, sleeping(false)
, syncResultedInChanges(false)
, active(false)
- , window(0)
+ , window(nullptr)
, stopEventProcessing(false)
{
sgrc = static_cast<QSGDefaultRenderContext *>(renderContext);
@@ -315,7 +315,7 @@ public:
public slots:
void sceneGraphChanged() {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "sceneGraphChanged";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "sceneGraphChanged");
syncResultedInChanges = true;
}
@@ -358,15 +358,15 @@ bool QSGRenderThread::event(QEvent *e)
switch ((int) e->type()) {
case WM_Obscure: {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "WM_Obscure";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "WM_Obscure");
Q_ASSERT(!window || window == static_cast<WMWindowEvent *>(e)->window);
mutex.lock();
if (window) {
QQuickWindowPrivate::get(window)->fireAboutToStop();
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- window removed";
- window = 0;
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- window removed");
+ window = nullptr;
}
waitCondition.wakeOne();
mutex.unlock();
@@ -374,7 +374,7 @@ bool QSGRenderThread::event(QEvent *e)
return true; }
case WM_RequestSync: {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "WM_RequestSync";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "WM_RequestSync");
WMSyncEvent *se = static_cast<WMSyncEvent *>(e);
if (sleeping)
stopEventProcessing = true;
@@ -383,33 +383,33 @@ bool QSGRenderThread::event(QEvent *e)
pendingUpdate |= SyncRequest;
if (se->syncInExpose) {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- triggered from expose";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- triggered from expose");
pendingUpdate |= ExposeRequest;
}
if (se->forceRenderPass) {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- repaint regardless";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- repaint regardless");
pendingUpdate |= RepaintRequest;
}
return true; }
case WM_TryRelease: {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "WM_TryRelease";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "WM_TryRelease");
mutex.lock();
wm->m_lockedForSync = true;
WMTryReleaseEvent *wme = static_cast<WMTryReleaseEvent *>(e);
if (!window || wme->inDestructor) {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- setting exit flag and invalidating OpenGL";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- setting exit flag and invalidating OpenGL");
invalidateOpenGL(wme->window, wme->inDestructor, wme->fallbackSurface);
active = gl;
Q_ASSERT_X(!wme->inDestructor || !active, "QSGRenderThread::invalidateOpenGL()", "Thread's active state is not set to false when shutting down");
if (sleeping)
stopEventProcessing = true;
} else {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- not releasing because window is still active";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- not releasing because window is still active");
if (window) {
QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
if (d->renderer) {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- requesting renderer to release cached resources";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- requesting renderer to release cached resources");
d->renderer->releaseCachedResources();
}
}
@@ -421,7 +421,7 @@ bool QSGRenderThread::event(QEvent *e)
}
case WM_Grab: {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "WM_Grab";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "WM_Grab");
WMGrabEvent *ce = static_cast<WMGrabEvent *>(e);
Q_ASSERT(ce->window);
Q_ASSERT(ce->window == window || !window);
@@ -429,41 +429,41 @@ bool QSGRenderThread::event(QEvent *e)
if (ce->window) {
gl->makeCurrent(ce->window);
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- sync scene graph";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- sync scene graph");
QQuickWindowPrivate *d = QQuickWindowPrivate::get(ce->window);
d->syncSceneGraph();
sgrc->endSync();
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- rendering scene graph";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- rendering scene graph");
QQuickWindowPrivate::get(ce->window)->renderSceneGraph(ce->window->size());
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- grabbing result";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- grabbing result");
bool alpha = ce->window->format().alphaBufferSize() > 0 && ce->window->color().alpha() != 255;
*ce->image = qt_gl_read_framebuffer(windowSize * ce->window->effectiveDevicePixelRatio(), alpha, alpha);
ce->image->setDevicePixelRatio(ce->window->effectiveDevicePixelRatio());
}
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- waking gui to handle result";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- waking gui to handle result");
waitCondition.wakeOne();
mutex.unlock();
return true;
}
case WM_PostJob: {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "WM_PostJob";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "WM_PostJob");
WMJobEvent *ce = static_cast<WMJobEvent *>(e);
Q_ASSERT(ce->window == window);
if (window) {
gl->makeCurrent(window);
ce->job->run();
delete ce->job;
- ce->job = 0;
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- job done";
+ ce->job = nullptr;
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- job done");
}
return true;
}
case WM_RequestRepaint:
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "WM_RequestPaint";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "WM_RequestPaint");
// When GUI posts this event, it is followed by a polishAndSync, so we mustn't
// exit the event loop yet.
pendingUpdate |= RepaintRequest;
@@ -477,13 +477,13 @@ bool QSGRenderThread::event(QEvent *e)
void QSGRenderThread::invalidateOpenGL(QQuickWindow *window, bool inDestructor, QOffscreenSurface *fallback)
{
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "invalidateOpenGL()";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "invalidateOpenGL()");
if (!gl)
return;
if (!window) {
- qCWarning(QSG_LOG_RENDERLOOP()) << "QSGThreadedRenderLoop:QSGRenderThread: no window to make current...";
+ qCWarning(QSG_LOG_RENDERLOOP, "QSGThreadedRenderLoop:QSGRenderThread: no window to make current...");
return;
}
@@ -493,7 +493,7 @@ void QSGRenderThread::invalidateOpenGL(QQuickWindow *window, bool inDestructor,
bool current = gl->makeCurrent(fallback ? static_cast<QSurface *>(fallback) : static_cast<QSurface *>(window));
if (Q_UNLIKELY(!current)) {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- cleanup without an OpenGL context";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- cleanup without an OpenGL context");
}
QQuickWindowPrivate *dd = QQuickWindowPrivate::get(window);
@@ -506,7 +506,7 @@ void QSGRenderThread::invalidateOpenGL(QQuickWindow *window, bool inDestructor,
if (wipeSG) {
dd->cleanupNodesOnShutdown();
} else {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- persistent SG, avoiding cleanup";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- persistent SG, avoiding cleanup");
if (current)
gl->doneCurrent();
return;
@@ -514,29 +514,29 @@ void QSGRenderThread::invalidateOpenGL(QQuickWindow *window, bool inDestructor,
sgrc->invalidate();
QCoreApplication::processEvents();
- QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+ QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
if (inDestructor)
delete dd->animationController;
if (current)
gl->doneCurrent();
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- invalidating scene graph";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- invalidating scene graph");
if (wipeGL) {
delete gl;
- gl = 0;
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- invalidated OpenGL";
+ gl = nullptr;
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- invalidated OpenGL");
} else {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- persistent GL, avoiding cleanup";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- persistent GL, avoiding cleanup");
}
}
-/*!
+/*
Enters the mutex lock to make sure GUI is blocking and performs
sync, then wakes GUI.
*/
void QSGRenderThread::sync(bool inExpose)
{
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "sync()";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "sync()");
mutex.lock();
Q_ASSERT_X(wm->m_lockedForSync, "QSGRenderThread::sync()", "sync triggered on bad terms as gui is not already locked...");
@@ -554,7 +554,7 @@ void QSGRenderThread::sync(bool inExpose)
}
if (current) {
QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
- bool hadRenderer = d->renderer != 0;
+ bool hadRenderer = d->renderer != nullptr;
// If the scene graph was touched since the last sync() make sure it sends the
// changed signal.
if (d->renderer)
@@ -562,7 +562,7 @@ void QSGRenderThread::sync(bool inExpose)
d->syncSceneGraph();
sgrc->endSync();
if (!hadRenderer && d->renderer) {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- renderer was created";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- renderer was created");
syncResultedInChanges = true;
connect(d->renderer, SIGNAL(sceneGraphChanged()), this, SLOT(sceneGraphChanged()), Qt::DirectConnection);
}
@@ -570,13 +570,13 @@ void QSGRenderThread::sync(bool inExpose)
// Process deferred deletes now, directly after the sync as
// deleteLater on the GUI must now also have resulted in SG changes
// and the delete is a safe operation.
- QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+ QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
} else {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- window has bad size, sync aborted";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- window has bad size, sync aborted");
}
if (!inExpose) {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- sync complete, waking Gui";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- sync complete, waking Gui");
waitCondition.wakeOne();
mutex.unlock();
}
@@ -594,7 +594,7 @@ void QSGRenderThread::syncAndRender()
QElapsedTimer waitTimer;
waitTimer.start();
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "syncAndRender()";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "syncAndRender()");
syncResultedInChanges = false;
QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
@@ -605,7 +605,7 @@ void QSGRenderThread::syncAndRender()
pendingUpdate = 0;
if (syncRequested) {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- updatePending, doing sync";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- updatePending, doing sync");
sync(exposeRequested);
}
#ifndef QSG_NO_RENDER_TIMING
@@ -616,14 +616,14 @@ void QSGRenderThread::syncAndRender()
QQuickProfiler::SceneGraphRenderLoopSync);
if (!syncResultedInChanges && !repaintRequested && sgrc->isValid()) {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- no changes, render aborted";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- no changes, render aborted");
int waitTime = vsyncDelta - (int) waitTimer.elapsed();
if (waitTime > 0)
msleep(waitTime);
return;
}
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- rendering started";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- rendering started");
if (animatorDriver->isRunning()) {
@@ -653,10 +653,10 @@ void QSGRenderThread::syncAndRender()
} else {
Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSync, 1);
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- window not ready, skipping render";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- window not ready, skipping render");
}
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- rendering done";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- rendering done");
// Though it would be more correct to put this block directly after
// fireFrameSwapped in the if (current) branch above, we don't do
@@ -664,7 +664,7 @@ void QSGRenderThread::syncAndRender()
// has started rendering with a bad window, causing makeCurrent to
// fail or if the window has a bad size.
if (exposeRequested) {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- wake Gui after initial expose";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- wake Gui after initial expose");
waitCondition.wakeOne();
mutex.unlock();
}
@@ -692,31 +692,31 @@ void QSGRenderThread::postEvent(QEvent *e)
void QSGRenderThread::processEvents()
{
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "--- begin processEvents()";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "--- begin processEvents()");
while (eventQueue.hasMoreEvents()) {
QEvent *e = eventQueue.takeEvent(false);
event(e);
delete e;
}
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "--- done processEvents()";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "--- done processEvents()");
}
void QSGRenderThread::processEventsAndWaitForMore()
{
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "--- begin processEventsAndWaitForMore()";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "--- begin processEventsAndWaitForMore()");
stopEventProcessing = false;
while (!stopEventProcessing) {
QEvent *e = eventQueue.takeEvent(true);
event(e);
delete e;
}
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "--- done processEventsAndWaitForMore()";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "--- done processEventsAndWaitForMore()");
}
void QSGRenderThread::run()
{
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "run()";
- animatorDriver = sgrc->sceneGraphContext()->createAnimationDriver(0);
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "run()");
+ animatorDriver = sgrc->sceneGraphContext()->createAnimationDriver(nullptr);
animatorDriver->install();
if (QQmlDebugConnector::service<QQmlProfilerService>())
QQuickProfiler::registerAnimationCallback();
@@ -733,7 +733,7 @@ void QSGRenderThread::run()
QCoreApplication::processEvents();
if (active && (pendingUpdate == 0 || !window)) {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "done drawing, sleep...";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "done drawing, sleep...");
sleeping = true;
processEventsAndWaitForMore();
sleeping = false;
@@ -742,10 +742,10 @@ void QSGRenderThread::run()
Q_ASSERT_X(!gl, "QSGRenderThread::run()", "The OpenGL context should be cleaned up before exiting the render thread...");
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "run() completed";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "run() completed");
delete animatorDriver;
- animatorDriver = 0;
+ animatorDriver = nullptr;
sgrc->moveToThread(wm->thread());
moveToThread(wm->thread());
@@ -809,7 +809,7 @@ bool QSGThreadedRenderLoop::interleaveIncubation() const
void QSGThreadedRenderLoop::animationStarted()
{
- qCDebug(QSG_LOG_RENDERLOOP) << "- animationStarted()";
+ qCDebug(QSG_LOG_RENDERLOOP, "- animationStarted()");
startOrStopAnimationTimer();
for (int i=0; i<m_windows.size(); ++i)
@@ -818,7 +818,7 @@ void QSGThreadedRenderLoop::animationStarted()
void QSGThreadedRenderLoop::animationStopped()
{
- qCDebug(QSG_LOG_RENDERLOOP) << "- animationStopped()";
+ qCDebug(QSG_LOG_RENDERLOOP, "- animationStopped()");
startOrStopAnimationTimer();
}
@@ -826,7 +826,7 @@ void QSGThreadedRenderLoop::animationStopped()
void QSGThreadedRenderLoop::startOrStopAnimationTimer()
{
int exposedWindows = 0;
- const Window *theOne = 0;
+ const Window *theOne = nullptr;
for (int i=0; i<m_windows.size(); ++i) {
const Window &w = m_windows.at(i);
if (w.window->isVisible() && w.window->isExposed()) {
@@ -836,14 +836,14 @@ void QSGThreadedRenderLoop::startOrStopAnimationTimer()
}
if (m_animation_timer != 0 && (exposedWindows == 1 || !m_animation_driver->isRunning())) {
- qCDebug(QSG_LOG_RENDERLOOP) << "*** Stopping animation timer";
+ qCDebug(QSG_LOG_RENDERLOOP, "*** Stopping animation timer");
killTimer(m_animation_timer);
m_animation_timer = 0;
// If animations are running, make sure we keep on animating
if (m_animation_driver->isRunning())
maybePostPolishRequest(const_cast<Window *>(theOne));
} else if (m_animation_timer == 0 && exposedWindows != 1 && m_animation_driver->isRunning()) {
- qCDebug(QSG_LOG_RENDERLOOP) << "*** Starting animation timer";
+ qCDebug(QSG_LOG_RENDERLOOP, "*** Starting animation timer");
m_animation_timer = startTimer(qsgrl_animation_interval());
}
}
@@ -870,7 +870,7 @@ void QSGThreadedRenderLoop::hide(QQuickWindow *window)
}
-/*!
+/*
If the window is first hide it, then perform a complete cleanup
with releaseResources which will take down the GL context and
exit the rendering thread.
@@ -920,7 +920,7 @@ void QSGThreadedRenderLoop::exposureChanged(QQuickWindow *window)
}
}
-/*!
+/*
Will post an event to the render thread that this window should
start to render.
*/
@@ -930,7 +930,7 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window)
Window *w = windowFor(m_windows, window);
if (!w) {
- qCDebug(QSG_LOG_RENDERLOOP) << "- adding window to list";
+ qCDebug(QSG_LOG_RENDERLOOP, "- adding window to list");
Window win;
win.window = window;
win.actualWindowFormat = window->format();
@@ -962,7 +962,7 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window)
// Start render thread if it is not running
if (!w->thread->isRunning()) {
- qCDebug(QSG_LOG_RENDERLOOP) << "- starting render thread";
+ qCDebug(QSG_LOG_RENDERLOOP, "- starting render thread");
if (!w->thread->gl) {
w->thread->gl = new QOpenGLContext();
@@ -973,7 +973,7 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window)
if (!w->thread->gl->create()) {
const bool isEs = w->thread->gl->isOpenGLES();
delete w->thread->gl;
- w->thread->gl = 0;
+ w->thread->gl = nullptr;
handleContextCreationFailure(w->window, isEs);
return;
}
@@ -981,7 +981,7 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window)
QQuickWindowPrivate::get(w->window)->fireOpenGLContextCreated(w->thread->gl);
w->thread->gl->moveToThread(w->thread);
- qCDebug(QSG_LOG_RENDERLOOP) << "- OpenGL context created";
+ qCDebug(QSG_LOG_RENDERLOOP, "- OpenGL context created");
}
QQuickAnimatorController *controller = QQuickWindowPrivate::get(w->window)->animationController;
@@ -998,16 +998,16 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window)
qFatal("Render thread failed to start, aborting application.");
} else {
- qCDebug(QSG_LOG_RENDERLOOP) << "- render thread already running";
+ qCDebug(QSG_LOG_RENDERLOOP, "- render thread already running");
}
polishAndSync(w, true);
- qCDebug(QSG_LOG_RENDERLOOP) << "- done with handleExposure()";
+ qCDebug(QSG_LOG_RENDERLOOP, "- done with handleExposure()");
startOrStopAnimationTimer();
}
-/*!
+/*
This function posts an event to the render thread to remove the window
from the list of windowses to render.
@@ -1029,7 +1029,7 @@ void QSGThreadedRenderLoop::handleObscurity(Window *w)
void QSGThreadedRenderLoop::handleUpdateRequest(QQuickWindow *window)
{
- qCDebug(QSG_LOG_RENDERLOOP) << "- polish and sync update request";
+ qCDebug(QSG_LOG_RENDERLOOP, "- polish and sync update request");
Window *w = windowFor(m_windows, window);
if (w)
polishAndSync(w);
@@ -1042,7 +1042,7 @@ void QSGThreadedRenderLoop::maybeUpdate(QQuickWindow *window)
maybeUpdate(w);
}
-/*!
+/*
Called whenever the QML scene has changed. Will post an event to
ourselves that a sync is needed.
*/
@@ -1065,7 +1065,7 @@ void QSGThreadedRenderLoop::maybeUpdate(Window *w)
// Call this function from the Gui thread later as startTimer cannot be
// called from the render thread.
if (current == w->thread) {
- qCDebug(QSG_LOG_RENDERLOOP) << "- on render thread";
+ qCDebug(QSG_LOG_RENDERLOOP, "- on render thread");
w->updateDuringSync = true;
return;
}
@@ -1073,7 +1073,7 @@ void QSGThreadedRenderLoop::maybeUpdate(Window *w)
maybePostPolishRequest(w);
}
-/*!
+/*
Called when the QQuickWindow should be explicitly repainted. This function
can also be called on the render thread when the GUI thread is blocked to
keep render thread animations alive.
@@ -1105,7 +1105,7 @@ void QSGThreadedRenderLoop::releaseResources(QQuickWindow *window)
releaseResources(w, false);
}
-/*!
+/*
* Release resources will post an event to the render thread to
* free up the SG and GL resources and exists the render thread.
*/
@@ -1123,15 +1123,15 @@ void QSGThreadedRenderLoop::releaseResources(Window *w, bool inDestructor)
// and the OpenGL resources.
// QOffscreenSurface must be created on the GUI thread, so we
// create it here and pass it on to QSGRenderThread::invalidateGL()
- QOffscreenSurface *fallback = 0;
+ QOffscreenSurface *fallback = nullptr;
if (!window->handle()) {
- qCDebug(QSG_LOG_RENDERLOOP) << "- using fallback surface";
+ qCDebug(QSG_LOG_RENDERLOOP, "- using fallback surface");
fallback = new QOffscreenSurface();
fallback->setFormat(w->actualWindowFormat);
fallback->create();
}
- qCDebug(QSG_LOG_RENDERLOOP) << "- posting release request to render thread";
+ qCDebug(QSG_LOG_RENDERLOOP, "- posting release request to render thread");
w->thread->postEvent(new WMTryReleaseEvent(window, inDestructor, fallback));
w->thread->waitCondition.wait(&w->thread->mutex);
delete fallback;
@@ -1161,7 +1161,7 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
QQuickWindow *window = w->window;
if (!w->thread || !w->thread->window) {
- qCDebug(QSG_LOG_RENDERLOOP) << "- not exposed, abort";
+ qCDebug(QSG_LOG_RENDERLOOP, "- not exposed, abort");
return;
}
@@ -1170,7 +1170,7 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
// The delivery of the event might have caused the window to stop rendering
w = windowFor(m_windows, window);
if (!w || !w->thread || !w->thread->window) {
- qCDebug(QSG_LOG_RENDERLOOP) << "- removed after event flushing, abort";
+ qCDebug(QSG_LOG_RENDERLOOP, "- removed after event flushing, abort");
return;
}
@@ -1196,13 +1196,13 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
emit window->afterAnimating();
- qCDebug(QSG_LOG_RENDERLOOP) << "- lock for sync";
+ qCDebug(QSG_LOG_RENDERLOOP, "- lock for sync");
w->thread->mutex.lock();
m_lockedForSync = true;
w->thread->postEvent(new WMSyncEvent(window, inExpose, w->forceRenderPass));
w->forceRenderPass = false;
- qCDebug(QSG_LOG_RENDERLOOP) << "- wait for sync";
+ qCDebug(QSG_LOG_RENDERLOOP, "- wait for sync");
if (profileFrames)
waitTime = timer.nsecsElapsed();
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
@@ -1210,7 +1210,7 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
w->thread->waitCondition.wait(&w->thread->mutex);
m_lockedForSync = false;
w->thread->mutex.unlock();
- qCDebug(QSG_LOG_RENDERLOOP) << "- unlock after sync";
+ qCDebug(QSG_LOG_RENDERLOOP, "- unlock after sync");
if (profileFrames)
syncTime = timer.nsecsElapsed();
@@ -1218,9 +1218,9 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
QQuickProfiler::SceneGraphPolishAndSyncSync);
if (m_animation_timer == 0 && m_animation_driver->isRunning()) {
- qCDebug(QSG_LOG_RENDERLOOP) << "- advancing animations";
+ qCDebug(QSG_LOG_RENDERLOOP, "- advancing animations");
m_animation_driver->advance();
- qCDebug(QSG_LOG_RENDERLOOP) << "- animations done..";
+ qCDebug(QSG_LOG_RENDERLOOP, "- animations done..");
// We need to trigger another sync to keep animations running...
maybePostPolishRequest(w);
emit timeToIncubate();
@@ -1247,7 +1247,7 @@ bool QSGThreadedRenderLoop::event(QEvent *e)
case QEvent::Timer: {
QTimerEvent *te = static_cast<QTimerEvent *>(e);
if (te->timerId() == m_animation_timer) {
- qCDebug(QSG_LOG_RENDERLOOP) << "- ticking non-visual timer";
+ qCDebug(QSG_LOG_RENDERLOOP, "- ticking non-visual timer");
m_animation_driver->advance();
emit timeToIncubate();
return true;
@@ -1286,25 +1286,25 @@ QImage QSGThreadedRenderLoop::grab(QQuickWindow *window)
if (!window->handle())
window->create();
- qCDebug(QSG_LOG_RENDERLOOP) << "- polishing items";
+ qCDebug(QSG_LOG_RENDERLOOP, "- polishing items");
QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
d->polishItems();
QImage result;
w->thread->mutex.lock();
m_lockedForSync = true;
- qCDebug(QSG_LOG_RENDERLOOP) << "- posting grab event";
+ qCDebug(QSG_LOG_RENDERLOOP, "- posting grab event");
w->thread->postEvent(new WMGrabEvent(window, &result));
w->thread->waitCondition.wait(&w->thread->mutex);
m_lockedForSync = false;
w->thread->mutex.unlock();
- qCDebug(QSG_LOG_RENDERLOOP) << "- grab complete";
+ qCDebug(QSG_LOG_RENDERLOOP, "- grab complete");
return result;
}
-/*!
+/*
* Posts a new job event to the render thread.
* Returns true if posting succeeded.
*/
diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
index e33f31f2ac..3b2737b8e1 100644
--- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp
+++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
@@ -64,7 +64,7 @@ QT_BEGIN_NAMESPACE
extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha);
-#define RLDEBUG(x) qCDebug(QSG_LOG_RENDERLOOP) << x;
+#define RLDEBUG(x) qCDebug(QSG_LOG_RENDERLOOP, x)
static QElapsedTimer qsg_render_timer;
#define QSG_LOG_TIME_SAMPLE(sampleName) \
@@ -78,7 +78,7 @@ static QElapsedTimer qsg_render_timer;
QSGWindowsRenderLoop::QSGWindowsRenderLoop()
- : m_gl(0)
+ : m_gl(nullptr)
, m_sg(QSGContext::createDefaultContext())
, m_updateTimer(0)
, m_animationTimer(0)
@@ -117,7 +117,7 @@ QSGWindowsRenderLoop::WindowData *QSGWindowsRenderLoop::windowData(QQuickWindow
if (wd.window == window)
return &wd;
}
- return 0;
+ return nullptr;
}
void QSGWindowsRenderLoop::maybePostUpdateTimer()
@@ -158,7 +158,7 @@ void QSGWindowsRenderLoop::stopped()
void QSGWindowsRenderLoop::show(QQuickWindow *window)
{
RLDEBUG("show");
- if (windowData(window) != 0)
+ if (windowData(window) != nullptr)
return;
// This happens before the platform window is shown, but after
@@ -178,7 +178,7 @@ void QSGWindowsRenderLoop::show(QQuickWindow *window)
if (!created) {
const bool isEs = m_gl->isOpenGLES();
delete m_gl;
- m_gl = 0;
+ m_gl = nullptr;
handleContextCreationFailure(window, isEs);
return;
}
@@ -243,7 +243,7 @@ void QSGWindowsRenderLoop::windowDestroyed(QQuickWindow *window)
current = m_gl->makeCurrent(surface);
}
if (Q_UNLIKELY(!current))
- qCDebug(QSG_LOG_RENDERLOOP) << "cleanup without an OpenGL context";
+ RLDEBUG("cleanup without an OpenGL context");
#if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl)
QQuickOpenGLShaderEffectMaterial::cleanupMaterialCache();
@@ -253,7 +253,7 @@ void QSGWindowsRenderLoop::windowDestroyed(QQuickWindow *window)
if (m_windows.size() == 0) {
d->context->invalidate();
delete m_gl;
- m_gl = 0;
+ m_gl = nullptr;
} else if (m_gl && current) {
m_gl->doneCurrent();
}
@@ -272,7 +272,7 @@ bool QSGWindowsRenderLoop::anyoneShowing() const
void QSGWindowsRenderLoop::exposureChanged(QQuickWindow *window)
{
- if (windowData(window) == 0)
+ if (windowData(window) == nullptr)
return;
if (window->isExposed() && window->isVisible()) {
diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri
index b5c72f521c..4fa3e7b6bf 100644
--- a/src/quick/scenegraph/scenegraph.pri
+++ b/src/quick/scenegraph/scenegraph.pri
@@ -1,4 +1,4 @@
-DEFINES += QSG_SEPARATE_INDEX_BUFFER
+# DEFINES += QSG_SEPARATE_INDEX_BUFFER
# DEFINES += QSG_DISTANCEFIELD_CACHE_DEBUG
# Core API
@@ -230,8 +230,15 @@ SOURCES += \
qtConfig(opengl(es1|es2)?) {
HEADERS += \
- $$PWD/compressedtexture/qsgpkmhandler_p.h
+ $$PWD/compressedtexture/qsgcompressedatlastexture_p.h \
+ $$PWD/compressedtexture/qsgcompressedtexture_p.h \
+ $$PWD/compressedtexture/qsgtexturefilehandler_p.h \
+ $$PWD/compressedtexture/qsgpkmhandler_p.h \
+ $$PWD/compressedtexture/qsgktxhandler_p.h
SOURCES += \
- $$PWD/compressedtexture/qsgpkmhandler.cpp
+ $$PWD/compressedtexture/qsgcompressedatlastexture.cpp \
+ $$PWD/compressedtexture/qsgcompressedtexture.cpp \
+ $$PWD/compressedtexture/qsgpkmhandler.cpp \
+ $$PWD/compressedtexture/qsgktxhandler.cpp
}
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;
}