diff options
Diffstat (limited to 'src/quick')
-rw-r--r-- | src/quick/handlers/qquickpointerhandler.cpp | 2 | ||||
-rw-r--r-- | src/quick/items/qquickflickable.cpp | 40 | ||||
-rw-r--r-- | src/quick/items/qquickflickable_p_p.h | 4 | ||||
-rw-r--r-- | src/quick/items/qquickmousearea.cpp | 3 | ||||
-rw-r--r-- | src/quick/items/qquickmultipointtoucharea.cpp | 26 | ||||
-rw-r--r-- | src/quick/items/qquickmultipointtoucharea_p.h | 7 | ||||
-rw-r--r-- | src/quick/items/qquicktext.cpp | 32 | ||||
-rw-r--r-- | src/quick/items/qquicktext_p.h | 2 | ||||
-rw-r--r-- | src/quick/items/qquicktextedit_p.h | 2 | ||||
-rw-r--r-- | src/quick/items/qquicktextinput.cpp | 23 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 68 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgopenglvisualizer.cpp | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgdefaultglyphnode_p.cpp | 9 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgdefaultrendercontext.cpp | 15 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgdefaultrendercontext_p.h | 1 | ||||
-rw-r--r-- | src/quick/util/qquickpropertychanges.cpp | 35 |
17 files changed, 149 insertions, 124 deletions
diff --git a/src/quick/handlers/qquickpointerhandler.cpp b/src/quick/handlers/qquickpointerhandler.cpp index 908c616d74..67700e04fa 100644 --- a/src/quick/handlers/qquickpointerhandler.cpp +++ b/src/quick/handlers/qquickpointerhandler.cpp @@ -421,6 +421,8 @@ bool QQuickPointerHandler::approveGrabTransition(QQuickEventPoint *point, QObjec This handler can take the exclusive grab from another handler of the same class. \value PointerHandler.CanTakeOverFromHandlersOfDifferentType This handler can take the exclusive grab from any kind of handler. + \value PointerHandler.CanTakeOverFromItems + This handler can take the exclusive grab from any type of Item. \value PointerHandler.CanTakeOverFromAnything This handler can take the exclusive grab from any type of Item or Handler. \value PointerHandler.ApprovesTakeOverByHandlersOfSameType diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index a9f5aec7a3..ea357d819d 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -326,7 +326,7 @@ void QQuickFlickablePrivate::AxisData::updateVelocity() } } -void QQuickFlickablePrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &) +void QQuickFlickablePrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &oldGeom) { Q_Q(QQuickFlickable); if (item == contentItem) { @@ -335,8 +335,14 @@ void QQuickFlickablePrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometr orient |= Qt::Horizontal; if (change.yChange()) orient |= Qt::Vertical; - if (orient) + if (orient) { q->viewportMoved(orient); + const QPointF deltaMoved = item->position() - oldGeom.topLeft(); + if (hData.contentPositionChangedExternallyDuringDrag) + hData.pressPos += deltaMoved.x(); + if (vData.contentPositionChangedExternallyDuringDrag) + vData.pressPos += deltaMoved.y(); + } if (orient & Qt::Horizontal) emit q->contentXChanged(); if (orient & Qt::Vertical) @@ -796,8 +802,11 @@ void QQuickFlickable::setContentX(qreal pos) d->hData.vTime = d->timeline.time(); if (isMoving() || isFlicking()) movementEnding(true, false); - if (!qFuzzyCompare(-pos, d->hData.move.value())) + if (!qFuzzyCompare(-pos, d->hData.move.value())) { + d->hData.contentPositionChangedExternallyDuringDrag = d->hData.dragging; d->hData.move.setValue(-pos); + d->hData.contentPositionChangedExternallyDuringDrag = false; + } } qreal QQuickFlickable::contentY() const @@ -814,8 +823,11 @@ void QQuickFlickable::setContentY(qreal pos) d->vData.vTime = d->timeline.time(); if (isMoving() || isFlicking()) movementEnding(false, true); - if (!qFuzzyCompare(-pos, d->vData.move.value())) + if (!qFuzzyCompare(-pos, d->vData.move.value())) { + d->vData.contentPositionChangedExternallyDuringDrag = d->vData.dragging; d->vData.move.setValue(-pos); + d->vData.contentPositionChangedExternallyDuringDrag = false; + } } /*! @@ -2108,9 +2120,11 @@ void QQuickFlickable::setContentWidth(qreal w) d->contentItem->setWidth(w); d->hData.markExtentsDirty(); // Make sure that we're entirely in view. - if (!d->pressed && !d->hData.moving && !d->vData.moving) { + if ((!d->pressed && !d->hData.moving && !d->vData.moving) || d->hData.dragging) { + d->hData.contentPositionChangedExternallyDuringDrag = d->hData.dragging; d->fixupMode = QQuickFlickablePrivate::Immediate; d->fixupX(); + d->hData.contentPositionChangedExternallyDuringDrag = false; } else if (!d->pressed && d->hData.fixingUp) { d->fixupMode = QQuickFlickablePrivate::ExtentChanged; d->fixupX(); @@ -2137,9 +2151,11 @@ void QQuickFlickable::setContentHeight(qreal h) d->contentItem->setHeight(h); d->vData.markExtentsDirty(); // Make sure that we're entirely in view. - if (!d->pressed && !d->hData.moving && !d->vData.moving) { + if ((!d->pressed && !d->hData.moving && !d->vData.moving) || d->vData.dragging) { + d->vData.contentPositionChangedExternallyDuringDrag = d->vData.dragging; d->fixupMode = QQuickFlickablePrivate::Immediate; d->fixupY(); + d->vData.contentPositionChangedExternallyDuringDrag = false; } else if (!d->pressed && d->vData.fixingUp) { d->fixupMode = QQuickFlickablePrivate::ExtentChanged; d->fixupY(); @@ -2766,6 +2782,12 @@ void QQuickFlickable::movementStarting() if (!wasMoving && (d->hData.moving || d->vData.moving)) { emit movingChanged(); emit movementStarted(); +#if QT_CONFIG(accessibility) + if (QAccessible::isActive()) { + QAccessibleEvent ev(this, QAccessible::ScrollingStart); + QAccessible::updateAccessibility(&ev); + } +#endif } } @@ -2810,6 +2832,12 @@ void QQuickFlickable::movementEnding(bool hMovementEnding, bool vMovementEnding) if (wasMoving && !isMoving()) { emit movingChanged(); emit movementEnded(); +#if QT_CONFIG(accessibility) + if (QAccessible::isActive()) { + QAccessibleEvent ev(this, QAccessible::ScrollingEnd); + QAccessible::updateAccessibility(&ev); + } +#endif } if (hMovementEnding) { diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h index 6163613493..d5d838eaea 100644 --- a/src/quick/items/qquickflickable_p_p.h +++ b/src/quick/items/qquickflickable_p_p.h @@ -109,6 +109,7 @@ public: , fixingUp(false), inOvershoot(false), inRebound(false), moving(false), flicking(false) , dragging(false), extentsChanged(false) , explicitValue(false), minExtentDirty(true), maxExtentDirty(true) + , contentPositionChangedExternallyDuringDrag(false) , unused(0) {} @@ -169,7 +170,8 @@ public: bool explicitValue : 1; mutable bool minExtentDirty : 1; mutable bool maxExtentDirty : 1; - uint unused : 19; + bool contentPositionChangedExternallyDuringDrag : 1; + uint unused : 18; }; bool flickX(qreal velocity); diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp index 867a36a362..3e2e4fc1cf 100644 --- a/src/quick/items/qquickmousearea.cpp +++ b/src/quick/items/qquickmousearea.cpp @@ -806,7 +806,8 @@ void QQuickMouseArea::mouseReleaseEvent(QMouseEvent *event) QQuickWindow *w = window(); if (w && w->mouseGrabberItem() == this) ungrabMouse(); - setKeepMouseGrab(false); + if (!d->preventStealing) + setKeepMouseGrab(false); } } d->doubleClick = false; diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp index 7573b41f67..4d420969cf 100644 --- a/src/quick/items/qquickmultipointtoucharea.cpp +++ b/src/quick/items/qquickmultipointtoucharea.cpp @@ -569,7 +569,7 @@ void QQuickMultiPointTouchArea::grabGesture() setKeepTouchGrab(true); } -void QQuickMultiPointTouchArea::updateTouchData(QEvent *event) +void QQuickMultiPointTouchArea::updateTouchData(QEvent *event, RemapEventPoints remap) { bool ended = false; bool moved = false; @@ -578,12 +578,14 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event) clearTouchLists(); QList<QTouchEvent::TouchPoint> touchPoints; QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window()); + bool touchPointsFromEvent = false; switch (event->type()) { case QEvent::TouchBegin: case QEvent::TouchUpdate: case QEvent::TouchEnd: touchPoints = static_cast<QTouchEvent*>(event)->touchPoints(); + touchPointsFromEvent = true; break; case QEvent::MouseButtonPress: _mouseQpaTouchPoint = QTouchEvent::TouchPoint(windowPriv->touchMouseId); @@ -614,6 +616,8 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event) qWarning("updateTouchData: unhandled event type %d", event->type()); break; } + if (!touchPointsFromEvent) + remap = RemapEventPoints::No; int numTouchPoints = touchPoints.count(); //always remove released touches, and make sure we handle all releases before adds. @@ -624,7 +628,7 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event) QQuickTouchPoint* dtp = static_cast<QQuickTouchPoint*>(_touchPoints.value(id)); if (!dtp) continue; - updateTouchPoint(dtp, &p); + updateTouchPoint(dtp, &p, RemapEventPoints::No); dtp->setPressed(false); _releasedTouchPoints.append(dtp); _touchPoints.remove(id); @@ -639,19 +643,19 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event) //handled above } else if (!_touchPoints.contains(id)) { //could be pressed, moved, or stationary // (we may have just obtained enough points to start tracking them -- in that case moved or stationary count as newly pressed) - addTouchPoint(&p); + addTouchPoint(&p, remap); started = true; } else if ((touchPointState & Qt::TouchPointMoved) || p.d->stationaryWithModifiedProperty) { // React to a stationary point with a property change (velocity, pressure) as if the point moved. (QTBUG-77142) QQuickTouchPoint* dtp = static_cast<QQuickTouchPoint*>(_touchPoints.value(id)); Q_ASSERT(dtp); _movedTouchPoints.append(dtp); - updateTouchPoint(dtp,&p); + updateTouchPoint(dtp, &p, remap); moved = true; } else { QQuickTouchPoint* dtp = static_cast<QQuickTouchPoint*>(_touchPoints.value(id)); Q_ASSERT(dtp); - updateTouchPoint(dtp,&p); + updateTouchPoint(dtp, &p, remap); } } @@ -707,7 +711,7 @@ void QQuickMultiPointTouchArea::clearTouchLists() _movedTouchPoints.clear(); } -void QQuickMultiPointTouchArea::addTouchPoint(const QTouchEvent::TouchPoint *p) +void QQuickMultiPointTouchArea::addTouchPoint(const QTouchEvent::TouchPoint *p, RemapEventPoints remap) { QQuickTouchPoint *dtp = nullptr; for (QQuickTouchPoint* tp : qAsConst(_touchPrototypes)) { @@ -721,7 +725,7 @@ void QQuickMultiPointTouchArea::addTouchPoint(const QTouchEvent::TouchPoint *p) if (dtp == nullptr) dtp = new QQuickTouchPoint(false); dtp->setPointId(p->id()); - updateTouchPoint(dtp,p); + updateTouchPoint(dtp, p, remap); dtp->setPressed(true); _touchPoints.insert(p->id(),dtp); _pressedTouchPoints.append(dtp); @@ -782,12 +786,12 @@ void QQuickMultiPointTouchArea::addTouchPrototype(QQuickTouchPoint *prototype) _touchPrototypes.insert(id, prototype); } -void QQuickMultiPointTouchArea::updateTouchPoint(QQuickTouchPoint *dtp, const QTouchEvent::TouchPoint *p) +void QQuickMultiPointTouchArea::updateTouchPoint(QQuickTouchPoint *dtp, const QTouchEvent::TouchPoint *p, RemapEventPoints remap) { //TODO: if !qmlDefined, could bypass setters. // also, should only emit signals after all values have been set dtp->setUniqueId(p->uniqueId()); - dtp->setPosition(p->pos()); + dtp->setPosition(remap == RemapEventPoints::ToLocal ? mapFromScene(p->scenePos()) : p->pos()); dtp->setEllipseDiameters(p->ellipseDiameters()); dtp->setPressure(p->pressure()); dtp->setRotation(p->rotation()); @@ -975,12 +979,12 @@ bool QQuickMultiPointTouchArea::childMouseEventFilter(QQuickItem *receiver, QEve } if (!shouldFilter(event)) return false; - updateTouchData(event); + updateTouchData(event, RemapEventPoints::ToLocal); return _stealMouse; case QEvent::TouchEnd: { if (!shouldFilter(event)) return false; - updateTouchData(event); + updateTouchData(event, RemapEventPoints::ToLocal); ungrab(true); } break; diff --git a/src/quick/items/qquickmultipointtoucharea_p.h b/src/quick/items/qquickmultipointtoucharea_p.h index e34a3faad6..85c1e2258e 100644 --- a/src/quick/items/qquickmultipointtoucharea_p.h +++ b/src/quick/items/qquickmultipointtoucharea_p.h @@ -267,14 +267,15 @@ protected: void mouseUngrabEvent() override; void touchUngrabEvent() override; + enum class RemapEventPoints { No, ToLocal }; void addTouchPrototype(QQuickTouchPoint* prototype); - void addTouchPoint(const QTouchEvent::TouchPoint *p); + void addTouchPoint(const QTouchEvent::TouchPoint *p, RemapEventPoints remap); void addTouchPoint(const QMouseEvent *e); void clearTouchLists(); - void updateTouchPoint(QQuickTouchPoint*, const QTouchEvent::TouchPoint*); + void updateTouchPoint(QQuickTouchPoint*, const QTouchEvent::TouchPoint*, RemapEventPoints remap); void updateTouchPoint(QQuickTouchPoint *dtp, const QMouseEvent *e); - void updateTouchData(QEvent*); + void updateTouchData(QEvent*, RemapEventPoints remap = RemapEventPoints::No); bool sendMouseEvent(QMouseEvent *event); bool shouldFilter(QEvent *event); diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index c135a7f272..d8fd2017e3 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -2409,21 +2409,23 @@ void QQuickText::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeo goto geomChangeDone; if (!(widthChanged || widthMaximum) && !d->isLineLaidOutConnected()) { // only height has changed - if (newGeometry.height() > oldGeometry.height()) { - if (!d->heightExceeded && !qFuzzyIsNull(oldGeometry.height())) { - // Height is adequate and growing, and it wasn't 0 previously. - goto geomChangeDone; - } - if (d->lineCount == d->maximumLineCount()) // Reached maximum line and height is growing. - goto geomChangeDone; - } else if (newGeometry.height() < oldGeometry.height()) { - if (d->lineCount < 2 && !verticalScale && newGeometry.height() > 0) // A single line won't be truncated until the text is 0 height. - goto geomChangeDone; - - if (!verticalScale // no scaling, no eliding, and either unwrapped, or no maximum line count. - && d->elideMode != QQuickText::ElideRight - && !(d->maximumLineCountValid && d->widthExceeded)) { - goto geomChangeDone; + if (!verticalPositionChanged) { + if (newGeometry.height() > oldGeometry.height()) { + if (!d->heightExceeded && !qFuzzyIsNull(oldGeometry.height())) { + // Height is adequate and growing, and it wasn't 0 previously. + goto geomChangeDone; + } + if (d->lineCount == d->maximumLineCount()) // Reached maximum line and height is growing. + goto geomChangeDone; + } else if (newGeometry.height() < oldGeometry.height()) { + if (d->lineCount < 2 && !verticalScale && newGeometry.height() > 0) // A single line won't be truncated until the text is 0 height. + goto geomChangeDone; + + if (!verticalScale // no scaling, no eliding, and either unwrapped, or no maximum line count. + && d->elideMode != QQuickText::ElideRight + && !(d->maximumLineCountValid && d->widthExceeded)) { + goto geomChangeDone; + } } } } else if (!heightChanged && widthMaximum) { diff --git a/src/quick/items/qquicktext_p.h b/src/quick/items/qquicktext_p.h index 0fffc1fb9a..698f9649dd 100644 --- a/src/quick/items/qquicktext_p.h +++ b/src/quick/items/qquicktext_p.h @@ -326,6 +326,8 @@ private: Q_DECLARE_PRIVATE(QQuickText) }; +Q_DECLARE_MIXED_ENUM_OPERATORS_SYMMETRIC(int, QQuickText::HAlignment, QQuickText::VAlignment) + class QTextLine; class QQuickTextLine : public QObject { diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h index 227d8cbf51..88ba2f9d0d 100644 --- a/src/quick/items/qquicktextedit_p.h +++ b/src/quick/items/qquicktextedit_p.h @@ -422,6 +422,8 @@ private: Q_DECLARE_PRIVATE(QQuickTextEdit) }; +Q_DECLARE_MIXED_ENUM_OPERATORS_SYMMETRIC(int, QQuickTextEdit::HAlignment, QQuickTextEdit::VAlignment) + QT_END_NAMESPACE QML_DECLARE_TYPE(QQuickTextEdit) diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index c3d013f166..9db18d1683 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -518,8 +518,16 @@ void QQuickTextInput::setSelectedTextColor(const QColor &color) } /*! - \qmlproperty enumeration QtQuick::TextInput::horizontalAlignment \qmlproperty enumeration QtQuick::TextInput::effectiveHorizontalAlignment + \readonly + + When using the attached property LayoutMirroring::enabled to mirror application + layouts, the horizontal alignment of text will also be mirrored. However, the property + \l horizontalAlignment will remain unchanged. To query the effective horizontal alignment + of TextInput, use the read-only property \c effectiveHorizontalAlignment. +*/ +/*! + \qmlproperty enumeration QtQuick::TextInput::horizontalAlignment \qmlproperty enumeration QtQuick::TextInput::verticalAlignment Sets the horizontal alignment of the text within the TextInput item's @@ -542,7 +550,7 @@ void QQuickTextInput::setSelectedTextColor(const QColor &color) When using the attached property LayoutMirroring::enabled to mirror application layouts, the horizontal alignment of text will also be mirrored. However, the property \c horizontalAlignment will remain unchanged. To query the effective horizontal alignment - of TextInput, use the read-only property \c effectiveHorizontalAlignment. + of TextInput, use the read-only property \l effectiveHorizontalAlignment. */ QQuickTextInput::HAlignment QQuickTextInput::hAlign() const { @@ -862,6 +870,7 @@ void QQuickTextInput::setCursorPosition(int cp) /*! \qmlproperty rectangle QtQuick::TextInput::cursorRectangle + \readonly The rectangle where the standard text cursor is rendered within the text input. Read only. @@ -903,6 +912,7 @@ QRectF QQuickTextInput::cursorRectangle() const This property is read-only. To change the selection, use select(start,end), selectAll(), or selectWord(). + \readonly \sa selectionEnd, cursorPosition, selectedText */ int QQuickTextInput::selectionStart() const @@ -918,6 +928,7 @@ int QQuickTextInput::selectionStart() const This property is read-only. To change the selection, use select(start,end), selectAll(), or selectWord(). + \readonly \sa selectionStart, cursorPosition, selectedText */ int QQuickTextInput::selectionEnd() const @@ -948,6 +959,7 @@ void QQuickTextInput::select(int start, int end) /*! \qmlproperty string QtQuick::TextInput::selectedText + \readonly This read-only property provides the text currently selected in the text input. @@ -2473,6 +2485,7 @@ void QQuickTextInput::setPersistentSelection(bool on) /*! \qmlproperty bool QtQuick::TextInput::canPaste + \readonly Returns true if the TextInput is writable and the content of the clipboard is suitable for pasting into the TextInput. @@ -2494,6 +2507,7 @@ bool QQuickTextInput::canPaste() const /*! \qmlproperty bool QtQuick::TextInput::canUndo + \readonly Returns true if the TextInput is writable and there are previous operations that can be undone. @@ -2507,6 +2521,7 @@ bool QQuickTextInput::canUndo() const /*! \qmlproperty bool QtQuick::TextInput::canRedo + \readonly Returns true if the TextInput is writable and there are \l {undo}{undone} operations that can be redone. @@ -2520,6 +2535,7 @@ bool QQuickTextInput::canRedo() const /*! \qmlproperty real QtQuick::TextInput::contentWidth + \readonly Returns the width of the text, including the width past the width which is covered due to insufficient wrapping if \l wrapMode is set. @@ -2533,6 +2549,7 @@ qreal QQuickTextInput::contentWidth() const /*! \qmlproperty real QtQuick::TextInput::contentHeight + \readonly Returns the height of the text, including the height past the height that is covered if the text does not fit within the set height. @@ -2696,7 +2713,7 @@ void QQuickTextInput::focusOutEvent(QFocusEvent *event) /*! \qmlproperty bool QtQuick::TextInput::inputMethodComposing - + \readonly This property holds whether the TextInput has partial text input from an input method. diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 5e3f48584d..50b7a333c7 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -2209,6 +2209,8 @@ bool QQuickWindowPrivate::deliverSinglePointEventUntilAccepted(QQuickPointerEven itemPrivate->handlePointerEvent(event); if (point->isAccepted()) return true; + if (!item->window()) + continue; QPointF g = item->window()->mapToGlobal(point->scenePosition().toPoint()); #if QT_CONFIG(wheelevent) // Let the Item have a chance to handle it diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index 79d3fca500..8f24617b24 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -1068,11 +1068,10 @@ static void qsg_wipeBuffer(Buffer *buffer, QOpenGLFunctions *funcs) free(buffer->data); } -static void qsg_wipeBatch(Batch *batch, QOpenGLFunctions *funcs, bool separateIndexBuffer) +static void qsg_wipeBatch(Batch *batch, QOpenGLFunctions *funcs) { qsg_wipeBuffer(&batch->vbo, funcs); - if (separateIndexBuffer) - qsg_wipeBuffer(&batch->ibo, funcs); + qsg_wipeBuffer(&batch->ibo, funcs); delete batch->ubuf; batch->stencilClipState.reset(); delete batch; @@ -1082,13 +1081,12 @@ Renderer::~Renderer() { if (m_rhi || QOpenGLContext::currentContext()) { // Clean up batches and buffers - const bool separateIndexBuffer = m_context->separateIndexBuffer(); for (int i = 0; i < m_opaqueBatches.size(); ++i) - qsg_wipeBatch(m_opaqueBatches.at(i), this, separateIndexBuffer); + qsg_wipeBatch(m_opaqueBatches.at(i), this); for (int i = 0; i < m_alphaBatches.size(); ++i) - qsg_wipeBatch(m_alphaBatches.at(i), this, separateIndexBuffer); + qsg_wipeBatch(m_alphaBatches.at(i), this); for (int i = 0; i < m_batchPool.size(); ++i) - qsg_wipeBatch(m_batchPool.at(i), this, separateIndexBuffer); + qsg_wipeBatch(m_batchPool.at(i), this); } for (Node *n : qAsConst(m_nodes)) @@ -1162,8 +1160,7 @@ void Renderer::map(Buffer *buffer, int byteSize, bool isIndexBuf) if (!m_context->hasBrokenIndexBufferObjects() && m_visualizer->mode() == Visualizer::VisualizeNothing) { // Common case, use a shared memory pool for uploading vertex data to avoid // excessive reevaluation - QDataBuffer<char> &pool = m_context->separateIndexBuffer() && isIndexBuf - ? m_indexUploadPool : m_vertexUploadPool; + QDataBuffer<char> &pool = isIndexBuf ? m_indexUploadPool : m_vertexUploadPool; if (byteSize > pool.size()) pool.resize(byteSize); buffer->data = pool.data(); @@ -2215,15 +2212,6 @@ void Renderer::uploadBatch(Batch *b) */ int bufferSize = b->vertexCount * g->sizeOfVertex(); int ibufferSize = 0; - // At this point, we need to check if the vertices byte size is 4 byte aligned or not. - // If an unaligned value is used in a shared buffer with indices, it causes problems with - // glDrawElements. We need to do a 4 byte alignment so that it can work with both - // QSGGeometry::UnsignedShortType and QSGGeometry::UnsignedIntType - int paddingBytes = 0; - if (!m_context->separateIndexBuffer()) { - paddingBytes = aligned(bufferSize, 4) - bufferSize; - bufferSize += paddingBytes; - } if (b->merged) { ibufferSize = b->indexCount * mergedIndexElemSize(); if (m_useDepthBuffer) @@ -2232,11 +2220,7 @@ void Renderer::uploadBatch(Batch *b) ibufferSize = unmergedIndexSize; } - const bool separateIndexBuffer = m_context->separateIndexBuffer(); - if (separateIndexBuffer) - map(&b->ibo, ibufferSize, true); - else - bufferSize += ibufferSize; + map(&b->ibo, ibufferSize, true); map(&b->vbo, bufferSize); if (Q_UNLIKELY(debug_upload())) qDebug() << " - batch" << b << " first:" << b->first << " root:" @@ -2246,9 +2230,7 @@ void Renderer::uploadBatch(Batch *b) if (b->merged) { char *vertexData = b->vbo.data; char *zData = vertexData + b->vertexCount * g->sizeOfVertex(); - char *indexData = separateIndexBuffer - ? b->ibo.data - : zData + (int(m_useDepthBuffer) * b->vertexCount * sizeof(float)) + paddingBytes; + char *indexData = b->ibo.data; quint16 iOffset16 = 0; quint32 iOffset32 = 0; @@ -2260,8 +2242,8 @@ void Renderer::uploadBatch(Batch *b) const uint verticesInSetLimit = m_uint32IndexForRhi ? 0xfffffffe : 0xfffe; int indicesInSet = 0; b->drawSets.reset(); - int drawSetIndices = separateIndexBuffer ? 0 : indexData - vertexData; - const char *indexBase = separateIndexBuffer ? b->ibo.data : b->vbo.data; + int drawSetIndices = 0; + const char *indexBase = b->ibo.data; b->drawSets << DrawSet(0, zData - vertexData, drawSetIndices); while (e) { verticesInSet += e->node->geometry()->vertexCount(); @@ -2295,8 +2277,7 @@ void Renderer::uploadBatch(Batch *b) } } else { char *vboData = b->vbo.data; - char *iboData = separateIndexBuffer ? b->ibo.data - : vboData + b->vertexCount * g->sizeOfVertex() + paddingBytes; + char *iboData = b->ibo.data; Element *e = b->first; while (e) { QSGGeometry *g = e->node->geometry(); @@ -2364,9 +2345,7 @@ void Renderer::uploadBatch(Batch *b) if (!b->drawSets.isEmpty()) { if (m_uint32IndexForRhi) { - const quint32 *id = (const quint32 *)(separateIndexBuffer - ? b->ibo.data - : b->vbo.data + b->drawSets.at(0).indices); + const quint32 *id = (const quint32 *) b->ibo.data; { QDebug iDump = qDebug(); iDump << " -- Index Data, count:" << b->indexCount; @@ -2377,9 +2356,7 @@ void Renderer::uploadBatch(Batch *b) } } } else { - const quint16 *id = (const quint16 *)(separateIndexBuffer - ? b->ibo.data - : b->vbo.data + b->drawSets.at(0).indices); + const quint16 *id = (const quint16 *) b->ibo.data; { QDebug iDump = qDebug(); iDump << " -- Index Data, count:" << b->indexCount; @@ -2400,8 +2377,7 @@ void Renderer::uploadBatch(Batch *b) #endif // QT_NO_DEBUG_OUTPUT unmap(&b->vbo); - if (separateIndexBuffer) - unmap(&b->ibo, true); + unmap(&b->ibo, true); if (Q_UNLIKELY(debug_upload())) qDebug() << " --- vertex/index buffers unmapped, batch upload completed..."; @@ -3061,7 +3037,7 @@ void Renderer::renderMergedBatch(const Batch *batch) // legacy (GL-only) glBindBuffer(GL_ARRAY_BUFFER, batch->vbo.id); char *indexBase = nullptr; - const Buffer *indexBuf = m_context->separateIndexBuffer() ? &batch->ibo : &batch->vbo; + const Buffer *indexBuf = &batch->ibo; if (m_context->hasBrokenIndexBufferObjects()) { indexBase = indexBuf->data; glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); @@ -3154,8 +3130,7 @@ void Renderer::renderUnmergedBatch(const Batch *batch) // legacy (GL-only) glBindBuffer(GL_ARRAY_BUFFER, batch->vbo.id); char *indexBase = nullptr; - const bool separateIndexBuffer = m_context->separateIndexBuffer(); - const Buffer *indexBuf = separateIndexBuffer ? &batch->ibo : &batch->vbo; + const Buffer *indexBuf = &batch->ibo; if (batch->indexCount) { if (m_context->hasBrokenIndexBufferObjects()) { indexBase = indexBuf->data; @@ -3185,15 +3160,6 @@ void Renderer::renderUnmergedBatch(const Batch *batch) // legacy (GL-only) int vOffset = 0; char *iOffset = indexBase; - // If a shared buffer is used, 4 byte alignment was done to avoid issues - // while using glDrawElements with both QSGGeometry::UnsignedShortType and - // QSGGeometry::UnsignedIntType. Here, we need to take this into account - // while calculating iOffset value to end up with the correct offset for drawing. - int vertexDataByteSize = batch->vertexCount * gn->geometry()->sizeOfVertex(); - vertexDataByteSize = aligned(vertexDataByteSize, 4); - if (!separateIndexBuffer) - iOffset += vertexDataByteSize; - QMatrix4x4 rootMatrix = batch->root ? qsg_matrixForRoot(batch->root) : QMatrix4x4(); while (e) { @@ -4363,7 +4329,7 @@ void Renderer::render() if (largestVBO * 2 < m_vertexUploadPool.size()) m_vertexUploadPool.resize(largestVBO * 2); - if (m_context->separateIndexBuffer() && largestIBO * 2 < m_indexUploadPool.size()) + if (largestIBO * 2 < m_indexUploadPool.size()) m_indexUploadPool.resize(largestIBO * 2); renderBatches(); diff --git a/src/quick/scenegraph/coreapi/qsgopenglvisualizer.cpp b/src/quick/scenegraph/coreapi/qsgopenglvisualizer.cpp index 9282b6c308..c7af996a30 100644 --- a/src/quick/scenegraph/coreapi/qsgopenglvisualizer.cpp +++ b/src/quick/scenegraph/coreapi/qsgopenglvisualizer.cpp @@ -130,7 +130,7 @@ void OpenGLVisualizer::visualizeBatch(Batch *b) if (b->merged) { shader->setUniformValue(shader->matrix, matrix); - const char *dataStart = m_renderer->m_context->separateIndexBuffer() ? b->ibo.data : b->vbo.data; + const char *dataStart = b->ibo.data; for (int ds=0; ds<b->drawSets.size(); ++ds) { const DrawSet &set = b->drawSets.at(ds); m_funcs->glVertexAttribPointer(a.position, 2, a.type, false, g->sizeOfVertex(), diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp index f912da5799..10fd2c094d 100644 --- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp +++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp @@ -818,8 +818,11 @@ void QSGTextMaskMaterial::populate(const QPointF &p, QTextureGlyphCache *cache = glyphCache(); QRawFontPrivate *fontD = QRawFontPrivate::get(m_font); - cache->populate(fontD->fontEngine, glyphIndexes.size(), glyphIndexes.constData(), - fixedPointPositions.data()); + cache->populate(fontD->fontEngine, + glyphIndexes.size(), + glyphIndexes.constData(), + fixedPointPositions.data(), + true); cache->fillInPendingGlyphs(); int margin = fontD->fontEngine->glyphMargin(cache->glyphFormat()); @@ -841,7 +844,7 @@ void QSGTextMaskMaterial::populate(const QPointF &p, QPointF glyphPosition = glyphPositions.at(i) + position; QFixed subPixelPosition; if (supportsSubPixelPositions) - subPixelPosition = fontD->fontEngine->subPixelPositionForX(QFixed::fromReal(glyphPosition.x())); + subPixelPosition = fontD->fontEngine->subPixelPositionForX(QFixed::fromReal(glyphPosition.x() * glyphCacheScaleX)); QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphIndexes.at(i), subPixelPosition); const QTextureGlyphCache::Coord &c = cache->coords.value(glyph); diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp index bf7bb052bb..0e11a062de 100644 --- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp +++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp @@ -415,21 +415,6 @@ QSGDefaultRenderContext *QSGDefaultRenderContext::from(QOpenGLContext *context) return qobject_cast<QSGDefaultRenderContext *>(context->property(QSG_RENDERCONTEXT_PROPERTY).value<QObject *>()); } -bool QSGDefaultRenderContext::separateIndexBuffer() const -{ - if (m_rhi) - return true; - - // WebGL: A given WebGLBuffer object may only be bound to one of - // the ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER target in its - // lifetime. An attempt to bind a buffer object to the other - // target will generate an INVALID_OPERATION error, and the - // current binding will remain untouched. - static const bool isWebGL = (qGuiApp->platformName().compare(QLatin1String("webgl")) == 0 - || qGuiApp->platformName().compare(QLatin1String("wasm")) == 0); - return isWebGL; -} - void QSGDefaultRenderContext::preprocess() { for (auto it = m_glyphCaches.begin(); it != m_glyphCaches.end(); ++it) { diff --git a/src/quick/scenegraph/qsgdefaultrendercontext_p.h b/src/quick/scenegraph/qsgdefaultrendercontext_p.h index e90a11eda6..6da67264d1 100644 --- a/src/quick/scenegraph/qsgdefaultrendercontext_p.h +++ b/src/quick/scenegraph/qsgdefaultrendercontext_p.h @@ -140,7 +140,6 @@ public: bool hasBrokenIndexBufferObjects() const { return m_brokenIBOs; } int maxTextureSize() const override { return m_maxTextureSize; } - bool separateIndexBuffer() const; int msaaSampleCount() const { return m_initParams.sampleCount; } diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp index 1cb30f5a8d..7a47f132fe 100644 --- a/src/quick/util/qquickpropertychanges.cpp +++ b/src/quick/util/qquickpropertychanges.cpp @@ -239,18 +239,22 @@ public: void QQuickPropertyChangesParser::verifyList(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QV4::CompiledData::Binding *binding) { - if (binding->type == QV4::CompiledData::Binding::Type_Object) { - error(compilationUnit->objectAt(binding->value.objectIndex), QQuickPropertyChanges::tr("PropertyChanges does not support creating state-specific objects.")); - return; - } - - if (binding->type == QV4::CompiledData::Binding::Type_GroupProperty - || binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) { + switch (binding->type()) { + case QV4::CompiledData::Binding::Type_Object: + error(compilationUnit->objectAt(binding->value.objectIndex), + QQuickPropertyChanges::tr( + "PropertyChanges does not support creating state-specific objects.")); + break; + case QV4::CompiledData::Binding::Type_GroupProperty: + case QV4::CompiledData::Binding::Type_AttachedProperty: { const QV4::CompiledData::Object *subObj = compilationUnit->objectAt(binding->value.objectIndex); const QV4::CompiledData::Binding *subBinding = subObj->bindingTable(); - for (quint32 i = 0; i < subObj->nBindings; ++i, ++subBinding) { + for (quint32 i = 0; i < subObj->nBindings; ++i, ++subBinding) verifyList(compilationUnit, subBinding); - } + break; + } + default: + break; } } @@ -273,8 +277,9 @@ void QQuickPropertyChangesPrivate::decodeBinding(const QString &propertyPrefix, QString propertyName = propertyPrefix + compilationUnit->stringAt(binding->propertyNameIndex); - if (binding->type == QV4::CompiledData::Binding::Type_GroupProperty - || binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) { + switch (binding->type()) { + case QV4::CompiledData::Binding::Type_GroupProperty: + case QV4::CompiledData::Binding::Type_AttachedProperty: { QString pre = propertyName + QLatin1Char('.'); const QV4::CompiledData::Object *subObj = compilationUnit->objectAt(binding->value.objectIndex); const QV4::CompiledData::Binding *subBinding = subObj->bindingTable(); @@ -283,6 +288,9 @@ void QQuickPropertyChangesPrivate::decodeBinding(const QString &propertyPrefix, } return; } + default: + break; + } if (propertyName.count() >= 3 && propertyName.at(0) == QLatin1Char('o') && @@ -299,7 +307,8 @@ void QQuickPropertyChangesPrivate::decodeBinding(const QString &propertyPrefix, } } - if (binding->type == QV4::CompiledData::Binding::Type_Script || binding->isTranslationBinding()) { + if (binding->type() == QV4::CompiledData::Binding::Type_Script + || binding->isTranslationBinding()) { QUrl url = QUrl(); int line = -1; int column = -1; @@ -323,7 +332,7 @@ void QQuickPropertyChangesPrivate::decodeBinding(const QString &propertyPrefix, } QVariant var; - switch (binding->type) { + switch (binding->type()) { case QV4::CompiledData::Binding::Type_Script: case QV4::CompiledData::Binding::Type_Translation: case QV4::CompiledData::Binding::Type_TranslationById: |