diff options
Diffstat (limited to 'src/quick')
23 files changed, 190 insertions, 100 deletions
diff --git a/src/quick/handlers/qquickhoverhandler.cpp b/src/quick/handlers/qquickhoverhandler.cpp index b12d85784a..3361415eac 100644 --- a/src/quick/handlers/qquickhoverhandler.cpp +++ b/src/quick/handlers/qquickhoverhandler.cpp @@ -85,8 +85,11 @@ QQuickHoverHandler::~QQuickHoverHandler() void QQuickHoverHandler::componentComplete() { - parentItem()->setAcceptHoverEvents(true); - QQuickItemPrivate::get(parentItem())->setHasHoverInChild(true); + QQuickSinglePointHandler::componentComplete(); + if (auto par = parentItem()) { + par->setAcceptHoverEvents(true); + QQuickItemPrivate::get(par)->setHasHoverInChild(true); + } } bool QQuickHoverHandler::wantsPointerEvent(QQuickPointerEvent *event) @@ -124,6 +127,13 @@ void QQuickHoverHandler::handleEventPoint(QQuickEventPoint *point) setPassiveGrab(point); } +void QQuickHoverHandler::onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabTransition transition, QQuickEventPoint *point) +{ + QQuickSinglePointHandler::onGrabChanged(grabber, transition, point); + if (grabber == this && transition == QQuickEventPoint::CancelGrabPassive) + setHovered(false); +} + /*! \qmlproperty bool QtQuick::HoverHandler::hovered \readonly diff --git a/src/quick/handlers/qquickhoverhandler_p.h b/src/quick/handlers/qquickhoverhandler_p.h index 313b87217c..426372d162 100644 --- a/src/quick/handlers/qquickhoverhandler_p.h +++ b/src/quick/handlers/qquickhoverhandler_p.h @@ -78,6 +78,7 @@ protected: void componentComplete() override; bool wantsPointerEvent(QQuickPointerEvent *event) override; void handleEventPoint(QQuickEventPoint *point) override; + void onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabTransition transition, QQuickEventPoint *point) override; private: void setHovered(bool hovered); diff --git a/src/quick/handlers/qquickpointerhandler.cpp b/src/quick/handlers/qquickpointerhandler.cpp index a6c18feafe..25c5e684b7 100644 --- a/src/quick/handlers/qquickpointerhandler.cpp +++ b/src/quick/handlers/qquickpointerhandler.cpp @@ -207,9 +207,11 @@ void QQuickPointerHandler::setCursorShape(Qt::CursorShape shape) return; d->cursorShape = shape; d->cursorSet = true; - QQuickItemPrivate *itemPriv = QQuickItemPrivate::get(parentItem()); - itemPriv->hasCursorHandler = true; - itemPriv->setHasCursorInChild(true); + if (auto *par = qmlobject_cast<QQuickItem *>(parent())) { + QQuickItemPrivate *itemPriv = QQuickItemPrivate::get(par); + itemPriv->hasCursorHandler = true; + itemPriv->setHasCursorInChild(true); + } emit cursorShapeChanged(); } @@ -220,9 +222,11 @@ void QQuickPointerHandler::resetCursorShape() return; d->cursorShape = Qt::ArrowCursor; d->cursorSet = false; - QQuickItemPrivate *itemPriv = QQuickItemPrivate::get(parentItem()); - itemPriv->hasCursorHandler = false; - itemPriv->setHasCursorInChild(itemPriv->hasCursor); + if (auto *parent = parentItem()) { + QQuickItemPrivate *itemPriv = QQuickItemPrivate::get(parent); + itemPriv->hasCursorHandler = false; + itemPriv->setHasCursorInChild(itemPriv->hasCursor); + } emit cursorShapeChanged(); } @@ -457,6 +461,14 @@ void QQuickPointerHandler::classBegin() void QQuickPointerHandler::componentComplete() { + Q_D(const QQuickPointerHandler); + if (d->cursorSet) { + if (auto *parent = parentItem()) { + QQuickItemPrivate *itemPriv = QQuickItemPrivate::get(parent); + itemPriv->hasCursorHandler = true; + itemPriv->setHasCursorInChild(true); + } + } } QQuickPointerEvent *QQuickPointerHandler::currentEvent() diff --git a/src/quick/items/qquickanimatedsprite.cpp b/src/quick/items/qquickanimatedsprite.cpp index f239f24367..8818bc5608 100644 --- a/src/quick/items/qquickanimatedsprite.cpp +++ b/src/quick/items/qquickanimatedsprite.cpp @@ -894,7 +894,7 @@ void QQuickAnimatedSprite::prepareNextFrame(QSGSpriteNode *node) maybeUpdate(); } - qreal frameCount = d->m_spriteEngine->spriteFrames(); + int frameCount = d->m_spriteEngine->spriteFrames(); bool reverse = d->m_spriteEngine->sprite()->reverse(); if (reverse) frameAt = (frameCount - 1) - frameAt; @@ -931,15 +931,15 @@ void QQuickAnimatedSprite::prepareNextFrame(QSGSpriteNode *node) x2 = x1 - w; y2 = y1; } else { - x2 = 1.0 - w; + x2 = d->m_sheetSize.width() - w; y2 = y1 - h; - if (y2 < 0.0) { + if (y2 < 0) { //the last row may not fill the entire width int maxRowFrames = d->m_sheetSize.width() / d->m_spriteEngine->spriteWidth(); if (d->m_spriteEngine->maxFrames() % maxRowFrames) x2 = ((d->m_spriteEngine->maxFrames() % maxRowFrames) - 1) * w; - y2 = 1.0 - h; + y2 = d->m_sheetSize.height() - h; } } } else { @@ -947,10 +947,10 @@ void QQuickAnimatedSprite::prepareNextFrame(QSGSpriteNode *node) x2 = x1 + w; y2 = y1; } else { - x2 = 0.0; + x2 = 0; y2 = y1 + h; - if (y2 >= 1.0) - y2 = 0.0; + if (y2 >= d->m_sheetSize.height()) + y2 = 0; } } diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index e12e85db64..7bf242a527 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -62,6 +62,8 @@ QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcHandlerParent) +Q_LOGGING_CATEGORY(lcVel, "qt.quick.flickable.velocity") +Q_LOGGING_CATEGORY(lcWheel, "qt.quick.flickable.wheel") // FlickThreshold determines how far the "mouse" must have moved // before we perform a flick. @@ -263,7 +265,8 @@ QQuickFlickablePrivate::QQuickFlickablePrivate() , deceleration(QML_FLICK_DEFAULTDECELERATION) , maxVelocity(QML_FLICK_DEFAULTMAXVELOCITY), reportedVelocitySmoothing(100) , delayedPressEvent(nullptr), pressDelay(0), fixupDuration(400) - , flickBoost(1.0), fixupMode(Normal), vTime(0), visibleArea(nullptr) + , flickBoost(1.0), initialWheelFlickDistance(qApp->styleHints()->wheelScrollLines() * 24) + , fixupMode(Normal), vTime(0), visibleArea(nullptr) , flickableDirection(QQuickFlickable::AutoFlickDirection) , boundsBehavior(QQuickFlickable::DragAndOvershootBounds) , boundsMovement(QQuickFlickable::FollowBoundsBehavior) @@ -531,10 +534,14 @@ void QQuickFlickablePrivate::updateBeginningEnd() if (atBeginning != vData.atBeginning) { vData.atBeginning = atBeginning; atYBeginningChange = true; + if (!vData.moving && atBeginning) + vData.smoothVelocity.setValue(0); } if (atEnd != vData.atEnd) { vData.atEnd = atEnd; atYEndChange = true; + if (!vData.moving && atEnd) + vData.smoothVelocity.setValue(0); } // Horizontal @@ -547,10 +554,14 @@ void QQuickFlickablePrivate::updateBeginningEnd() if (atBeginning != hData.atBeginning) { hData.atBeginning = atBeginning; atXBeginningChange = true; + if (!hData.moving && atBeginning) + hData.smoothVelocity.setValue(0); } if (atEnd != hData.atEnd) { hData.atEnd = atEnd; atXEndChange = true; + if (!hData.moving && atEnd) + hData.smoothVelocity.setValue(0); } if (vData.extentsChanged) { @@ -1489,6 +1500,7 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event) d->hData.velocity = 0; d->timer.start(); d->maybeBeginDrag(currentTimestamp, event->position()); + d->lastPosTime = -1; break; case Qt::NoScrollPhase: // default phase with an ordinary wheel mouse case Qt::ScrollUpdate: @@ -1515,20 +1527,34 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event) return; } + qreal elapsed = qreal(currentTimestamp - d->lastPosTime) / qreal(1000); + if (elapsed <= 0) { + d->lastPosTime = currentTimestamp; + qCDebug(lcWheel) << "insufficient elapsed time: can't calculate velocity" << elapsed; + return; + } + if (event->source() == Qt::MouseEventNotSynthesized || event->pixelDelta().isNull()) { - // physical mouse wheel, so use angleDelta + // no pixel delta (physical mouse wheel, or "dumb" touchpad), so use angleDelta int xDelta = event->angleDelta().x(); int yDelta = event->angleDelta().y(); + // For a single "clicky" wheel event (angleDelta +/- 120), + // we want flick() to end up moving a distance proportional to QStyleHints::wheelScrollLines(). + // The decel algo from there is + // qreal dist = v2 / (accel * 2.0); + // i.e. initialWheelFlickDistance = (120 / dt)^2 / (deceleration * 2) + // now solve for dt: + // dt = 120 / sqrt(deceleration * 2 * initialWheelFlickDistance) + if (!isMoving()) + elapsed = 120 / qSqrt(d->deceleration * 2 * d->initialWheelFlickDistance); if (yflick() && yDelta != 0) { - bool valid = false; - if (yDelta > 0 && contentY() > -minYExtent()) { - d->vData.velocity = qMax(yDelta*2 - d->vData.smoothVelocity.value(), qreal(d->maxVelocity/4)); - valid = true; - } else if (yDelta < 0 && contentY() < -maxYExtent()) { - d->vData.velocity = qMin(yDelta*2 - d->vData.smoothVelocity.value(), qreal(-d->maxVelocity/4)); - valid = true; - } - if (valid) { + qreal instVelocity = yDelta / elapsed; + // if the direction has changed, start over with filtering, to allow instant movement in the opposite direction + if ((instVelocity < 0 && d->vData.velocity > 0) || (instVelocity > 0 && d->vData.velocity < 0)) + d->vData.velocityBuffer.clear(); + d->vData.addVelocitySample(instVelocity, d->maxVelocity); + d->vData.updateVelocity(); + if ((yDelta > 0 && contentY() > -minYExtent()) || (yDelta < 0 && contentY() < -maxYExtent())) { d->flickY(d->vData.velocity); d->flickingStarted(false, true); if (d->vData.flicking) { @@ -1539,15 +1565,13 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event) } } if (xflick() && xDelta != 0) { - bool valid = false; - if (xDelta > 0 && contentX() > -minXExtent()) { - d->hData.velocity = qMax(xDelta*2 - d->hData.smoothVelocity.value(), qreal(d->maxVelocity/4)); - valid = true; - } else if (xDelta < 0 && contentX() < -maxXExtent()) { - d->hData.velocity = qMin(xDelta*2 - d->hData.smoothVelocity.value(), qreal(-d->maxVelocity/4)); - valid = true; - } - if (valid) { + qreal instVelocity = xDelta / elapsed; + // if the direction has changed, start over with filtering, to allow instant movement in the opposite direction + if ((instVelocity < 0 && d->hData.velocity > 0) || (instVelocity > 0 && d->hData.velocity < 0)) + d->hData.velocityBuffer.clear(); + d->hData.addVelocitySample(instVelocity, d->maxVelocity); + d->hData.updateVelocity(); + if ((xDelta > 0 && contentX() > -minXExtent()) || (xDelta < 0 && contentX() < -maxXExtent())) { d->flickX(d->hData.velocity); d->flickingStarted(true, false); if (d->hData.flicking) { @@ -1562,18 +1586,13 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event) int xDelta = event->pixelDelta().x(); int yDelta = event->pixelDelta().y(); - qreal elapsed = qreal(currentTimestamp - d->lastPosTime) / 1000.; - if (elapsed <= 0) { - d->lastPosTime = currentTimestamp; - return; - } QVector2D velocity(xDelta / elapsed, yDelta / elapsed); - d->lastPosTime = currentTimestamp; d->accumulatedWheelPixelDelta += QVector2D(event->pixelDelta()); d->drag(currentTimestamp, event->type(), event->position(), d->accumulatedWheelPixelDelta, true, !d->scrollingPhase, true, velocity); event->accept(); } + d->lastPosTime = currentTimestamp; if (!event->isAccepted()) QQuickItem::wheelEvent(event); @@ -1744,6 +1763,10 @@ void QQuickFlickable::componentComplete() setContentX(-minXExtent()); if (!d->vData.explicitValue && d->vData.startMargin != 0.) setContentY(-minYExtent()); + if (lcWheel().isDebugEnabled() || lcVel().isDebugEnabled()) { + d->timeline.setObjectName(QLatin1String("timeline for Flickable ") + objectName()); + d->velocityTimeline.setObjectName(QLatin1String("velocity timeline for Flickable ") + objectName()); + } } void QQuickFlickable::viewportMoved(Qt::Orientations orient) @@ -2504,9 +2527,23 @@ void QQuickFlickable::setMaximumFlickVelocity(qreal v) /*! \qmlproperty real QtQuick::Flickable::flickDeceleration - This property holds the rate at which a flick will decelerate. - - The default value is platform dependent. + This property holds the rate at which a flick will decelerate: + the higher the number, the faster it slows down when the user stops + flicking via touch, touchpad or mouse wheel. For example 0.0001 is nearly + "frictionless", and 10000 feels quite "sticky". + + The default value is platform dependent. Values of zero or less are not allowed. + + \note For touchpad flicking, some platforms drive Flickable directly by + sending QWheelEvents with QWheelEvent::phase() being \c Qt::ScrollMomentum, + after the user has released all fingers from the touchpad. In that case, + the operating system is controlling the deceleration, and this property has + no effect. + + \note For mouse wheel scrolling, and for gesture scrolling on touchpads + that do not have a momentum phase, extremely large values of + flickDeceleration can make Flickable very resistant to scrolling, + especially if \l maximumFlickVelocity is too small. */ qreal QQuickFlickable::flickDeceleration() const { @@ -2519,7 +2556,7 @@ void QQuickFlickable::setFlickDeceleration(qreal deceleration) Q_D(QQuickFlickable); if (deceleration == d->deceleration) return; - d->deceleration = deceleration; + d->deceleration = qMax(0.001, deceleration); emit flickDecelerationChanged(); } diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h index 414c9c33d6..6163613493 100644 --- a/src/quick/items/qquickflickable_p_p.h +++ b/src/quick/items/qquickflickable_p_p.h @@ -241,6 +241,7 @@ public: int pressDelay; int fixupDuration; qreal flickBoost; + qreal initialWheelFlickDistance; enum FixupMode { Normal, Immediate, ExtentChanged }; FixupMode fixupMode; diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index 13e7b87049..010a0152e1 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -2402,8 +2402,6 @@ void QQuickItemView::createdItem(int index, QObject* object) d->repositionPackageItemAt(item, index); else if (index == d->currentIndex) d->updateCurrent(index); - } else if (index == d->currentIndex) { - d->updateCurrent(index); } } diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp index 4f61d61309..b298ed74da 100644 --- a/src/quick/items/qquickshadereffectsource.cpp +++ b/src/quick/items/qquickshadereffectsource.cpp @@ -344,7 +344,6 @@ void QQuickShaderEffectSource::setSourceItem(QQuickItem *item) d->refFromEffectItem(m_hideSource); d->addItemChangeListener(this, QQuickItemPrivate::Geometry); connect(m_sourceItem, SIGNAL(destroyed(QObject*)), this, SLOT(sourceItemDestroyed(QObject*))); - connect(m_sourceItem, SIGNAL(parentChanged(QQuickItem*)), this, SLOT(sourceItemParentChanged(QQuickItem*))); } else { qWarning("ShaderEffectSource: sourceItem and ShaderEffectSource must both be children of the same window."); m_sourceItem = nullptr; @@ -364,13 +363,6 @@ void QQuickShaderEffectSource::sourceItemDestroyed(QObject *item) } -void QQuickShaderEffectSource::sourceItemParentChanged(QQuickItem *parent) -{ - if (!parent && m_texture) - m_texture->setItem(0); -} - - /*! \qmlproperty rect QtQuick::ShaderEffectSource::sourceRect diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h index 4deb6c70a3..c0a1ccab78 100644 --- a/src/quick/items/qquickshadereffectsource_p.h +++ b/src/quick/items/qquickshadereffectsource_p.h @@ -173,7 +173,6 @@ Q_SIGNALS: private Q_SLOTS: void sourceItemDestroyed(QObject *item); void invalidateSceneGraph(); - void sourceItemParentChanged(QQuickItem *parent); protected: void releaseResources() override; diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index bfdb107ef8..97ece4e10d 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -3458,7 +3458,12 @@ void QQuickTextInputPrivate::processInputMethodEvent(QInputMethodEvent *event) for (int i = 0; i < event->attributes().size(); ++i) { const QInputMethodEvent::Attribute &a = event->attributes().at(i); if (a.type == QInputMethodEvent::Selection) { - m_cursor = qBound(0, a.start + a.length, m_text.length()); + // If we already called internalInsert(), the cursor position will + // already be adjusted correctly. The attribute.start does + // not seem to take the mask into account, so it will reset cursor + // to an invalid position in such case. + if (!cursorPositionChanged) + m_cursor = qBound(0, a.start + a.length, m_text.length()); if (a.length) { m_selstart = qMax(0, qMin(a.start, m_text.length())); m_selend = m_cursor; diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 2b9810ed57..ce32d5aa33 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -2146,6 +2146,15 @@ bool QQuickWindowPrivate::deliverHoverEvent(QQuickItem *item, const QPointF &sce while (!hoverItems.isEmpty() && !itemsToHover.contains(hoverItems.at(0))) { QQuickItem *hoverLeaveItem = hoverItems.takeFirst(); sendHoverEvent(QEvent::HoverLeave, hoverLeaveItem, scenePos, lastScenePos, modifiers, timestamp, accepted); + QQuickItemPrivate *hoverLeaveItemPrivate = QQuickItemPrivate::get(hoverLeaveItem); + if (hoverLeaveItemPrivate->hasPointerHandlers()) { + for (QQuickPointerHandler *handler : hoverLeaveItemPrivate->extra->pointerHandlers) { + if (auto *hh = qmlobject_cast<QQuickHoverHandler *>(handler)) { + QQuickPointerEvent *pointerEvent = pointerEventInstance(QQuickPointerDevice::genericMouseDevice(), QEvent::MouseMove); + pointerEvent->point(0)->cancelPassiveGrab(hh); + } + } + } } if (!hoverItems.isEmpty() && hoverItems.at(0) == item) {//Not entering a new Item @@ -2190,6 +2199,8 @@ bool QQuickWindowPrivate::deliverSinglePointEventUntilAccepted(QQuickPointerEven QVector<QQuickItem *> targetItems = pointerTargets(contentItem, point, false, false); for (QQuickItem *item : targetItems) { + if (!item->window()) + continue; QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); event->localize(item); // Let Pointer Handlers have the first shot diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index ec65dce95b..77bac7c8a5 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -1133,6 +1133,9 @@ void Renderer::releaseCachedResources() if (m_rhi) m_rhi->releaseCachedResources(); + + m_vertexUploadPool.resize(0); + m_indexUploadPool.resize(0); } void Renderer::invalidateAndRecycleBatch(Batch *b) @@ -4006,6 +4009,16 @@ void Renderer::renderBatches() if (m_useDepthBuffer) { glClearDepthf(1); // calls glClearDepth() under the hood for desktop OpenGL + } + glColorMask(true, true, true, true); + glDisable(GL_SCISSOR_TEST); + + bindable()->clear(clearMode()); + + if (m_renderPassRecordingCallbacks.start) + m_renderPassRecordingCallbacks.start(m_renderPassRecordingCallbacks.userData); + + if (m_useDepthBuffer) { glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glDepthMask(true); @@ -4019,11 +4032,6 @@ void Renderer::renderBatches() glDisable(GL_SCISSOR_TEST); glDisable(GL_STENCIL_TEST); - bindable()->clear(clearMode()); - - if (m_renderPassRecordingCallbacks.start) - m_renderPassRecordingCallbacks.start(m_renderPassRecordingCallbacks.userData); - if (Q_LIKELY(renderOpaque)) { for (int i=0; i<m_opaqueBatches.size(); ++i) { Batch *b = m_opaqueBatches.at(i); diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h index 742a4d03b2..04f1f2732c 100644 --- a/src/quick/scenegraph/qsgadaptationlayer_p.h +++ b/src/quick/scenegraph/qsgadaptationlayer_p.h @@ -465,9 +465,9 @@ public: { return pixelSize / QT_DISTANCEFIELD_BASEFONTSIZE(m_doubleGlyphResolution); } - int distanceFieldRadius() const + qreal distanceFieldRadius() const { - return QT_DISTANCEFIELD_RADIUS(m_doubleGlyphResolution) / QT_DISTANCEFIELD_SCALE(m_doubleGlyphResolution); + return QT_DISTANCEFIELD_RADIUS(m_doubleGlyphResolution) / qreal(QT_DISTANCEFIELD_SCALE(m_doubleGlyphResolution)); } int glyphCount() const { return m_glyphCount; } bool doubleGlyphResolution() const { return m_doubleGlyphResolution; } diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp index 0fd6581dc4..f912da5799 100644 --- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp +++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp @@ -119,7 +119,8 @@ public: protected: void initialize() override; - int m_matrix_id; + int m_projectionMatrix_id; + int m_modelViewMatrix_id; int m_color_id; int m_textureScale_id; float m_devicePixelRatio; @@ -135,7 +136,8 @@ char const *const *QSGTextMaskShader::attributeNames() const QSGTextMaskShader::QSGTextMaskShader(QFontEngine::GlyphFormat glyphFormat) : QSGMaterialShader(*new QSGMaterialShaderPrivate) - , m_matrix_id(-1) + , m_projectionMatrix_id(-1) + , m_modelViewMatrix_id(-1) , m_color_id(-1) , m_textureScale_id(-1) , m_glyphFormat(glyphFormat) @@ -146,7 +148,8 @@ QSGTextMaskShader::QSGTextMaskShader(QFontEngine::GlyphFormat glyphFormat) void QSGTextMaskShader::initialize() { - m_matrix_id = program()->uniformLocation("matrix"); + m_projectionMatrix_id = program()->uniformLocation("projectionMatrix"); + m_modelViewMatrix_id = program()->uniformLocation("modelViewMatrix"); m_color_id = program()->uniformLocation("color"); m_textureScale_id = program()->uniformLocation("textureScale"); m_devicePixelRatio = (float) qsg_device_pixel_ratio(QOpenGLContext::currentContext()); @@ -184,8 +187,10 @@ void QSGTextMaskShader::updateState(const RenderState &state, QSGMaterial *newEf program()->setUniformValue("dpr", m_devicePixelRatio); } - if (state.isMatrixDirty()) - program()->setUniformValue(m_matrix_id, state.combinedMatrix()); + if (state.isMatrixDirty()) { + program()->setUniformValue(m_projectionMatrix_id, state.projectionMatrix()); + program()->setUniformValue(m_modelViewMatrix_id, state.modelViewMatrix()); + } } class QSG8BitTextMaskShader : public QSGTextMaskShader @@ -387,8 +392,10 @@ void QSGStyledTextShader::updateState(const RenderState &state, } } - if (state.isMatrixDirty()) - program()->setUniformValue(m_matrix_id, state.combinedMatrix()); + if (state.isMatrixDirty()) { + program()->setUniformValue(m_projectionMatrix_id, state.projectionMatrix()); + program()->setUniformValue(m_modelViewMatrix_id, state.modelViewMatrix()); + } } class QSGOutlinedTextShader : public QSGStyledTextShader diff --git a/src/quick/scenegraph/qsgopengldistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgopengldistancefieldglyphcache.cpp index b6b6f3b057..6e9894b10b 100644 --- a/src/quick/scenegraph/qsgopengldistancefieldglyphcache.cpp +++ b/src/quick/scenegraph/qsgopengldistancefieldglyphcache.cpp @@ -122,7 +122,7 @@ void QSGOpenGLDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs // We need to add a buffer to avoid glyphs that overlap the border between two // textures causing the height of the textures to extend beyond the limit. - m_maxTextureHeight = m_maxTextureWidth - (qCeil(m_referenceFont.pixelSize() * scaleFactor) + distanceFieldRadius() * 2 + padding * 2); + m_maxTextureHeight = m_maxTextureWidth - (qCeil(m_referenceFont.pixelSize() * scaleFactor + distanceFieldRadius() * 2) + padding * 2); } if (m_areaAllocator == nullptr) @@ -132,8 +132,8 @@ void QSGOpenGLDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs glyph_t glyphIndex = *it; QRectF boundingRect = glyphData(glyphIndex).boundingRect; - int glyphWidth = qCeil(boundingRect.width()) + distanceFieldRadius() * 2; - int glyphHeight = qCeil(boundingRect.height()) + distanceFieldRadius() * 2; + int glyphWidth = qCeil(boundingRect.width() + distanceFieldRadius()) * 2; + int glyphHeight = qCeil(boundingRect.height() + distanceFieldRadius()) * 2; QSize glyphSize(glyphWidth + padding * 2, glyphHeight + padding * 2); QRect alloc = m_areaAllocator->allocate(glyphSize); @@ -144,8 +144,8 @@ void QSGOpenGLDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs TexCoord unusedCoord = glyphTexCoord(unusedGlyph); QRectF unusedGlyphBoundingRect = glyphData(unusedGlyph).boundingRect; - int unusedGlyphWidth = qCeil(unusedGlyphBoundingRect.width()) + distanceFieldRadius() * 2; - int unusedGlyphHeight = qCeil(unusedGlyphBoundingRect.height()) + distanceFieldRadius() * 2; + int unusedGlyphWidth = qCeil(unusedGlyphBoundingRect.width() + distanceFieldRadius()) * 2; + int unusedGlyphHeight = qCeil(unusedGlyphBoundingRect.height() + distanceFieldRadius()) * 2; m_areaAllocator->deallocate(QRect(unusedCoord.x - padding, unusedCoord.y - padding, padding * 2 + unusedGlyphWidth, diff --git a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp index 53b6fe117f..eb4db0f85e 100644 --- a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp +++ b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp @@ -86,8 +86,8 @@ void QSGRhiDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs) int padding = QSG_RHI_DISTANCEFIELD_GLYPH_CACHE_PADDING; QRectF boundingRect = glyphData(glyphIndex).boundingRect; - int glyphWidth = qCeil(boundingRect.width()) + distanceFieldRadius() * 2; - int glyphHeight = qCeil(boundingRect.height()) + distanceFieldRadius() * 2; + int glyphWidth = qCeil(boundingRect.width() + distanceFieldRadius() * 2); + int glyphHeight = qCeil(boundingRect.height() + distanceFieldRadius() * 2); QSize glyphSize(glyphWidth + padding * 2, glyphHeight + padding * 2); QRect alloc = m_areaAllocator->allocate(glyphSize); @@ -98,8 +98,8 @@ void QSGRhiDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs) TexCoord unusedCoord = glyphTexCoord(unusedGlyph); QRectF unusedGlyphBoundingRect = glyphData(unusedGlyph).boundingRect; - int unusedGlyphWidth = qCeil(unusedGlyphBoundingRect.width()) + distanceFieldRadius() * 2; - int unusedGlyphHeight = qCeil(unusedGlyphBoundingRect.height()) + distanceFieldRadius() * 2; + int unusedGlyphWidth = qCeil(unusedGlyphBoundingRect.width() + distanceFieldRadius() * 2); + int unusedGlyphHeight = qCeil(unusedGlyphBoundingRect.height() + distanceFieldRadius() * 2); m_areaAllocator->deallocate(QRect(unusedCoord.x - padding, unusedCoord.y - padding, padding * 2 + unusedGlyphWidth, diff --git a/src/quick/scenegraph/shaders/outlinedtext.vert b/src/quick/scenegraph/shaders/outlinedtext.vert index 9df832de3c..42fa577063 100644 --- a/src/quick/scenegraph/shaders/outlinedtext.vert +++ b/src/quick/scenegraph/shaders/outlinedtext.vert @@ -1,4 +1,5 @@ -uniform highp mat4 matrix; +uniform highp mat4 modelViewMatrix; +uniform highp mat4 projectionMatrix; uniform highp vec2 textureScale; uniform highp vec2 shift; uniform highp float dpr; @@ -19,6 +20,6 @@ void main() sCoordDown = (tCoord - vec2(0.0, 1.0)) * textureScale; sCoordLeft = (tCoord - vec2(-1.0, 0.0)) * textureScale; sCoordRight = (tCoord - vec2(1.0, 0.0)) * textureScale; - vec3 dprSnapPos = floor(vCoord.xyz * dpr + 0.5) / dpr; - gl_Position = matrix * vec4(dprSnapPos, vCoord.w); -}
\ No newline at end of file + vec4 xformed = modelViewMatrix * vCoord; + gl_Position = projectionMatrix * vec4(floor(xformed.xyz * dpr + 0.5) / dpr, xformed.w); +} diff --git a/src/quick/scenegraph/shaders/outlinedtext_core.vert b/src/quick/scenegraph/shaders/outlinedtext_core.vert index a854355460..50a1371e89 100644 --- a/src/quick/scenegraph/shaders/outlinedtext_core.vert +++ b/src/quick/scenegraph/shaders/outlinedtext_core.vert @@ -9,7 +9,8 @@ out vec2 sCoordDown; out vec2 sCoordLeft; out vec2 sCoordRight; -uniform mat4 matrix; +uniform mat4 modelViewMatrix; +uniform mat4 projectionMatrix; uniform vec2 textureScale; uniform vec2 shift; uniform float dpr; @@ -21,6 +22,6 @@ void main() sCoordDown = (tCoord - vec2(0.0, 1.0)) * textureScale; sCoordLeft = (tCoord - vec2(-1.0, 0.0)) * textureScale; sCoordRight = (tCoord - vec2(1.0, 0.0)) * textureScale; - vec3 dprSnapPos = floor(vCoord.xyz * dpr + 0.5) / dpr; - gl_Position = matrix * vec4(dprSnapPos, vCoord.w); -}
\ No newline at end of file + vec4 xformed = modelViewMatrix * vCoord; + gl_Position = projectionMatrix * vec4(floor(xformed.xyz * dpr + 0.5) / dpr, xformed.w); +} diff --git a/src/quick/scenegraph/shaders/styledtext.vert b/src/quick/scenegraph/shaders/styledtext.vert index 29c9902609..dc87dadd5f 100644 --- a/src/quick/scenegraph/shaders/styledtext.vert +++ b/src/quick/scenegraph/shaders/styledtext.vert @@ -1,4 +1,5 @@ -uniform highp mat4 matrix; +uniform highp mat4 modelViewMatrix; +uniform highp mat4 projectionMatrix; uniform highp vec2 textureScale; uniform highp vec2 shift; uniform highp float dpr; @@ -13,6 +14,6 @@ void main() { sampleCoord = tCoord * textureScale; shiftedSampleCoord = (tCoord - shift) * textureScale; - vec3 dprSnapPos = floor(vCoord.xyz * dpr + 0.5) / dpr; - gl_Position = matrix * vec4(dprSnapPos, vCoord.w); + vec4 xformed = modelViewMatrix * vCoord; + gl_Position = projectionMatrix * vec4(floor(xformed.xyz * dpr + 0.5) / dpr, xformed.w); } diff --git a/src/quick/scenegraph/shaders/styledtext_core.vert b/src/quick/scenegraph/shaders/styledtext_core.vert index 04a0e88da8..d9a81bf06f 100644 --- a/src/quick/scenegraph/shaders/styledtext_core.vert +++ b/src/quick/scenegraph/shaders/styledtext_core.vert @@ -6,7 +6,8 @@ in vec2 tCoord; out vec2 sampleCoord; out vec2 shiftedSampleCoord; -uniform mat4 matrix; +uniform mat4 modelViewMatrix; +uniform mat4 projectionMatrix; uniform vec2 textureScale; uniform vec2 shift; uniform float dpr; @@ -15,6 +16,6 @@ void main() { sampleCoord = tCoord * textureScale; shiftedSampleCoord = (tCoord - shift) * textureScale; - vec3 dprSnapPos = floor(vCoord.xyz * dpr + 0.5) / dpr; - gl_Position = matrix * vec4(dprSnapPos, vCoord.w); + vec4 xformed = modelViewMatrix * vCoord; + gl_Position = projectionMatrix * vec4(floor(xformed.xyz * dpr + 0.5) / dpr, xformed.w); } diff --git a/src/quick/scenegraph/shaders/textmask.vert b/src/quick/scenegraph/shaders/textmask.vert index 1692159d2c..7f418b0895 100644 --- a/src/quick/scenegraph/shaders/textmask.vert +++ b/src/quick/scenegraph/shaders/textmask.vert @@ -1,4 +1,5 @@ -uniform highp mat4 matrix; +uniform highp mat4 modelViewMatrix; +uniform highp mat4 projectionMatrix; uniform highp vec2 textureScale; uniform highp float dpr; @@ -10,6 +11,6 @@ varying highp vec2 sampleCoord; void main() { sampleCoord = tCoord * textureScale; - vec3 dprSnapPos = floor(vCoord.xyz * dpr + 0.5) / dpr; - gl_Position = matrix * vec4(dprSnapPos, vCoord.w); + vec4 xformed = modelViewMatrix * vCoord; + gl_Position = projectionMatrix * vec4(floor(xformed.xyz * dpr + 0.5) / dpr, xformed.w); } diff --git a/src/quick/scenegraph/shaders/textmask_core.vert b/src/quick/scenegraph/shaders/textmask_core.vert index b0efc1e731..1f88974aed 100644 --- a/src/quick/scenegraph/shaders/textmask_core.vert +++ b/src/quick/scenegraph/shaders/textmask_core.vert @@ -5,13 +5,14 @@ in vec2 tCoord; out vec2 sampleCoord; -uniform mat4 matrix; +uniform mat4 modelViewMatrix; +uniform mat4 projectionMatrix; uniform vec2 textureScale; uniform float dpr; void main() { sampleCoord = tCoord * textureScale; - vec3 dprSnapPos = floor(vCoord.xyz * dpr + 0.5) / dpr; - gl_Position = matrix * vec4(dprSnapPos, vCoord.w); + vec4 xformed = modelViewMatrix * vCoord; + gl_Position = projectionMatrix * vec4(floor(xformed.xyz * dpr + 0.5) / dpr, xformed.w); } diff --git a/src/quick/util/qquicktimeline.cpp b/src/quick/util/qquicktimeline.cpp index 7ec7c827eb..abe6eb7261 100644 --- a/src/quick/util/qquicktimeline.cpp +++ b/src/quick/util/qquicktimeline.cpp @@ -53,6 +53,8 @@ QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcTl, "qt.quick.timeline") + struct Update { Update(QQuickTimeLineValue *_g, qreal _v) : g(_g), v(_v) {} @@ -513,6 +515,7 @@ void QQuickTimeLine::reset(QQuickTimeLineValue &timeLineValue) qWarning() << "QQuickTimeLine: Cannot reset a QQuickTimeLineValue owned by another timeline."; return; } + qCDebug(lcTl) << static_cast<QObject*>(this) << timeLineValue.value(); remove(&timeLineValue); timeLineValue._t = nullptr; } |