summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/animation/qabstractanimation.cpp2
-rw-r--r--src/corelib/tools/qeasingcurve.cpp6
-rw-r--r--src/gui/dialogs/qprintpreviewdialog.cpp10
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp146
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h14
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp83
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h3
-rw-r--r--src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp10
-rw-r--r--src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h2
-rw-r--r--src/gui/graphicsview/qgraphicssceneindex.cpp2
-rw-r--r--src/gui/graphicsview/qgraphicssceneindex_p.h2
-rw-r--r--src/gui/kernel/qapplication_mac.mm42
-rw-r--r--src/gui/painting/qcolor.cpp11
-rw-r--r--src/gui/painting/qpainter.cpp38
-rw-r--r--src/gui/widgets/qlinecontrol.cpp5
-rw-r--r--src/gui/widgets/qlinecontrol_p.h5
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager.cpp10
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager_p.h5
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadersource_p.h678
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp25
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h2
-rw-r--r--src/opengl/qpixmapdata_gl.cpp14
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp31
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h1
24 files changed, 666 insertions, 481 deletions
diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp
index 2b4ab47..cedb43f 100644
--- a/src/corelib/animation/qabstractanimation.cpp
+++ b/src/corelib/animation/qabstractanimation.cpp
@@ -299,8 +299,6 @@ void QUnifiedTimer::registerRunningAnimation(QAbstractAnimation *animation)
return;
if (QAbstractAnimationPrivate::get(animation)->isPause) {
- if (animation->duration() == -1)
- qDebug() << "toto";
runningPauseAnimations << animation;
} else
runningLeafAnimations++;
diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp
index 0ef92d9..b6a2df4 100644
--- a/src/corelib/tools/qeasingcurve.cpp
+++ b/src/corelib/tools/qeasingcurve.cpp
@@ -125,7 +125,7 @@
\value OutCubic \inlineimage qeasingcurve-outcubic.png
\br
Easing curve for a cubic (t^3) function:
- decelerating from zero velocity.
+ decelerating to zero velocity.
\value InOutCubic \inlineimage qeasingcurve-inoutcubic.png
\br
Easing curve for a cubic (t^3) function:
@@ -141,7 +141,7 @@
\value OutQuart \inlineimage qeasingcurve-outquart.png
\br
Easing curve for a cubic (t^4) function:
- decelerating from zero velocity.
+ decelerating to zero velocity.
\value InOutQuart \inlineimage qeasingcurve-inoutquart.png
\br
Easing curve for a cubic (t^4) function:
@@ -157,7 +157,7 @@
\value OutQuint \inlineimage qeasingcurve-outquint.png
\br
Easing curve for a cubic (t^5) function:
- decelerating from zero velocity.
+ decelerating to zero velocity.
\value InOutQuint \inlineimage qeasingcurve-inoutquint.png
\br
Easing curve for a cubic (t^5) function:
diff --git a/src/gui/dialogs/qprintpreviewdialog.cpp b/src/gui/dialogs/qprintpreviewdialog.cpp
index 42be780..6723b53 100644
--- a/src/gui/dialogs/qprintpreviewdialog.cpp
+++ b/src/gui/dialogs/qprintpreviewdialog.cpp
@@ -207,6 +207,9 @@ public:
QActionGroup *printerGroup;
QAction *printAction;
QAction *pageSetupAction;
+#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
+ QAction *closeAction;
+#endif
QPointer<QObject> receiverToDisconnectOnClose;
QByteArray memberToDisconnectOnClose;
@@ -287,6 +290,9 @@ void QPrintPreviewDialogPrivate::init(QPrinter *_printer)
toolbar->addSeparator();
toolbar->addAction(pageSetupAction);
toolbar->addAction(printAction);
+#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
+ toolbar->addAction(closeAction);
+#endif
// Cannot use the actions' triggered signal here, since it doesn't autorepeat
QToolButton *zoomInButton = static_cast<QToolButton *>(toolbar->widgetForAction(zoomInAction));
@@ -406,6 +412,10 @@ void QPrintPreviewDialogPrivate::setupActions()
qt_setupActionIcon(pageSetupAction, QLatin1String("page-setup"));
QObject::connect(printAction, SIGNAL(triggered(bool)), q, SLOT(_q_print()));
QObject::connect(pageSetupAction, SIGNAL(triggered(bool)), q, SLOT(_q_pageSetup()));
+#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
+ closeAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Close"));
+ QObject::connect(closeAction, SIGNAL(triggered(bool)), q, SLOT(reject()));
+#endif
// Initial state:
fitPageAction->setChecked(true);
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 1361a89..d43176b 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -798,8 +798,36 @@ void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag ch
return;
}
- foreach (QGraphicsItem *child, children)
- child->d_ptr->updateAncestorFlag(childFlag, flag, enabled, false);
+ for (int i = 0; i < children.size(); ++i)
+ children.at(i)->d_ptr->updateAncestorFlag(childFlag, flag, enabled, false);
+}
+
+void QGraphicsItemPrivate::updateAncestorFlags()
+{
+ int flags = 0;
+ if (parent) {
+ // Inherit the parent's ancestor flags.
+ QGraphicsItemPrivate *pd = parent->d_ptr.data();
+ flags = pd->ancestorFlags;
+
+ // Add in flags from the parent.
+ if (pd->filtersDescendantEvents)
+ flags |= AncestorFiltersChildEvents;
+ if (pd->handlesChildEvents)
+ flags |= AncestorHandlesChildEvents;
+ if (pd->flags & QGraphicsItem::ItemClipsChildrenToShape)
+ flags |= AncestorClipsChildren;
+ if (pd->flags & QGraphicsItem::ItemIgnoresTransformations)
+ flags |= AncestorIgnoresTransformations;
+ }
+
+ if (ancestorFlags == flags)
+ return; // No change; stop propagation.
+ ancestorFlags = flags;
+
+ // Propagate to children recursively.
+ for (int i = 0; i < children.size(); ++i)
+ children.at(i)->d_ptr->updateAncestorFlags();
}
/*!
@@ -984,25 +1012,17 @@ QVariant QGraphicsItemPrivate::inputMethodQueryHelper(Qt::InputMethodQuery query
prepareGeometryChange) if the item is in its destructor, i.e.
inDestructor is 1.
*/
-void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
+void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const QVariant *newParentVariant,
+ const QVariant *thisPointerVariant)
{
Q_Q(QGraphicsItem);
- if (newParent == q) {
- qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this);
- return;
- }
- if (newParent == parent)
- return;
-
- const QVariant newParentVariant(q->itemChange(QGraphicsItem::ItemParentChange,
- qVariantFromValue<QGraphicsItem *>(newParent)));
- newParent = qVariantValue<QGraphicsItem *>(newParentVariant);
if (newParent == parent)
return;
if (scene) {
// Deliver the change to the index
- scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParentVariant);
+ if (scene->d_func()->indexMethod != QGraphicsScene::NoIndex)
+ scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParent);
// Disable scene pos notifications for old ancestors
if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges))
@@ -1020,11 +1040,11 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
if (!inDestructor)
q_ptr->prepareGeometryChange();
- const QVariant thisPointerVariant(qVariantFromValue<QGraphicsItem *>(q));
if (parent) {
// Remove from current parent
parent->d_ptr->removeChild(q);
- parent->itemChange(QGraphicsItem::ItemChildRemovedChange, thisPointerVariant);
+ if (thisPointerVariant)
+ parent->itemChange(QGraphicsItem::ItemChildRemovedChange, *thisPointerVariant);
}
// Update toplevelitem list. If this item is being deleted, its parent
@@ -1042,7 +1062,7 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
QGraphicsItem *p = parent;
QGraphicsItem *parentFocusScopeItem = 0;
while (p) {
- if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
+ if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) {
// If this item's focus scope's focus scope item points
// to this item or a descendent, then clear it.
QGraphicsItem *fsi = p->d_ptr->focusScopeItem;
@@ -1063,11 +1083,11 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
QGraphicsItem *ancestorScope = 0;
QGraphicsItem *p = subFocusItem->d_ptr->parent;
while (p) {
- if (p->flags() & QGraphicsItem::ItemIsFocusScope)
+ if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope)
ancestorScope = p;
- if (p->isPanel())
+ if (p->d_ptr->flags & QGraphicsItem::ItemIsPanel)
break;
- p = p->parentItem();
+ p = p->d_ptr->parent;
}
if (ancestorScope)
newFocusScopeItem = ancestorScope;
@@ -1075,7 +1095,7 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
QGraphicsItem *p = newParent;
while (p) {
- if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
+ if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) {
p->d_ptr->focusScopeItem = newFocusScopeItem;
// Ensure the new item is no longer the subFocusItem. The
// only way to set focus on a child of a focus scope is
@@ -1100,7 +1120,8 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
}
parent->d_ptr->addChild(q);
- parent->itemChange(QGraphicsItem::ItemChildAddedChange, thisPointerVariant);
+ if (thisPointerVariant)
+ parent->itemChange(QGraphicsItem::ItemChildAddedChange, *thisPointerVariant);
if (scene) {
if (!implicitUpdate)
scene->d_func()->markDirty(q_ptr);
@@ -1111,30 +1132,24 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
}
// Inherit ancestor flags from the new parent.
- updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2));
- updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1));
- updateAncestorFlag(QGraphicsItem::ItemClipsChildrenToShape);
- updateAncestorFlag(QGraphicsItem::ItemIgnoresTransformations);
+ updateAncestorFlags();
// Update item visible / enabled.
- if (parent->isVisible() != visible) {
- if (!parent->isVisible() || !explicitlyHidden)
- setVisibleHelper(parent->isVisible(), /* explicit = */ false, /* update = */ !implicitUpdate);
+ if (parent->d_ptr->visible != visible) {
+ if (!parent->d_ptr->visible || !explicitlyHidden)
+ setVisibleHelper(parent->d_ptr->visible, /* explicit = */ false, /* update = */ !implicitUpdate);
}
if (parent->isEnabled() != enabled) {
- if (!parent->isEnabled() || !explicitlyDisabled)
- setEnabledHelper(parent->isEnabled(), /* explicit = */ false, /* update = */ !implicitUpdate);
+ if (!parent->d_ptr->enabled || !explicitlyDisabled)
+ setEnabledHelper(parent->d_ptr->enabled, /* explicit = */ false, /* update = */ !implicitUpdate);
}
// Auto-activate if visible and the parent is active.
- if (q->isVisible() && parent->isActive())
+ if (visible && parent->isActive())
q->setActive(true);
} else {
// Inherit ancestor flags from the new parent.
- updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2));
- updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1));
- updateAncestorFlag(QGraphicsItem::ItemClipsChildrenToShape);
- updateAncestorFlag(QGraphicsItem::ItemIgnoresTransformations);
+ updateAncestorFlags();
if (!inDestructor) {
// Update item visible / enabled.
@@ -1161,7 +1176,8 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
}
// Deliver post-change notification
- q->itemChange(QGraphicsItem::ItemParentHasChanged, newParentVariant);
+ if (newParentVariant)
+ q->itemChange(QGraphicsItem::ItemParentHasChanged, *newParentVariant);
if (isObject)
emit static_cast<QGraphicsObject *>(q)->parentChanged();
@@ -1350,7 +1366,7 @@ QGraphicsItem::~QGraphicsItem()
d_ptr->scene->d_func()->removeItemHelper(this);
} else {
d_ptr->resetFocusProxy();
- d_ptr->setParentItemHelper(0);
+ setParentItem(0);
}
#ifndef QT_NO_GRAPHICSEFFECT
@@ -1555,9 +1571,23 @@ const QGraphicsObject *QGraphicsItem::toGraphicsObject() const
\sa parentItem(), childItems()
*/
-void QGraphicsItem::setParentItem(QGraphicsItem *parent)
+void QGraphicsItem::setParentItem(QGraphicsItem *newParent)
{
- d_ptr->setParentItemHelper(parent);
+ if (newParent == this) {
+ qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this);
+ return;
+ }
+ if (newParent == d_ptr->parent)
+ return;
+
+ const QVariant newParentVariant(itemChange(QGraphicsItem::ItemParentChange,
+ qVariantFromValue<QGraphicsItem *>(newParent)));
+ newParent = qVariantValue<QGraphicsItem *>(newParentVariant);
+ if (newParent == d_ptr->parent)
+ return;
+
+ const QVariant thisPointerVariant(qVariantFromValue<QGraphicsItem *>(this));
+ d_ptr->setParentItemHelper(newParent, &newParentVariant, &thisPointerVariant);
}
/*!
@@ -1607,7 +1637,7 @@ bool QGraphicsItem::isWidget() const
*/
bool QGraphicsItem::isWindow() const
{
- return isWidget() && (static_cast<const QGraphicsWidget *>(this)->windowType() & Qt::Window);
+ return d_ptr->isWidget && (static_cast<const QGraphicsWidget *>(this)->windowType() & Qt::Window);
}
/*!
@@ -1644,9 +1674,9 @@ QGraphicsItem::GraphicsItemFlags QGraphicsItem::flags() const
void QGraphicsItem::setFlag(GraphicsItemFlag flag, bool enabled)
{
if (enabled)
- setFlags(flags() | flag);
+ setFlags(GraphicsItemFlags(d_ptr->flags) | flag);
else
- setFlags(flags() & ~flag);
+ setFlags(GraphicsItemFlags(d_ptr->flags) & ~flag);
}
/*!
@@ -1693,8 +1723,8 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
flags = GraphicsItemFlags(itemChange(ItemFlagsChange, quint32(flags)).toUInt());
if (quint32(d_ptr->flags) == quint32(flags))
return;
- if (d_ptr->scene)
- d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, quint32(flags));
+ if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex)
+ d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, &flags);
// Flags that alter the geometry of the item (or its children).
const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations | ItemIsSelectable);
@@ -1703,7 +1733,7 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
// Keep the old flags to compare the diff.
- GraphicsItemFlags oldFlags = this->flags();
+ GraphicsItemFlags oldFlags = GraphicsItemFlags(d_ptr->flags);
// Update flags.
d_ptr->flags = flags;
@@ -1732,7 +1762,23 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
d_ptr->updateAncestorFlag(ItemIgnoresTransformations);
}
+ if ((flags & ItemNegativeZStacksBehindParent) != (oldFlags & ItemNegativeZStacksBehindParent)) {
+ // NB! We change the flags directly here, so we must also update d_ptr->flags.
+ // Note that this has do be done before the ItemStacksBehindParent check
+ // below; otherwise we will loose the change.
+
+ // Update stack-behind.
+ if (d_ptr->z < qreal(0.0))
+ flags |= ItemStacksBehindParent;
+ else
+ flags &= ~ItemStacksBehindParent;
+ d_ptr->flags = flags;
+ }
+
if ((flags & ItemStacksBehindParent) != (oldFlags & ItemStacksBehindParent)) {
+ // NB! This check has to come after the ItemNegativeZStacksBehindParent
+ // check above. Be careful.
+
// Ensure child item sorting is up to date when toggling this flag.
if (d_ptr->parent)
d_ptr->parent->d_ptr->needSortChildren = 1;
@@ -1746,10 +1792,6 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
d_ptr->scene->d_func()->updateInputMethodSensitivityInViews();
}
- if ((flags & ItemNegativeZStacksBehindParent) != (oldFlags & ItemNegativeZStacksBehindParent)) {
- // Update stack-behind.
- setFlag(ItemStacksBehindParent, d_ptr->z < qreal(0.0));
- }
if ((d_ptr->panelModality != NonModal)
&& d_ptr->scene
@@ -4264,9 +4306,9 @@ void QGraphicsItem::setZValue(qreal z)
if (newZ == d_ptr->z)
return;
- if (d_ptr->scene) {
+ if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex) {
// Z Value has changed, we have to notify the index.
- d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, newZVariant);
+ d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, &newZ);
}
d_ptr->z = newZ;
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index 2d34b80..bdd8863 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -153,7 +153,7 @@ public:
dirtyChildren(0),
localCollisionHack(0),
inSetPosHelper(0),
- needSortChildren(1), // ### can be 0 by default?
+ needSortChildren(0),
allChildrenDirty(0),
fullUpdatePending(0),
flags(0),
@@ -178,6 +178,7 @@ public:
sequentialOrdering(1),
updateDueToGraphicsEffect(0),
scenePosDescendants(0),
+ pendingPolish(0),
globalStackingOrder(-1),
q_ptr(0)
{
@@ -197,6 +198,7 @@ public:
void updateAncestorFlag(QGraphicsItem::GraphicsItemFlag childFlag,
AncestorFlag flag = NoFlag, bool enabled = false, bool root = true);
+ void updateAncestorFlags();
void setIsMemberOfGroup(bool enabled);
void remapItemPos(QEvent *event, QGraphicsItem *item);
QPointF genericMapFromScene(const QPointF &pos, const QWidget *viewport) const;
@@ -229,7 +231,8 @@ public:
void resolveDepth();
void addChild(QGraphicsItem *child);
void removeChild(QGraphicsItem *child);
- void setParentItemHelper(QGraphicsItem *parent);
+ void setParentItemHelper(QGraphicsItem *parent, const QVariant *newParentVariant,
+ const QVariant *thisPointerVariant);
void childrenBoundingRectHelper(QTransform *x, QRectF *rect);
void initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform,
const QRegion &exposedRegion, bool allItems = false) const;
@@ -484,6 +487,7 @@ public:
quint32 sequentialOrdering : 1;
quint32 updateDueToGraphicsEffect : 1;
quint32 scenePosDescendants : 1;
+ quint32 pendingPolish : 1;
// Optional stacking order
int globalStackingOrder;
@@ -721,11 +725,13 @@ inline QTransform QGraphicsItemPrivate::transformToParent() const
inline void QGraphicsItemPrivate::ensureSortedChildren()
{
if (needSortChildren) {
- qSort(children.begin(), children.end(), qt_notclosestLeaf);
needSortChildren = 0;
sequentialOrdering = 1;
+ if (children.isEmpty())
+ return;
+ qSort(children.begin(), children.end(), qt_notclosestLeaf);
for (int i = 0; i < children.size(); ++i) {
- if (children[i]->d_ptr->siblingIndex != i) {
+ if (children.at(i)->d_ptr->siblingIndex != i) {
sequentialOrdering = 0;
break;
}
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index cea723c..ae48bee 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -292,7 +292,6 @@ QGraphicsScenePrivate::QGraphicsScenePrivate()
processDirtyItemsEmitted(false),
selectionChanging(0),
needSortTopLevelItems(true),
- unpolishedItemsModified(true),
holesInTopLevelSiblingIndex(false),
topLevelSequentialOrdering(true),
scenePosDescendantsUpdatePending(false),
@@ -429,22 +428,38 @@ void QGraphicsScenePrivate::unregisterTopLevelItem(QGraphicsItem *item)
*/
void QGraphicsScenePrivate::_q_polishItems()
{
- QSet<QGraphicsItem *>::Iterator it = unpolishedItems.begin();
+ if (unpolishedItems.isEmpty())
+ return;
+
const QVariant booleanTrueVariant(true);
- while (!unpolishedItems.isEmpty()) {
- QGraphicsItem *item = *it;
- it = unpolishedItems.erase(it);
- unpolishedItemsModified = false;
- if (!item->d_ptr->explicitlyHidden) {
+ QGraphicsItem *item = 0;
+ QGraphicsItemPrivate *itemd = 0;
+ const int oldUnpolishedCount = unpolishedItems.count();
+
+ for (int i = 0; i < oldUnpolishedCount; ++i) {
+ item = unpolishedItems.at(i);
+ if (!item)
+ continue;
+ itemd = item->d_ptr.data();
+ itemd->pendingPolish = false;
+ if (!itemd->explicitlyHidden) {
item->itemChange(QGraphicsItem::ItemVisibleChange, booleanTrueVariant);
item->itemChange(QGraphicsItem::ItemVisibleHasChanged, booleanTrueVariant);
}
- if (item->isWidget()) {
+ if (itemd->isWidget) {
QEvent event(QEvent::Polish);
QApplication::sendEvent((QGraphicsWidget *)item, &event);
}
- if (unpolishedItemsModified)
- it = unpolishedItems.begin();
+ }
+
+ if (unpolishedItems.count() == oldUnpolishedCount) {
+ // No new items were added to the vector.
+ unpolishedItems.clear();
+ } else {
+ // New items were appended; keep them and remove the old ones.
+ unpolishedItems.remove(0, oldUnpolishedCount);
+ unpolishedItems.squeeze();
+ QMetaObject::invokeMethod(q_ptr, "_q_polishItems", Qt::QueuedConnection);
}
}
@@ -599,7 +614,7 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
if (parentItem->scene()) {
Q_ASSERT_X(parentItem->scene() == q, "QGraphicsScene::removeItem",
"Parent item's scene is different from this item's scene");
- item->d_ptr->setParentItemHelper(0);
+ item->setParentItem(0);
}
} else {
unregisterTopLevelItem(item);
@@ -638,8 +653,12 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
selectedItems.remove(item);
hoverItems.removeAll(item);
cachedItemsUnderMouse.removeAll(item);
- unpolishedItems.remove(item);
- unpolishedItemsModified = true;
+ if (item->d_ptr->pendingPolish) {
+ const int unpolishedIndex = unpolishedItems.indexOf(item);
+ if (unpolishedIndex != -1)
+ unpolishedItems[unpolishedIndex] = 0;
+ item->d_ptr->pendingPolish = false;
+ }
resetDirtyItem(item);
//We remove all references of item from the sceneEventFilter arrays
@@ -2482,12 +2501,12 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
qWarning("QGraphicsScene::addItem: cannot add null item");
return;
}
- if (item->scene() == this) {
+ if (item->d_ptr->scene == this) {
qWarning("QGraphicsScene::addItem: item has already been added to this scene");
return;
}
// Remove this item from its existing scene
- if (QGraphicsScene *oldScene = item->scene())
+ if (QGraphicsScene *oldScene = item->d_ptr->scene)
oldScene->removeItem(item);
// Notify the item that its scene is changing, and allow the item to
@@ -2496,15 +2515,20 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
qVariantFromValue<QGraphicsScene *>(this)));
QGraphicsScene *targetScene = qVariantValue<QGraphicsScene *>(newSceneVariant);
if (targetScene != this) {
- if (targetScene && item->scene() != targetScene)
+ if (targetScene && item->d_ptr->scene != targetScene)
targetScene->addItem(item);
return;
}
+ if (d->unpolishedItems.isEmpty())
+ QMetaObject::invokeMethod(this, "_q_polishItems", Qt::QueuedConnection);
+ d->unpolishedItems.append(item);
+ item->d_ptr->pendingPolish = true;
+
// Detach this item from its parent if the parent's scene is different
// from this scene.
- if (QGraphicsItem *itemParent = item->parentItem()) {
- if (itemParent->scene() != this)
+ if (QGraphicsItem *itemParent = item->d_ptr->parent) {
+ if (itemParent->d_ptr->scene != this)
item->setParentItem(0);
}
@@ -2534,7 +2558,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
d->enableMouseTrackingOnViews();
}
#ifndef QT_NO_CURSOR
- if (d->allItemsUseDefaultCursor && item->hasCursor()) {
+ if (d->allItemsUseDefaultCursor && item->d_ptr->hasCursor) {
d->allItemsUseDefaultCursor = false;
if (d->allItemsIgnoreHoverEvents) // already enabled otherwise
d->enableMouseTrackingOnViews();
@@ -2542,7 +2566,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
#endif //QT_NO_CURSOR
// Enable touch events if the item accepts touch events.
- if (d->allItemsIgnoreTouchEvents && item->acceptTouchEvents()) {
+ if (d->allItemsIgnoreTouchEvents && item->d_ptr->acceptTouchEvents) {
d->allItemsIgnoreTouchEvents = false;
d->enableTouchEventsOnViews();
}
@@ -2575,17 +2599,14 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
}
// Add all children recursively
- foreach (QGraphicsItem *child, item->children())
- addItem(child);
+ item->d_ptr->ensureSortedChildren();
+ for (int i = 0; i < item->d_ptr->children.size(); ++i)
+ addItem(item->d_ptr->children.at(i));
// Resolve font and palette.
item->d_ptr->resolveFont(d->font.resolve());
item->d_ptr->resolvePalette(d->palette.resolve());
- if (d->unpolishedItems.isEmpty())
- QMetaObject::invokeMethod(this, "_q_polishItems", Qt::QueuedConnection);
- d->unpolishedItems.insert(item);
- d->unpolishedItemsModified = true;
// Reenable selectionChanged() for individual items
--d->selectionChanging;
@@ -2619,7 +2640,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
}
}
- if (item->flags() & QGraphicsItem::ItemSendsScenePositionChanges)
+ if (item->d_ptr->flags & QGraphicsItem::ItemSendsScenePositionChanges)
d->registerScenePosItem(item);
// Ensure that newly added items that have subfocus set, gain
@@ -3766,10 +3787,10 @@ void QGraphicsScene::helpEvent(QGraphicsSceneHelpEvent *helpEvent)
bool QGraphicsScenePrivate::itemAcceptsHoverEvents_helper(const QGraphicsItem *item) const
{
- return (!item->isBlockedByModalPanel() &&
- (item->acceptHoverEvents()
- || (item->isWidget()
- && static_cast<const QGraphicsWidget *>(item)->d_func()->hasDecoration())));
+ return (item->d_ptr->acceptsHover
+ || (item->d_ptr->isWidget
+ && static_cast<const QGraphicsWidget *>(item)->d_func()->hasDecoration()))
+ && !item->isBlockedByModalPanel();
}
/*!
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
index d10811c..54d8130 100644
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_p.h
@@ -108,10 +108,9 @@ public:
QPainterPath selectionArea;
int selectionChanging;
QSet<QGraphicsItem *> selectedItems;
- QSet<QGraphicsItem *> unpolishedItems;
+ QVector<QGraphicsItem *> unpolishedItems;
QList<QGraphicsItem *> topLevelItems;
bool needSortTopLevelItems;
- bool unpolishedItemsModified;
bool holesInTopLevelSiblingIndex;
bool topLevelSequentialOrdering;
diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp
index 2e92b87..2a91348 100644
--- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp
+++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp
@@ -635,16 +635,17 @@ void QGraphicsSceneBspTreeIndex::updateSceneRect(const QRectF &rect)
This method react to the \a change of the \a item and use the \a value to
update the BSP tree if necessary.
*/
-void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value)
+void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const void *const value)
{
Q_D(QGraphicsSceneBspTreeIndex);
switch (change) {
case QGraphicsItem::ItemFlagsChange: {
// Handle ItemIgnoresTransformations
+ QGraphicsItem::GraphicsItemFlags newFlags = *static_cast<const QGraphicsItem::GraphicsItemFlags *>(value);
bool ignoredTransform = item->d_ptr->flags & QGraphicsItem::ItemIgnoresTransformations;
- bool willIgnoreTransform = value.toUInt() & QGraphicsItem::ItemIgnoresTransformations;
+ bool willIgnoreTransform = newFlags & QGraphicsItem::ItemIgnoresTransformations;
bool clipsChildren = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape;
- bool willClipChildren = value.toUInt() & QGraphicsItem::ItemClipsChildrenToShape;
+ bool willClipChildren = newFlags & QGraphicsItem::ItemClipsChildrenToShape;
if ((ignoredTransform != willIgnoreTransform) || (clipsChildren != willClipChildren)) {
QGraphicsItem *thatItem = const_cast<QGraphicsItem *>(item);
// Remove item and its descendants from the index and append
@@ -661,7 +662,7 @@ void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphics
case QGraphicsItem::ItemParentChange: {
d->invalidateSortCache();
// Handle ItemIgnoresTransformations
- QGraphicsItem *newParent = qVariantValue<QGraphicsItem *>(value);
+ const QGraphicsItem *newParent = static_cast<const QGraphicsItem *>(value);
bool ignoredTransform = item->d_ptr->itemIsUntransformable();
bool willIgnoreTransform = (item->d_ptr->flags & QGraphicsItem::ItemIgnoresTransformations)
|| (newParent && newParent->d_ptr->itemIsUntransformable());
@@ -682,7 +683,6 @@ void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphics
default:
break;
}
- return QGraphicsSceneIndex::itemChange(item, change, value);
}
/*!
\reimp
diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h
index 119571b..f671fd9 100644
--- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h
+++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h
@@ -97,7 +97,7 @@ protected:
void removeItem(QGraphicsItem *item);
void prepareBoundingRectChange(const QGraphicsItem *item);
- void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value);
+ void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const void *const value);
private :
Q_DECLARE_PRIVATE(QGraphicsSceneBspTreeIndex)
diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp
index bc8a7dc..043c4eb 100644
--- a/src/gui/graphicsview/qgraphicssceneindex.cpp
+++ b/src/gui/graphicsview/qgraphicssceneindex.cpp
@@ -624,7 +624,7 @@ void QGraphicsSceneIndex::deleteItem(QGraphicsItem *item)
\sa QGraphicsItem::GraphicsItemChange
*/
-void QGraphicsSceneIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value)
+void QGraphicsSceneIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const void *const value)
{
Q_UNUSED(item);
Q_UNUSED(change);
diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h
index def58f0..597a229 100644
--- a/src/gui/graphicsview/qgraphicssceneindex_p.h
+++ b/src/gui/graphicsview/qgraphicssceneindex_p.h
@@ -110,7 +110,7 @@ protected:
virtual void removeItem(QGraphicsItem *item) = 0;
virtual void deleteItem(QGraphicsItem *item);
- virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value);
+ virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const void *const value);
virtual void prepareBoundingRectChange(const QGraphicsItem *item);
QGraphicsSceneIndex(QGraphicsSceneIndexPrivate &dd, QGraphicsScene *scene);
diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm
index 6aebef5..e8b821af 100644
--- a/src/gui/kernel/qapplication_mac.mm
+++ b/src/gui/kernel/qapplication_mac.mm
@@ -227,8 +227,29 @@ void onApplicationChangedActivation( bool activated );
static void qt_mac_read_fontsmoothing_settings()
{
- NSInteger appleFontSmoothing = [[NSUserDefaults standardUserDefaults] integerForKey:@"AppleFontSmoothing"];
- qt_applefontsmoothing_enabled = (appleFontSmoothing > 0);
+ qt_applefontsmoothing_enabled = true;
+ int w = 10, h = 10;
+ QImage image(w, h, QImage::Format_RGB32);
+ image.fill(0xffffffff);
+ QPainter p(&image);
+ p.drawText(0, h, "X\\");
+ p.end();
+
+ const int *bits = (const int *) ((const QImage &) image).bits();
+ int bpl = image.bytesPerLine() / 4;
+ for (int y=0; y<w; ++y) {
+ for (int x=0; x<h; ++x) {
+ int r = qRed(bits[x]);
+ int g = qGreen(bits[x]);
+ int b = qBlue(bits[x]);
+ if (r != g || r != b) {
+ qt_applefontsmoothing_enabled = true;
+ return;
+ }
+ }
+ bits += bpl;
+ }
+ qt_applefontsmoothing_enabled = false;
}
Q_GUI_EXPORT bool qt_mac_execute_apple_script(const char *script, long script_len, AEDesc *ret) {
@@ -772,11 +793,11 @@ static void qt_mac_update_intersected_gl_widgets(QWidget *widget)
qt_post_window_change_event(glWidget);
it->lastUpdateWidget = widget;
} else if (it->lastUpdateWidget == widget) {
- // Update the gl wigets that the widget intersected the last time around,
- // and that we are not intersecting now. This prevents paint errors when the
+ // Update the gl wigets that the widget intersected the last time around,
+ // and that we are not intersecting now. This prevents paint errors when the
// intersecting widget leaves a gl widget.
qt_post_window_change_event(glWidget);
- it->lastUpdateWidget = 0;
+ it->lastUpdateWidget = 0;
}
}
#else
@@ -808,8 +829,8 @@ Q_GUI_EXPORT void qt_event_request_window_change(QWidget *widget)
// Post a kEventQtRequestWindowChange event. This event is semi-public,
// don't remove this line!
qt_event_request_window_change();
-
- // Post update request on gl widgets unconditionally.
+
+ // Post update request on gl widgets unconditionally.
if (qt_widget_private(widget)->isGLWidget == true) {
qt_post_window_change_event(widget);
return;
@@ -1214,8 +1235,6 @@ void qt_init(QApplicationPrivate *priv, int)
if (QApplication::desktopSettingsAware())
QApplicationPrivate::qt_mac_apply_settings();
- qt_mac_read_fontsmoothing_settings();
-
// Cocoa application delegate
#ifdef QT_MAC_USE_COCOA
NSApplication *cocoaApp = [NSApplication sharedApplication];
@@ -1253,6 +1272,7 @@ void qt_init(QApplicationPrivate *priv, int)
}
priv->native_modal_dialog_active = false;
+ qt_mac_read_fontsmoothing_settings();
}
void qt_release_apple_event_handler()
@@ -1705,7 +1725,7 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event
// kEventMouseWheelMoved events if we dont eat this event
// (actually two events; one for horizontal and one for vertical).
// As a results of this, and to make sure we dont't receive duplicate events,
- // we try to detect when this happend by checking the 'compatibilityEvent'.
+ // we try to detect when this happend by checking the 'compatibilityEvent'.
SInt32 mdelt = 0;
GetEventParameter(event, kEventParamMouseWheelSmoothHorizontalDelta, typeSInt32, 0,
sizeof(mdelt), 0, &mdelt);
@@ -2576,7 +2596,7 @@ void QApplicationPrivate::closePopup(QWidget *popup)
if (QApplicationPrivate::popupWidgets->isEmpty()) { // this was the last popup
delete QApplicationPrivate::popupWidgets;
QApplicationPrivate::popupWidgets = 0;
-
+
// Special case for Tool windows: since they are activated and deactived together
// with a normal window they never become the QApplicationPrivate::active_window.
QWidget *appFocusWidget = QApplication::focusWidget();
diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index f51dc36..d6d288e 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -934,8 +934,7 @@ void QColor::setRgb(int r, int g, int b, int a)
/*!
\fn QRgb QColor::rgba() const
- Returns the RGB value of the color. Unlike rgb(), the alpha is not
- stripped.
+ Returns the RGB value of the color, including its alpha.
For an invalid color, the alpha value of the returned color is unspecified.
@@ -950,8 +949,7 @@ QRgb QColor::rgba() const
}
/*!
- Sets the RGBA value to \a rgba. Unlike setRgb(QRgb rgb), this function does
- not ignore the alpha.
+ Sets the RGB value to \a rgba, including its alpha.
\sa rgba(), rgb()
*/
@@ -968,8 +966,7 @@ void QColor::setRgba(QRgb rgba)
/*!
\fn QRgb QColor::rgb() const
- Returns the RGB value of the color. The alpha is stripped for
- compatibility.
+ Returns the RGB value of the color. The alpha value is opaque.
\sa getRgb(), rgba()
*/
@@ -983,7 +980,7 @@ QRgb QColor::rgb() const
/*!
\overload
- Sets the RGB value to \a rgb, ignoring the alpha.
+ Sets the RGB value to \a rgb. The alpha value is set to opaque.
*/
void QColor::setRgb(QRgb rgb)
{
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 31132d9..cde6a2d 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -7382,10 +7382,15 @@ struct QPaintDeviceRedirection
typedef QList<QPaintDeviceRedirection> QPaintDeviceRedirectionList;
Q_GLOBAL_STATIC(QPaintDeviceRedirectionList, globalRedirections)
Q_GLOBAL_STATIC(QMutex, globalRedirectionsMutex)
+Q_GLOBAL_STATIC(QAtomicInt, globalRedirectionAtomic)
/*!
\threadsafe
+ \obsolete
+
+ Please use QWidget::render() instead.
+
Redirects all paint commands for the given paint \a device, to the
\a replacement device. The optional point \a offset defines an
offset within the source device.
@@ -7395,9 +7400,10 @@ Q_GLOBAL_STATIC(QMutex, globalRedirectionsMutex)
device's painter (if any) before redirecting. Call
restoreRedirected() to restore the previous redirection.
- In general, you'll probably find that calling
- QPixmap::grabWidget() or QPixmap::grabWindow() is an easier
- solution.
+ \warning Making use of redirections in the QPainter API implies
+ that QPainter::begin() and QPaintDevice destructors need to hold
+ a mutex for a short period. This can impact performance. Use of
+ QWidget::render is strongly encouraged.
\sa redirected(), restoreRedirected()
*/
@@ -7429,14 +7435,24 @@ void QPainter::setRedirected(const QPaintDevice *device,
Q_ASSERT(redirections != 0);
*redirections += QPaintDeviceRedirection(device, rdev ? rdev : replacement, offset + roffset,
hadInternalWidgetRedirection ? redirections->size() - 1 : -1);
+ globalRedirectionAtomic()->ref();
}
/*!
\threadsafe
+ \obsolete
+
+ Using QWidget::render() obsoletes the use of this function.
+
Restores the previous redirection for the given \a device after a
call to setRedirected().
+ \warning Making use of redirections in the QPainter API implies
+ that QPainter::begin() and QPaintDevice destructors need to hold
+ a mutex for a short period. This can impact performance. Use of
+ QWidget::render is strongly encouraged.
+
\sa redirected()
*/
void QPainter::restoreRedirected(const QPaintDevice *device)
@@ -7447,6 +7463,7 @@ void QPainter::restoreRedirected(const QPaintDevice *device)
Q_ASSERT(redirections != 0);
for (int i = redirections->size()-1; i >= 0; --i) {
if (redirections->at(i) == device) {
+ globalRedirectionAtomic()->deref();
const int internalWidgetRedirectionIndex = redirections->at(i).internalWidgetRedirectionIndex;
redirections->removeAt(i);
// Restore the internal widget redirection, i.e. remove it from the global
@@ -7468,9 +7485,18 @@ void QPainter::restoreRedirected(const QPaintDevice *device)
/*!
\threadsafe
+ \obsolete
+
+ Using QWidget::render() obsoletes the use of this function.
+
Returns the replacement for given \a device. The optional out
parameter \a offset returns the offset within the replaced device.
+ \warning Making use of redirections in the QPainter API implies
+ that QPainter::begin() and QPaintDevice destructors need to hold
+ a mutex for a short period. This can impact performance. Use of
+ QWidget::render is strongly encouraged.
+
\sa setRedirected(), restoreRedirected()
*/
QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset)
@@ -7483,6 +7509,9 @@ QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset)
return widgetPrivate->redirected(offset);
}
+ if (*globalRedirectionAtomic() == 0)
+ return 0;
+
QMutexLocker locker(globalRedirectionsMutex());
QPaintDeviceRedirectionList *redirections = globalRedirections();
Q_ASSERT(redirections != 0);
@@ -7500,6 +7529,9 @@ QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset)
void qt_painter_removePaintDevice(QPaintDevice *dev)
{
+ if (*globalRedirectionAtomic() == 0)
+ return;
+
QMutex *mutex = 0;
QT_TRY {
mutex = globalRedirectionsMutex();
diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp
index 414c2ed..b0a64ea 100644
--- a/src/gui/widgets/qlinecontrol.cpp
+++ b/src/gui/widgets/qlinecontrol.cpp
@@ -524,8 +524,11 @@ void QLineControl::draw(QPainter *painter, const QPoint &offset, const QRect &cl
m_textLayout.draw(painter, offset, selections, clip);
if (flags & DrawCursor){
+ int cursor = m_cursor;
+ if (m_preeditCursor != -1)
+ cursor += m_preeditCursor;
if(!m_blinkPeriod || m_blinkStatus)
- m_textLayout.drawCursor(painter, offset, m_cursor, m_cursorWidth);
+ m_textLayout.drawCursor(painter, offset, cursor, m_cursorWidth);
}
}
diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h
index 301ff72..d6f2705 100644
--- a/src/gui/widgets/qlinecontrol_p.h
+++ b/src/gui/widgets/qlinecontrol_p.h
@@ -549,7 +549,10 @@ inline qreal QLineControl::cursorToX(int cursor) const
inline qreal QLineControl::cursorToX() const
{
- return cursorToX(m_cursor);
+ int cursor = m_cursor;
+ if (m_preeditCursor != -1)
+ cursor += m_preeditCursor;
+ return cursorToX(cursor);
}
inline bool QLineControl::isReadOnly() const
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
index 556b888..8183f08 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
@@ -184,6 +184,9 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context)
simpleShaderProg->addShader(vertexShader);
simpleShaderProg->addShader(fragShader);
simpleShaderProg->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR);
+ simpleShaderProg->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR);
+ simpleShaderProg->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR);
+ simpleShaderProg->bindAttributeLocation("pmvMatrix3", QT_PMV_MATRIX_3_ATTR);
simpleShaderProg->link();
if (!simpleShaderProg->isLinked()) {
qCritical() << "Errors linking simple shader:"
@@ -324,6 +327,11 @@ QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineS
newProg->program->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR);
if (newProg->useOpacityAttribute)
newProg->program->bindAttributeLocation("opacityArray", QT_OPACITY_ATTR);
+ if (newProg->usePmvMatrix) {
+ newProg->program->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR);
+ newProg->program->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR);
+ newProg->program->bindAttributeLocation("pmvMatrix3", QT_PMV_MATRIX_3_ATTR);
+ }
newProg->program->link();
if (!newProg->program->isLinked()) {
@@ -424,7 +432,6 @@ GLuint QGLEngineShaderManager::getUniformLocation(Uniform id)
"patternColor",
"globalOpacity",
"depth",
- "pmvMatrix",
"maskTexture",
"fragmentColor",
"linearData",
@@ -743,6 +750,7 @@ bool QGLEngineShaderManager::useCorrectShaderProg()
}
requiredProgram.useTextureCoords = texCoords;
requiredProgram.useOpacityAttribute = (opacityMode == AttributeOpacity);
+ requiredProgram.usePmvMatrix = true;
// At this point, requiredProgram is fully populated so try to find the program in the cache
currentShaderProg = sharedShaders->findProgramInCache(requiredProgram);
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
index c52e5c0..3ab4ebe 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
@@ -253,6 +253,9 @@ struct QGLEngineCachedShaderProg
static const GLuint QT_VERTEX_COORDS_ATTR = 0;
static const GLuint QT_TEXTURE_COORDS_ATTR = 1;
static const GLuint QT_OPACITY_ATTR = 2;
+static const GLuint QT_PMV_MATRIX_1_ATTR = 3;
+static const GLuint QT_PMV_MATRIX_2_ATTR = 4;
+static const GLuint QT_PMV_MATRIX_3_ATTR = 5;
class QGLEngineShaderProg;
@@ -397,6 +400,7 @@ public:
bool useTextureCoords;
bool useOpacityAttribute;
+ bool usePmvMatrix;
bool operator==(const QGLEngineShaderProg& other) {
// We don't care about the program
@@ -431,7 +435,6 @@ public:
PatternColor,
GlobalOpacity,
Depth,
- PmvMatrix,
MaskTexture,
FragmentColor,
LinearData,
diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h
index d9a61e9..ee04166 100644
--- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h
+++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h
@@ -63,210 +63,229 @@ QT_BEGIN_NAMESPACE
QT_MODULE(OpenGL)
-static const char* const qglslMainVertexShader = "\
- uniform highp float depth;\
- void setPosition();\
- void main(void)\
- {\
- setPosition();\
- gl_Position.z = depth * gl_Position.w;\
- }";
-
-static const char* const qglslMainWithTexCoordsVertexShader = "\
- attribute highp vec2 textureCoordArray; \
- varying highp vec2 textureCoords; \
- uniform highp float depth;\
- void setPosition();\
- void main(void) \
- {\
- setPosition();\
- gl_Position.z = depth * gl_Position.w;\
- textureCoords = textureCoordArray; \
- }";
-
-static const char* const qglslMainWithTexCoordsAndOpacityVertexShader = "\
- attribute highp vec2 textureCoordArray; \
- attribute lowp float opacityArray; \
- varying highp vec2 textureCoords; \
- varying lowp float opacity; \
- uniform highp float depth; \
- void setPosition(); \
- void main(void) \
- { \
- setPosition(); \
- gl_Position.z = depth * gl_Position.w; \
- textureCoords = textureCoordArray; \
- opacity = opacityArray; \
- }";
+static const char* const qglslMainVertexShader = "\n\
+ void setPosition(); \n\
+ void main(void) \n\
+ { \n\
+ setPosition(); \n\
+ }\n";
+
+static const char* const qglslMainWithTexCoordsVertexShader = "\n\
+ attribute highp vec2 textureCoordArray; \n\
+ varying highp vec2 textureCoords; \n\
+ void setPosition(); \n\
+ void main(void) \n\
+ { \n\
+ setPosition(); \n\
+ textureCoords = textureCoordArray; \n\
+ }\n";
+
+static const char* const qglslMainWithTexCoordsAndOpacityVertexShader = "\n\
+ attribute highp vec2 textureCoordArray; \n\
+ attribute lowp float opacityArray; \n\
+ varying highp vec2 textureCoords; \n\
+ varying lowp float opacity; \n\
+ void setPosition(); \n\
+ void main(void) \n\
+ { \n\
+ setPosition(); \n\
+ textureCoords = textureCoordArray; \n\
+ opacity = opacityArray; \n\
+ }\n";
// NOTE: We let GL do the perspective correction so texture lookups in the fragment
// shader are also perspective corrected.
-static const char* const qglslPositionOnlyVertexShader = "\
- attribute highp vec2 vertexCoordsArray;\
- uniform highp mat3 pmvMatrix;\
- void setPosition(void)\
- {\
- vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \
- gl_Position = vec4(transformedPos.xy, 0.0, transformedPos.z); \
- }";
-
-static const char* const qglslUntransformedPositionVertexShader = "\
- attribute highp vec4 vertexCoordsArray;\
- void setPosition(void)\
- {\
- gl_Position = vertexCoordsArray;\
- }";
+static const char* const qglslPositionOnlyVertexShader = "\n\
+ attribute highp vec2 vertexCoordsArray; \n\
+ attribute highp vec3 pmvMatrix1; \n\
+ attribute highp vec3 pmvMatrix2; \n\
+ attribute highp vec3 pmvMatrix3; \n\
+ void setPosition(void) \n\
+ { \n\
+ highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
+ vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
+ gl_Position = vec4(transformedPos.xy, 0.0, transformedPos.z); \n\
+ }\n";
+
+static const char* const qglslUntransformedPositionVertexShader = "\n\
+ attribute highp vec4 vertexCoordsArray; \n\
+ void setPosition(void) \n\
+ { \n\
+ gl_Position = vertexCoordsArray; \n\
+ }\n";
// Pattern Brush - This assumes the texture size is 8x8 and thus, the inverted size is 0.125
-static const char* const qglslPositionWithPatternBrushVertexShader = "\
- attribute highp vec2 vertexCoordsArray; \
- uniform highp mat3 pmvMatrix; \
- uniform mediump vec2 halfViewportSize; \
- uniform highp vec2 invertedTextureSize; \
- uniform highp mat3 brushTransform; \
- varying highp vec2 patternTexCoords; \
- void setPosition(void) { \
- vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \
- gl_Position.xy = transformedPos.xy / transformedPos.z; \
- mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \
- mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1.0); \
- mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \
- gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \
- patternTexCoords.xy = (hTexCoords.xy * 0.125) * invertedHTexCoordsZ; \
- }";
+static const char* const qglslPositionWithPatternBrushVertexShader = "\n\
+ attribute highp vec2 vertexCoordsArray; \n\
+ attribute highp vec3 pmvMatrix1; \n\
+ attribute highp vec3 pmvMatrix2; \n\
+ attribute highp vec3 pmvMatrix3; \n\
+ uniform mediump vec2 halfViewportSize; \n\
+ uniform highp vec2 invertedTextureSize; \n\
+ uniform highp mat3 brushTransform; \n\
+ varying highp vec2 patternTexCoords; \n\
+ void setPosition(void) \n\
+ { \n\
+ highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
+ vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
+ gl_Position.xy = transformedPos.xy / transformedPos.z; \n\
+ mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\
+ mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1.0); \n\
+ mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
+ gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
+ patternTexCoords.xy = (hTexCoords.xy * 0.125) * invertedHTexCoordsZ; \n\
+ }\n";
static const char* const qglslAffinePositionWithPatternBrushVertexShader
= qglslPositionWithPatternBrushVertexShader;
-static const char* const qglslPatternBrushSrcFragmentShader = "\
- uniform lowp sampler2D brushTexture;\
- uniform lowp vec4 patternColor; \
- varying highp vec2 patternTexCoords;\
- lowp vec4 srcPixel() { \
- return patternColor * (1.0 - texture2D(brushTexture, patternTexCoords).r); \
+static const char* const qglslPatternBrushSrcFragmentShader = "\n\
+ uniform lowp sampler2D brushTexture; \n\
+ uniform lowp vec4 patternColor; \n\
+ varying highp vec2 patternTexCoords;\n\
+ lowp vec4 srcPixel() \n\
+ { \n\
+ return patternColor * (1.0 - texture2D(brushTexture, patternTexCoords).r); \n\
}\n";
// Linear Gradient Brush
-static const char* const qglslPositionWithLinearGradientBrushVertexShader = "\
- attribute highp vec2 vertexCoordsArray; \
- uniform highp mat3 pmvMatrix; \
- uniform mediump vec2 halfViewportSize; \
- uniform highp vec3 linearData; \
- uniform highp mat3 brushTransform; \
- varying mediump float index; \
- void setPosition() { \
- vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \
- gl_Position.xy = transformedPos.xy / transformedPos.z; \
- mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \
- mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \
- mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \
- gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \
- index = (dot(linearData.xy, hTexCoords.xy) * linearData.z) * invertedHTexCoordsZ; \
- }";
+static const char* const qglslPositionWithLinearGradientBrushVertexShader = "\n\
+ attribute highp vec2 vertexCoordsArray; \n\
+ attribute highp vec3 pmvMatrix1; \n\
+ attribute highp vec3 pmvMatrix2; \n\
+ attribute highp vec3 pmvMatrix3; \n\
+ uniform mediump vec2 halfViewportSize; \n\
+ uniform highp vec3 linearData; \n\
+ uniform highp mat3 brushTransform; \n\
+ varying mediump float index; \n\
+ void setPosition() \n\
+ { \n\
+ highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
+ vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
+ gl_Position.xy = transformedPos.xy / transformedPos.z; \n\
+ mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\
+ mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\
+ mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
+ gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
+ index = (dot(linearData.xy, hTexCoords.xy) * linearData.z) * invertedHTexCoordsZ; \n\
+ }\n";
static const char* const qglslAffinePositionWithLinearGradientBrushVertexShader
= qglslPositionWithLinearGradientBrushVertexShader;
-static const char* const qglslLinearGradientBrushSrcFragmentShader = "\
- uniform lowp sampler2D brushTexture; \
- varying mediump float index; \
- lowp vec4 srcPixel() { \
- mediump vec2 val = vec2(index, 0.5); \
- return texture2D(brushTexture, val); \
+static const char* const qglslLinearGradientBrushSrcFragmentShader = "\n\
+ uniform lowp sampler2D brushTexture; \n\
+ varying mediump float index; \n\
+ lowp vec4 srcPixel() \n\
+ { \n\
+ mediump vec2 val = vec2(index, 0.5); \n\
+ return texture2D(brushTexture, val); \n\
}\n";
// Conical Gradient Brush
-static const char* const qglslPositionWithConicalGradientBrushVertexShader = "\
- attribute highp vec2 vertexCoordsArray;\
- uniform highp mat3 pmvMatrix;\
- uniform mediump vec2 halfViewportSize; \
- uniform highp mat3 brushTransform; \
- varying highp vec2 A; \
- void setPosition(void)\
- {\
- vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \
- gl_Position.xy = transformedPos.xy / transformedPos.z; \
- mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \
- mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \
- mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \
- gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \
- A = hTexCoords.xy * invertedHTexCoordsZ; \
- }";
+static const char* const qglslPositionWithConicalGradientBrushVertexShader = "\n\
+ attribute highp vec2 vertexCoordsArray; \n\
+ attribute highp vec3 pmvMatrix1; \n\
+ attribute highp vec3 pmvMatrix2; \n\
+ attribute highp vec3 pmvMatrix3; \n\
+ uniform mediump vec2 halfViewportSize; \n\
+ uniform highp mat3 brushTransform; \n\
+ varying highp vec2 A; \n\
+ void setPosition(void) \n\
+ { \n\
+ highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
+ vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
+ gl_Position.xy = transformedPos.xy / transformedPos.z; \n\
+ mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\
+ mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\
+ mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
+ gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
+ A = hTexCoords.xy * invertedHTexCoordsZ; \n\
+ }\n";
static const char* const qglslAffinePositionWithConicalGradientBrushVertexShader
= qglslPositionWithConicalGradientBrushVertexShader;
static const char* const qglslConicalGradientBrushSrcFragmentShader = "\n\
#define INVERSE_2PI 0.1591549430918953358 \n\
- uniform lowp sampler2D brushTexture; \n\
- uniform mediump float angle; \
- varying highp vec2 A; \
- lowp vec4 srcPixel() { \
- highp float t; \
- if (abs(A.y) == abs(A.x)) \
- t = (atan(-A.y + 0.002, A.x) + angle) * INVERSE_2PI; \
- else \
- t = (atan(-A.y, A.x) + angle) * INVERSE_2PI; \
- return texture2D(brushTexture, vec2(t - floor(t), 0.5)); \
- }";
+ uniform lowp sampler2D brushTexture; \n\
+ uniform mediump float angle; \n\
+ varying highp vec2 A; \n\
+ lowp vec4 srcPixel() \n\
+ { \n\
+ highp float t; \n\
+ if (abs(A.y) == abs(A.x)) \n\
+ t = (atan(-A.y + 0.002, A.x) + angle) * INVERSE_2PI; \n\
+ else \n\
+ t = (atan(-A.y, A.x) + angle) * INVERSE_2PI; \n\
+ return texture2D(brushTexture, vec2(t - floor(t), 0.5)); \n\
+ }\n";
// Radial Gradient Brush
-static const char* const qglslPositionWithRadialGradientBrushVertexShader = "\
- attribute highp vec2 vertexCoordsArray;\
- uniform highp mat3 pmvMatrix;\
- uniform mediump vec2 halfViewportSize; \
- uniform highp mat3 brushTransform; \
- uniform highp vec2 fmp; \
- varying highp float b; \
- varying highp vec2 A; \
- void setPosition(void) \
- {\
- vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \
- gl_Position.xy = transformedPos.xy / transformedPos.z; \
- mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \
- mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \
- mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \
- gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \
- A = hTexCoords.xy * invertedHTexCoordsZ; \
- b = 2.0 * dot(A, fmp); \
- }";
+static const char* const qglslPositionWithRadialGradientBrushVertexShader = "\n\
+ attribute highp vec2 vertexCoordsArray;\n\
+ attribute highp vec3 pmvMatrix1; \n\
+ attribute highp vec3 pmvMatrix2; \n\
+ attribute highp vec3 pmvMatrix3; \n\
+ uniform mediump vec2 halfViewportSize; \n\
+ uniform highp mat3 brushTransform; \n\
+ uniform highp vec2 fmp; \n\
+ varying highp float b; \n\
+ varying highp vec2 A; \n\
+ void setPosition(void) \n\
+ {\n\
+ highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
+ vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
+ gl_Position.xy = transformedPos.xy / transformedPos.z; \n\
+ mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\
+ mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\
+ mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
+ gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
+ A = hTexCoords.xy * invertedHTexCoordsZ; \n\
+ b = 2.0 * dot(A, fmp); \n\
+ }\n";
static const char* const qglslAffinePositionWithRadialGradientBrushVertexShader
= qglslPositionWithRadialGradientBrushVertexShader;
-static const char* const qglslRadialGradientBrushSrcFragmentShader = "\
- uniform lowp sampler2D brushTexture; \
- uniform highp float fmp2_m_radius2; \
- uniform highp float inverse_2_fmp2_m_radius2; \
- varying highp float b; \
- varying highp vec2 A; \
- lowp vec4 srcPixel() { \
- highp float c = -dot(A, A); \
- highp vec2 val = vec2((-b + sqrt(b*b - 4.0*fmp2_m_radius2*c)) * inverse_2_fmp2_m_radius2, 0.5); \
- return texture2D(brushTexture, val); \
- }";
+static const char* const qglslRadialGradientBrushSrcFragmentShader = "\n\
+ uniform lowp sampler2D brushTexture; \n\
+ uniform highp float fmp2_m_radius2; \n\
+ uniform highp float inverse_2_fmp2_m_radius2; \n\
+ varying highp float b; \n\
+ varying highp vec2 A; \n\
+ lowp vec4 srcPixel() \n\
+ { \n\
+ highp float c = -dot(A, A); \n\
+ highp vec2 val = vec2((-b + sqrt(b*b - 4.0*fmp2_m_radius2*c)) * inverse_2_fmp2_m_radius2, 0.5); \n\
+ return texture2D(brushTexture, val); \n\
+ }\n";
// Texture Brush
-static const char* const qglslPositionWithTextureBrushVertexShader = "\
- attribute highp vec2 vertexCoordsArray; \
- uniform highp mat3 pmvMatrix; \
- uniform mediump vec2 halfViewportSize; \
- uniform highp vec2 invertedTextureSize; \
- uniform highp mat3 brushTransform; \
- varying highp vec2 textureCoords; \
- void setPosition(void) { \
- vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \
- gl_Position.xy = transformedPos.xy / transformedPos.z; \
- mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \
- mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \
- mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \
- gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \
- textureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \
- }";
+static const char* const qglslPositionWithTextureBrushVertexShader = "\n\
+ attribute highp vec2 vertexCoordsArray; \n\
+ attribute highp vec3 pmvMatrix1; \n\
+ attribute highp vec3 pmvMatrix2; \n\
+ attribute highp vec3 pmvMatrix3; \n\
+ uniform mediump vec2 halfViewportSize; \n\
+ uniform highp vec2 invertedTextureSize; \n\
+ uniform highp mat3 brushTransform; \n\
+ varying highp vec2 textureCoords; \n\
+ void setPosition(void) \n\
+ { \n\
+ highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
+ vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
+ gl_Position.xy = transformedPos.xy / transformedPos.z; \n\
+ mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\
+ mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\
+ mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
+ gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
+ textureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \n\
+ }\n";
static const char* const qglslAffinePositionWithTextureBrushVertexShader
= qglslPositionWithTextureBrushVertexShader;
@@ -275,148 +294,165 @@ static const char* const qglslAffinePositionWithTextureBrushVertexShader
// OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead,
// we emulate GL_REPEAT by only taking the fractional part of the texture coords.
// TODO: Special case POT textures which don't need this emulation
-static const char* const qglslTextureBrushSrcFragmentShader = "\
- varying highp vec2 textureCoords; \
- uniform lowp sampler2D brushTexture; \
- lowp vec4 srcPixel() { \
- return texture2D(brushTexture, fract(textureCoords)); \
- }";
+static const char* const qglslTextureBrushSrcFragmentShader = "\n\
+ varying highp vec2 textureCoords; \n\
+ uniform lowp sampler2D brushTexture; \n\
+ lowp vec4 srcPixel() { \n\
+ return texture2D(brushTexture, fract(textureCoords)); \n\
+ }\n";
#else
-static const char* const qglslTextureBrushSrcFragmentShader = "\
- varying highp vec2 textureCoords; \
- uniform lowp sampler2D brushTexture; \
- lowp vec4 srcPixel() { \
- return texture2D(brushTexture, textureCoords); \
- }";
+static const char* const qglslTextureBrushSrcFragmentShader = "\n\
+ varying highp vec2 textureCoords; \n\
+ uniform lowp sampler2D brushTexture; \n\
+ lowp vec4 srcPixel() \n\
+ { \n\
+ return texture2D(brushTexture, textureCoords); \n\
+ }\n";
#endif
-static const char* const qglslTextureBrushSrcWithPatternFragmentShader = "\
- varying highp vec2 textureCoords; \
- uniform lowp vec4 patternColor; \
- uniform lowp sampler2D brushTexture; \
- lowp vec4 srcPixel() { \
- return patternColor * (1.0 - texture2D(brushTexture, textureCoords).r); \
- }";
+static const char* const qglslTextureBrushSrcWithPatternFragmentShader = "\n\
+ varying highp vec2 textureCoords; \n\
+ uniform lowp vec4 patternColor; \n\
+ uniform lowp sampler2D brushTexture; \n\
+ lowp vec4 srcPixel() \n\
+ { \n\
+ return patternColor * (1.0 - texture2D(brushTexture, textureCoords).r); \n\
+ }\n";
// Solid Fill Brush
-static const char* const qglslSolidBrushSrcFragmentShader = "\
- uniform lowp vec4 fragmentColor; \
- lowp vec4 srcPixel() { \
- return fragmentColor; \
- }";
-
-static const char* const qglslImageSrcFragmentShader = "\
- varying highp vec2 textureCoords; \
- uniform lowp sampler2D imageTexture; \
- lowp vec4 srcPixel() { \
- return texture2D(imageTexture, textureCoords); \
- }";
-
-static const char* const qglslCustomSrcFragmentShader = "\
- varying highp vec2 textureCoords; \
- uniform lowp sampler2D imageTexture; \
- lowp vec4 customShader(lowp sampler2D texture, highp vec2 coords); \
- lowp vec4 srcPixel() { \
- return customShader(imageTexture, textureCoords); \
- }";
-
-static const char* const qglslImageSrcWithPatternFragmentShader = "\
- varying highp vec2 textureCoords; \
- uniform lowp vec4 patternColor; \
- uniform lowp sampler2D imageTexture; \
- lowp vec4 srcPixel() { \
- return patternColor * (1.0 - texture2D(imageTexture, textureCoords).r); \
- }\n";
-
-static const char* const qglslNonPremultipliedImageSrcFragmentShader = "\
- varying highp vec2 textureCoords; \
- uniform lowp sampler2D imageTexture; \
- lowp vec4 srcPixel() { \
- lowp vec4 sample = texture2D(imageTexture, textureCoords); \
- sample.rgb = sample.rgb * sample.a; \
- return sample; \
- }";
-
-static const char* const qglslShockingPinkSrcFragmentShader = "\
- lowp vec4 srcPixel() { \
- return vec4(0.98, 0.06, 0.75, 1.0); \
- }";
-
-static const char* const qglslMainFragmentShader_ImageArrays = "\
- varying lowp float opacity; \
- lowp vec4 srcPixel(); \
- void main() { \
- gl_FragColor = srcPixel() * opacity; \
- }";
-
-static const char* const qglslMainFragmentShader_CMO = "\
- uniform lowp float globalOpacity; \
- lowp vec4 srcPixel(); \
- lowp vec4 applyMask(lowp vec4); \
- lowp vec4 compose(lowp vec4); \
- void main() { \
- gl_FragColor = applyMask(compose(srcPixel()*globalOpacity))); \
- }";
-
-static const char* const qglslMainFragmentShader_CM = "\
- lowp vec4 srcPixel(); \
- lowp vec4 applyMask(lowp vec4); \
- lowp vec4 compose(lowp vec4); \
- void main() { \
- gl_FragColor = applyMask(compose(srcPixel())); \
- }";
-
-static const char* const qglslMainFragmentShader_MO = "\
- uniform lowp float globalOpacity; \
- lowp vec4 srcPixel(); \
- lowp vec4 applyMask(lowp vec4); \
- void main() { \
- gl_FragColor = applyMask(srcPixel()*globalOpacity); \
- }";
-
-static const char* const qglslMainFragmentShader_M = "\
- lowp vec4 srcPixel(); \
- lowp vec4 applyMask(lowp vec4); \
- void main() { \
- gl_FragColor = applyMask(srcPixel()); \
- }";
-
-static const char* const qglslMainFragmentShader_CO = "\
- uniform lowp float globalOpacity; \
- lowp vec4 srcPixel(); \
- lowp vec4 compose(lowp vec4); \
- void main() { \
- gl_FragColor = compose(srcPixel()*globalOpacity); \
- }";
-
-static const char* const qglslMainFragmentShader_C = "\
- lowp vec4 srcPixel(); \
- lowp vec4 compose(lowp vec4); \
- void main() { \
- gl_FragColor = compose(srcPixel()); \
- }";
-
-static const char* const qglslMainFragmentShader_O = "\
- uniform lowp float globalOpacity; \
- lowp vec4 srcPixel(); \
- void main() { \
- gl_FragColor = srcPixel()*globalOpacity; \
- }";
-
-static const char* const qglslMainFragmentShader = "\
- lowp vec4 srcPixel(); \
- void main() { \
- gl_FragColor = srcPixel(); \
- }";
-
-static const char* const qglslMaskFragmentShader = "\
- varying highp vec2 textureCoords;\
- uniform lowp sampler2D maskTexture;\
- lowp vec4 applyMask(lowp vec4 src) \
- {\
- lowp vec4 mask = texture2D(maskTexture, textureCoords); \
- return src * mask.a; \
- }";
+static const char* const qglslSolidBrushSrcFragmentShader = "\n\
+ uniform lowp vec4 fragmentColor; \n\
+ lowp vec4 srcPixel() \n\
+ { \n\
+ return fragmentColor; \n\
+ }\n";
+
+static const char* const qglslImageSrcFragmentShader = "\n\
+ varying highp vec2 textureCoords; \n\
+ uniform lowp sampler2D imageTexture; \n\
+ lowp vec4 srcPixel() \n\
+ { \n\
+ return texture2D(imageTexture, textureCoords); \n\
+ }\n";
+
+static const char* const qglslCustomSrcFragmentShader = "\n\
+ varying highp vec2 textureCoords; \n\
+ uniform lowp sampler2D imageTexture; \n\
+ lowp vec4 customShader(lowp sampler2D texture, highp vec2 coords); \n\
+ lowp vec4 srcPixel() \n\
+ { \n\
+ return customShader(imageTexture, textureCoords); \n\
+ }\n";
+
+static const char* const qglslImageSrcWithPatternFragmentShader = "\n\
+ varying highp vec2 textureCoords; \n\
+ uniform lowp vec4 patternColor; \n\
+ uniform lowp sampler2D imageTexture; \n\
+ lowp vec4 srcPixel() \n\
+ { \n\
+ return patternColor * (1.0 - texture2D(imageTexture, textureCoords).r); \n\
+ }\n";
+
+static const char* const qglslNonPremultipliedImageSrcFragmentShader = "\n\
+ varying highp vec2 textureCoords; \n\
+ uniform lowp sampler2D imageTexture; \n\
+ lowp vec4 srcPixel() \n\
+ { \n\
+ lowp vec4 sample = texture2D(imageTexture, textureCoords); \n\
+ sample.rgb = sample.rgb * sample.a; \n\
+ return sample; \n\
+ }\n";
+
+static const char* const qglslShockingPinkSrcFragmentShader = "\n\
+ lowp vec4 srcPixel() \n\
+ { \n\
+ return vec4(0.98, 0.06, 0.75, 1.0); \n\
+ }\n";
+
+static const char* const qglslMainFragmentShader_ImageArrays = "\n\
+ varying lowp float opacity; \n\
+ lowp vec4 srcPixel(); \n\
+ void main() \n\
+ { \n\
+ gl_FragColor = srcPixel() * opacity; \n\
+ }\n";
+
+static const char* const qglslMainFragmentShader_CMO = "\n\
+ uniform lowp float globalOpacity; \n\
+ lowp vec4 srcPixel(); \n\
+ lowp vec4 applyMask(lowp vec4); \n\
+ lowp vec4 compose(lowp vec4); \n\
+ void main() \n\
+ { \n\
+ gl_FragColor = applyMask(compose(srcPixel()*globalOpacity))); \n\
+ }\n";
+
+static const char* const qglslMainFragmentShader_CM = "\n\
+ lowp vec4 srcPixel(); \n\
+ lowp vec4 applyMask(lowp vec4); \n\
+ lowp vec4 compose(lowp vec4); \n\
+ void main() \n\
+ { \n\
+ gl_FragColor = applyMask(compose(srcPixel())); \n\
+ }\n";
+
+static const char* const qglslMainFragmentShader_MO = "\n\
+ uniform lowp float globalOpacity; \n\
+ lowp vec4 srcPixel(); \n\
+ lowp vec4 applyMask(lowp vec4); \n\
+ void main() \n\
+ { \n\
+ gl_FragColor = applyMask(srcPixel()*globalOpacity); \n\
+ }\n";
+
+static const char* const qglslMainFragmentShader_M = "\n\
+ lowp vec4 srcPixel(); \n\
+ lowp vec4 applyMask(lowp vec4); \n\
+ void main() \n\
+ { \n\
+ gl_FragColor = applyMask(srcPixel()); \n\
+ }\n";
+
+static const char* const qglslMainFragmentShader_CO = "\n\
+ uniform lowp float globalOpacity; \n\
+ lowp vec4 srcPixel(); \n\
+ lowp vec4 compose(lowp vec4); \n\
+ void main() \n\
+ { \n\
+ gl_FragColor = compose(srcPixel()*globalOpacity); \n\
+ }\n";
+
+static const char* const qglslMainFragmentShader_C = "\n\
+ lowp vec4 srcPixel(); \n\
+ lowp vec4 compose(lowp vec4); \n\
+ void main() \n\
+ { \n\
+ gl_FragColor = compose(srcPixel()); \n\
+ }\n";
+
+static const char* const qglslMainFragmentShader_O = "\n\
+ uniform lowp float globalOpacity; \n\
+ lowp vec4 srcPixel(); \n\
+ void main() \n\
+ { \n\
+ gl_FragColor = srcPixel()*globalOpacity; \n\
+ }\n";
+
+static const char* const qglslMainFragmentShader = "\n\
+ lowp vec4 srcPixel(); \n\
+ void main() \n\
+ { \n\
+ gl_FragColor = srcPixel(); \n\
+ }\n";
+
+static const char* const qglslMaskFragmentShader = "\n\
+ varying highp vec2 textureCoords;\n\
+ uniform lowp sampler2D maskTexture;\n\
+ lowp vec4 applyMask(lowp vec4 src) \n\
+ {\n\
+ lowp vec4 mask = texture2D(maskTexture, textureCoords); \n\
+ return src * mask.a; \n\
+ }\n";
// For source over with subpixel antialiasing, the final color is calculated per component as follows
// (.a is alpha component, .c is red, green or blue component):
@@ -433,23 +469,23 @@ static const char* const qglslMaskFragmentShader = "\
// dest.c = dest.c * (1 - mask.c) + src.c * alpha
//
-static const char* const qglslRgbMaskFragmentShaderPass1 = "\
- varying highp vec2 textureCoords;\
- uniform lowp sampler2D maskTexture;\
- lowp vec4 applyMask(lowp vec4 src) \
- {\
- lowp vec4 mask = texture2D(maskTexture, textureCoords); \
- return src.a * mask; \
- }";
-
-static const char* const qglslRgbMaskFragmentShaderPass2 = "\
- varying highp vec2 textureCoords;\
- uniform lowp sampler2D maskTexture;\
- lowp vec4 applyMask(lowp vec4 src) \
- {\
- lowp vec4 mask = texture2D(maskTexture, textureCoords); \
- return src * mask; \
- }";
+static const char* const qglslRgbMaskFragmentShaderPass1 = "\n\
+ varying highp vec2 textureCoords;\n\
+ uniform lowp sampler2D maskTexture;\n\
+ lowp vec4 applyMask(lowp vec4 src) \n\
+ { \n\
+ lowp vec4 mask = texture2D(maskTexture, textureCoords); \n\
+ return src.a * mask; \n\
+ }\n";
+
+static const char* const qglslRgbMaskFragmentShaderPass2 = "\n\
+ varying highp vec2 textureCoords;\n\
+ uniform lowp sampler2D maskTexture;\n\
+ lowp vec4 applyMask(lowp vec4 src) \n\
+ { \n\
+ lowp vec4 mask = texture2D(maskTexture, textureCoords); \n\
+ return src * mask; \n\
+ }\n";
/*
Left to implement:
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index caa679b..b282676 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -168,12 +168,6 @@ void QGL2PaintEngineExPrivate::useSimpleShader()
if (matrixDirty)
updateMatrix();
-
- if (simpleShaderMatrixUniformDirty) {
- const GLuint location = shaderManager->simpleProgram()->uniformLocation("pmvMatrix");
- glUniformMatrix3fv(location, 1, GL_FALSE, (GLfloat*)pmvMatrix);
- simpleShaderMatrixUniformDirty = false;
- }
}
void QGL2PaintEngineExPrivate::updateBrushTexture()
@@ -392,9 +386,11 @@ void QGL2PaintEngineExPrivate::updateMatrix()
matrixDirty = false;
- // The actual data has been updated so both shader program's uniforms need updating
- simpleShaderMatrixUniformDirty = true;
- shaderMatrixUniformDirty = true;
+ // Set the PMV matrix attribute. As we use an attributes rather than uniforms, we only
+ // need to do this once for every matrix change and persists across all shader programs.
+ glVertexAttrib3fv(QT_PMV_MATRIX_1_ATTR, pmvMatrix[0]);
+ glVertexAttrib3fv(QT_PMV_MATRIX_2_ATTR, pmvMatrix[1]);
+ glVertexAttrib3fv(QT_PMV_MATRIX_3_ATTR, pmvMatrix[2]);
dasher.setInvScale(inverseScale);
stroker.setInvScale(inverseScale);
@@ -932,18 +928,12 @@ bool QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque)
if (changed) {
// The shader program has changed so mark all uniforms as dirty:
brushUniformsDirty = true;
- shaderMatrixUniformDirty = true;
opacityUniformDirty = true;
}
if (brushUniformsDirty && mode != ImageDrawingMode && mode != ImageArrayDrawingMode)
updateBrushUniforms();
- if (shaderMatrixUniformDirty) {
- glUniformMatrix3fv(location(QGLEngineShaderManager::PmvMatrix), 1, GL_FALSE, (GLfloat*)pmvMatrix);
- shaderMatrixUniformDirty = false;
- }
-
if (opacityMode == QGLEngineShaderManager::UniformOpacity && opacityUniformDirty) {
shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::GlobalOpacity), (GLfloat)q->state()->opacity);
opacityUniformDirty = false;
@@ -1955,11 +1945,8 @@ void QGL2PaintEngineEx::setState(QPainterState *new_state)
if (old_state == s || old_state->renderHintsChanged)
renderHintsChanged();
- if (old_state == s || old_state->matrixChanged) {
+ if (old_state == s || old_state->matrixChanged)
d->matrixDirty = true;
- d->simpleShaderMatrixUniformDirty = true;
- d->shaderMatrixUniformDirty = true;
- }
if (old_state == s || old_state->compositionModeChanged)
d->compositionModeDirty = true;
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
index ce1b538..8fa0eff 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
@@ -252,8 +252,6 @@ public:
bool compositionModeDirty;
bool brushTextureDirty;
bool brushUniformsDirty;
- bool simpleShaderMatrixUniformDirty;
- bool shaderMatrixUniformDirty;
bool opacityUniformDirty;
bool stencilClean; // Has the stencil not been used for clipping so far?
diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp
index 6d47687..aa80664 100644
--- a/src/opengl/qpixmapdata_gl.cpp
+++ b/src/opengl/qpixmapdata_gl.cpp
@@ -252,10 +252,6 @@ QGLPixmapData::QGLPixmapData(PixelType type)
{
setSerialNumber(++qt_gl_pixmap_serial);
m_glDevice.setPixmapData(this);
-
- // Set InteralBindOptions minus the memory managed, since this
- // QGLTexture is not managed as part of the internal texture cache
- m_texture.options = QGLContext::PremultipliedAlphaBindOption;
}
QGLPixmapData::~QGLPixmapData()
@@ -344,18 +340,18 @@ void QGLPixmapData::ensureCreated() const
}
if (!m_source.isNull()) {
- glBindTexture(target, m_texture.id);
if (external_format == GL_RGB) {
- const QImage tx = m_source.convertToFormat(QImage::Format_RGB888);
+ const QImage tx = m_source.convertToFormat(QImage::Format_RGB888).mirrored(false, true);
+
+ glBindTexture(target, m_texture.id);
glTexSubImage2D(target, 0, 0, 0, w, h, external_format,
GL_UNSIGNED_BYTE, tx.bits());
} else {
const QImage tx = ctx->d_func()->convertToGLFormat(m_source, true, external_format);
+
+ glBindTexture(target, m_texture.id);
glTexSubImage2D(target, 0, 0, 0, w, h, external_format,
GL_UNSIGNED_BYTE, tx.bits());
- // convertToGLFormat will flip the Y axis, so it needs to
- // be drawn upside down
- m_texture.options |= QGLContext::InvertedYBindOption;
}
if (useFramebufferObjects())
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
index 1cbfdaf..f27440e 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
@@ -552,6 +552,34 @@ QImage *QDirectFBPixmapData::buffer()
return &lockedImage;
}
+
+bool QDirectFBPixmapData::scroll(int dx, int dy, const QRect &rect)
+{
+ if (!dfbSurface) {
+ return false;
+ }
+ unlockSurface();
+ DFBResult result = dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBPixmapData::scroll", result);
+ return false;
+ }
+ result = dfbSurface->SetPorterDuff(dfbSurface, DSPD_NONE);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBPixmapData::scroll", result);
+ return false;
+ }
+
+ const DFBRectangle source = { rect.x(), rect.y(), rect.width(), rect.height() };
+ result = dfbSurface->Blit(dfbSurface, dfbSurface, &source, source.x + dx, source.y + dy);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBPixmapData::scroll", result);
+ return false;
+ }
+
+ return true;
+}
+
void QDirectFBPixmapData::invalidate()
{
if (dfbSurface) {
@@ -568,6 +596,3 @@ void QDirectFBPixmapData::invalidate()
QT_END_NAMESPACE
#endif // QT_NO_QWS_DIRECTFB
-
-
-
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h
index f9b14a9..da6edc6 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h
@@ -81,6 +81,7 @@ public:
virtual QImage toImage() const;
virtual QPaintEngine *paintEngine() const;
virtual QImage *buffer();
+ virtual bool scroll(int dx, int dy, const QRect &rect);
// Pure virtual in QPixmapData, so re-implement here and delegate to QDirectFBPaintDevice
virtual int metric(QPaintDevice::PaintDeviceMetric m) const { return QDirectFBPaintDevice::metric(m); }