From 5eae605a475db96ed16d81101e00e736efe9f202 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 20 Mar 2013 15:40:49 +0100 Subject: Fix distance field antialiasing for retina displays. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I01d7d41a4e70822555bae453978dbe92fbb5c98d Reviewed-by: Morten Johan Sørvig Reviewed-by: Yoann Lopes --- src/quick/items/qquickshadereffectsource.cpp | 10 +++++++--- src/quick/items/qquickshadereffectsource_p.h | 3 +++ src/quick/items/qquickwindow.cpp | 1 + src/quick/scenegraph/coreapi/qsgmaterial.cpp | 6 ++++++ src/quick/scenegraph/coreapi/qsgmaterial.h | 1 + src/quick/scenegraph/coreapi/qsgrenderer.cpp | 1 + src/quick/scenegraph/coreapi/qsgrenderer_p.h | 4 ++++ src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp | 5 +++-- 8 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp index cab3692f5a..59b788643a 100644 --- a/src/quick/items/qquickshadereffectsource.cpp +++ b/src/quick/items/qquickshadereffectsource.cpp @@ -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(root)); bool deleteFboLater = false; @@ -960,11 +962,12 @@ QSGNode *QQuickShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaint : m_textureSize; Q_ASSERT(!textureSize.isEmpty()); + QQuickItemPrivate *d = static_cast(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(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)); diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h index 57aba314aa..f391ed2389 100644 --- a/src/quick/items/qquickshadereffectsource_p.h +++ b/src/quick/items/qquickshadereffectsource_p.h @@ -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; diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 594897eae3..176f46e3b7 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -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(); diff --git a/src/quick/scenegraph/coreapi/qsgmaterial.cpp b/src/quick/scenegraph/coreapi/qsgmaterial.cpp index 11ce987959..c0794d0d69 100644 --- a/src/quick/scenegraph/coreapi/qsgmaterial.cpp +++ b/src/quick/scenegraph/coreapi/qsgmaterial.cpp @@ -416,6 +416,12 @@ QMatrix4x4 QSGMaterialShader::RenderState::combinedMatrix() const return static_cast(m_data)->currentCombinedMatrix(); } +float QSGMaterialShader::RenderState::devicePixelRatio() const +{ + Q_ASSERT(m_data); + return static_cast(m_data)->devicePixelRatio(); +} + /*! diff --git a/src/quick/scenegraph/coreapi/qsgmaterial.h b/src/quick/scenegraph/coreapi/qsgmaterial.h index 38862e694d..ee8889deac 100644 --- a/src/quick/scenegraph/coreapi/qsgmaterial.h +++ b/src/quick/scenegraph/coreapi/qsgmaterial.h @@ -73,6 +73,7 @@ public: QRect viewportRect() const; QRect deviceRect() const; float determinant() const; + float devicePixelRatio() const; QOpenGLContext *context() const; diff --git a/src/quick/scenegraph/coreapi/qsgrenderer.cpp b/src/quick/scenegraph/coreapi/qsgrenderer.cpp index 02eec70952..45a0b4b6ab 100644 --- a/src/quick/scenegraph/coreapi/qsgrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgrenderer.cpp @@ -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) diff --git a/src/quick/scenegraph/coreapi/qsgrenderer_p.h b/src/quick/scenegraph/coreapi/qsgrenderer_p.h index 844e8b1d8c..0370be000b 100644 --- a/src/quick/scenegraph/coreapi/qsgrenderer_p.h +++ b/src/quick/scenegraph/coreapi/qsgrenderer_p.h @@ -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; diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp index d3a8614b11..d409cea81a 100644 --- a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp +++ b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp @@ -43,6 +43,8 @@ #include #include #include +#include +#include #include 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) { -- cgit v1.2.3