Fix distance field antialiasing for retina displays.
authorGunnar Sletta <gunnar.sletta@digia.com>
Wed, 20 Mar 2013 14:40:49 +0000 (15:40 +0100)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Tue, 2 Apr 2013 06:29:53 +0000 (08:29 +0200)
Change-Id: I01d7d41a4e70822555bae453978dbe92fbb5c98d
Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
Reviewed-by: Yoann Lopes <yoann.lopes@digia.com>
src/quick/items/qquickshadereffectsource.cpp
src/quick/items/qquickshadereffectsource_p.h
src/quick/items/qquickwindow.cpp
src/quick/scenegraph/coreapi/qsgmaterial.cpp
src/quick/scenegraph/coreapi/qsgmaterial.h
src/quick/scenegraph/coreapi/qsgrenderer.cpp
src/quick/scenegraph/coreapi/qsgrenderer_p.h
src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp

index cab3692..59b7886 100644 (file)
@@ -131,6 +131,7 @@ void QQuickShaderEffectSourceNode::markDirtyTexture()
 QQuickShaderEffectTexture::QQuickShaderEffectTexture(QQuickItem *shaderSource)
     : QSGDynamicTexture()
     , m_item(0)
+    , m_device_pixel_ratio(1)
     , m_format(GL_RGBA)
     , m_renderer(0)
     , m_fbo(0)
@@ -313,6 +314,7 @@ void QQuickShaderEffectTexture::grab()
         m_renderer = m_context->createRenderer();
         connect(m_renderer, SIGNAL(sceneGraphChanged()), this, SLOT(markDirtyTexture()));
     }
+    m_renderer->setDevicePixelRatio(m_device_pixel_ratio);
     m_renderer->setRootNode(static_cast<QSGRootNode *>(root));
 
     bool deleteFboLater = false;
@@ -960,11 +962,12 @@ QSGNode *QQuickShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaint
                       : m_textureSize;
     Q_ASSERT(!textureSize.isEmpty());
 
+    QQuickItemPrivate *d = static_cast<QQuickItemPrivate *>(QObjectPrivate::get(this));
+
     // Crate large textures on high-dpi displays.
-    if (sourceItem() && sourceItem()->window())
-        textureSize *= sourceItem()->window()->devicePixelRatio();
+    if (sourceItem())
+        textureSize *= d->window->devicePixelRatio();
 
-    QQuickItemPrivate *d = static_cast<QQuickItemPrivate *>(QObjectPrivate::get(this));
     const QSize minTextureSize = d->sceneGraphContext()->minimumFBOSize();
     // Keep power-of-two by doubling the size.
     while (textureSize.width() < minTextureSize.width())
@@ -972,6 +975,7 @@ QSGNode *QQuickShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaint
     while (textureSize.height() < minTextureSize.height())
         textureSize.rheight() *= 2;
 
+    m_texture->setDevicePixelRatio(d->window->devicePixelRatio());
     m_texture->setSize(textureSize);
     m_texture->setRecursive(m_recursive);
     m_texture->setFormat(GLenum(m_format));
index 57aba31..f391ed2 100644 (file)
@@ -111,6 +111,8 @@ public:
     bool recursive() const { return bool(m_recursive); }
     void setRecursive(bool recursive);
 
+    void setDevicePixelRatio(qreal ratio) { m_device_pixel_ratio = ratio; }
+
     void scheduleUpdate();
 
     QImage toImage() const;
@@ -128,6 +130,7 @@ private:
     QSGNode *m_item;
     QRectF m_rect;
     QSize m_size;
+    qreal m_device_pixel_ratio;
     GLenum m_format;
 
     QSGRenderer *m_renderer;
index 594897e..176f46e 100644 (file)
@@ -348,6 +348,7 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size)
         renderer->setViewportRect(QRect(QPoint(0, 0), size * devicePixelRatio));
     }
     renderer->setProjectionMatrixToRect(QRect(QPoint(0, 0), size));
+    renderer->setDevicePixelRatio(q->devicePixelRatio());
 
     context->renderNextFrame(renderer, fboId);
     emit q->afterRendering();
index 11ce987..c0794d0 100644 (file)
@@ -416,6 +416,12 @@ QMatrix4x4 QSGMaterialShader::RenderState::combinedMatrix() const
     return static_cast<const QSGRenderer *>(m_data)->currentCombinedMatrix();
 }
 
+float QSGMaterialShader::RenderState::devicePixelRatio() const
+{
+    Q_ASSERT(m_data);
+    return static_cast<const QSGRenderer *>(m_data)->devicePixelRatio();
+}
+
 
 
 /*!
index 38862e6..ee8889d 100644 (file)
@@ -73,6 +73,7 @@ public:
         QRect viewportRect() const;
         QRect deviceRect() const;
         float determinant() const;
+        float devicePixelRatio() const;
 
         QOpenGLContext *context() const;
 
index 02eec70..45a0b4b 100644 (file)
@@ -137,6 +137,7 @@ QSGRenderer::QSGRenderer(QSGContext *context)
     , m_clear_mode(ClearColorBuffer | ClearDepthBuffer)
     , m_current_opacity(1)
     , m_current_determinant(1)
+    , m_device_pixel_ratio(1)
     , m_current_stencil_value(0)
     , m_context(context)
     , m_root_node(0)
index 844e8b1..0370be0 100644 (file)
@@ -105,6 +105,9 @@ public:
     qreal currentOpacity() const { return m_current_opacity; }
     qreal determinant() const { return m_current_determinant; }
 
+    void setDevicePixelRatio(qreal ratio) { m_device_pixel_ratio = ratio; }
+    qreal devicePixelRatio() const { return m_device_pixel_ratio; }
+
     void setProjectionMatrixToDeviceRect();
     virtual void setProjectionMatrixToRect(const QRectF &rect);
     void setProjectionMatrix(const QMatrix4x4 &matrix);
@@ -154,6 +157,7 @@ protected:
     QMatrix4x4 m_current_model_view_matrix;
     qreal m_current_opacity;
     qreal m_current_determinant;
+    qreal m_device_pixel_ratio;
     QRect m_current_scissor_rect;
     int m_current_stencil_value;
 
index d3a8614..d409cea 100644 (file)
@@ -43,6 +43,8 @@
 #include <QtQuick/private/qsgdistancefieldutil_p.h>
 #include <QtQuick/private/qsgtexture_p.h>
 #include <QtGui/qopenglfunctions.h>
+#include <QtGui/qsurface.h>
+#include <QtGui/qwindow.h>
 #include <qmath.h>
 
 QT_BEGIN_NAMESPACE
@@ -115,7 +117,6 @@ void QSGDistanceFieldTextMaterialShader::updateAlphaRange(ThresholdFunc threshol
     float combinedScale = m_fontScale * m_matrixScale;
     float base = thresholdFunc(combinedScale);
     float range = spreadFunc(combinedScale);
-
     float alphaMin = qMax(0.0f, base - range);
     float alphaMax = qMin(base + range, 1.0f);
     program()->setUniformValue(m_alphaMin_id, GLfloat(alphaMin));
@@ -157,7 +158,7 @@ void QSGDistanceFieldTextMaterialShader::updateState(const RenderState &state, Q
     }
     if (state.isMatrixDirty()) {
         program()->setUniformValue(m_matrix_id, state.combinedMatrix());
-        m_matrixScale = qSqrt(qAbs(state.determinant()));
+        m_matrixScale = qSqrt(qAbs(state.determinant())) * state.devicePixelRatio();
         updateRange = true;
     }
     if (updateRange) {