summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/accessible/qaccessible.cpp151
-rw-r--r--src/gui/accessible/qaccessible.h42
-rw-r--r--src/gui/accessible/qaccessiblebridge.h2
-rw-r--r--src/gui/accessible/qaccessibleplugin.h2
-rw-r--r--src/gui/doc/qtgui.qdocconf2
-rw-r--r--src/gui/doc/snippets/qfileopenevent/Info.plist59
-rw-r--r--src/gui/doc/snippets/qfileopenevent/main.cpp73
-rw-r--r--src/gui/doc/snippets/qfontdatabase/main.cpp2
-rw-r--r--src/gui/image/qbitmap.h2
-rw-r--r--src/gui/image/qicon.cpp108
-rw-r--r--src/gui/image/qicon.h12
-rw-r--r--src/gui/image/qicon_p.h1
-rw-r--r--src/gui/image/qiconengine.cpp7
-rw-r--r--src/gui/image/qiconengine.h1
-rw-r--r--src/gui/image/qiconengineplugin.h2
-rw-r--r--src/gui/image/qiconloader.cpp11
-rw-r--r--src/gui/image/qiconloader_p.h2
-rw-r--r--src/gui/image/qimage.cpp166
-rw-r--r--src/gui/image/qimage.h37
-rw-r--r--src/gui/image/qimage_conversions.cpp38
-rw-r--r--src/gui/image/qimage_neon.cpp30
-rw-r--r--src/gui/image/qimage_p.h37
-rw-r--r--src/gui/image/qimageiohandler.h2
-rw-r--r--src/gui/image/qimagereader.cpp42
-rw-r--r--src/gui/image/qimagereader.h3
-rw-r--r--src/gui/image/qimagewriter.cpp4
-rw-r--r--src/gui/image/qjpeghandler.cpp4
-rw-r--r--src/gui/image/qmovie.h6
-rw-r--r--src/gui/image/qpaintengine_pic.cpp1
-rw-r--r--src/gui/image/qpicture.cpp7
-rw-r--r--src/gui/image/qpicture.h8
-rw-r--r--src/gui/image/qpicture_p.h5
-rw-r--r--src/gui/image/qpictureformatplugin.h2
-rw-r--r--src/gui/image/qpixmap.cpp6
-rw-r--r--src/gui/image/qpixmap.h16
-rw-r--r--src/gui/image/qpixmap_blitter.cpp2
-rw-r--r--src/gui/image/qpixmap_raster.cpp30
-rw-r--r--src/gui/image/qpixmap_win.cpp28
-rw-r--r--src/gui/image/qpixmapcache.cpp43
-rw-r--r--src/gui/image/qpixmapcache.h12
-rw-r--r--src/gui/image/qpnghandler.cpp27
-rw-r--r--src/gui/image/qpnghandler.pri7
-rw-r--r--src/gui/image/qppmhandler.cpp16
-rw-r--r--src/gui/itemmodels/qstandarditemmodel.cpp83
-rw-r--r--src/gui/itemmodels/qstandarditemmodel.h22
-rw-r--r--src/gui/itemmodels/qstandarditemmodel_p.h2
-rw-r--r--src/gui/kernel/kernel.pri8
-rw-r--r--src/gui/kernel/qcursor.cpp18
-rw-r--r--src/gui/kernel/qdnd.cpp8
-rw-r--r--src/gui/kernel/qevent.cpp62
-rw-r--r--src/gui/kernel/qevent.h13
-rw-r--r--src/gui/kernel/qgenericplugin.h2
-rw-r--r--src/gui/kernel/qguiapplication.cpp238
-rw-r--r--src/gui/kernel/qguiapplication.h2
-rw-r--r--src/gui/kernel/qguiapplication_p.h2
-rw-r--r--src/gui/kernel/qguivariant.cpp9
-rw-r--r--src/gui/kernel/qhighdpiscaling.cpp423
-rw-r--r--src/gui/kernel/qhighdpiscaling_p.h514
-rw-r--r--src/gui/kernel/qinputmethod.cpp3
-rw-r--r--src/gui/kernel/qinputmethod.h2
-rw-r--r--src/gui/kernel/qkeymapper_p.h1
-rw-r--r--src/gui/kernel/qkeysequence.cpp82
-rw-r--r--src/gui/kernel/qkeysequence.h15
-rw-r--r--src/gui/kernel/qkeysequence_p.h13
-rw-r--r--src/gui/kernel/qoffscreensurface.h2
-rw-r--r--src/gui/kernel/qopenglcontext.cpp54
-rw-r--r--src/gui/kernel/qopenglcontext.h9
-rw-r--r--src/gui/kernel/qopenglcontext_p.h2
-rw-r--r--src/gui/kernel/qopenglwindow.cpp5
-rw-r--r--src/gui/kernel/qopenglwindow.h4
-rw-r--r--src/gui/kernel/qpaintdevicewindow.cpp6
-rw-r--r--src/gui/kernel/qpaintdevicewindow_p.h11
-rw-r--r--src/gui/kernel/qplatformcursor.cpp2
-rw-r--r--src/gui/kernel/qplatformcursor.h2
-rw-r--r--src/gui/kernel/qplatformdialoghelper.cpp19
-rw-r--r--src/gui/kernel/qplatformdialoghelper.h25
-rw-r--r--src/gui/kernel/qplatformgraphicsbufferhelper.cpp93
-rw-r--r--src/gui/kernel/qplatformgraphicsbufferhelper.h4
-rw-r--r--src/gui/kernel/qplatforminputcontextfactory.cpp46
-rw-r--r--src/gui/kernel/qplatforminputcontextfactory_p.h1
-rw-r--r--src/gui/kernel/qplatformintegration.cpp48
-rw-r--r--src/gui/kernel/qplatformintegration.h7
-rw-r--r--src/gui/kernel/qplatformintegrationfactory.cpp7
-rw-r--r--src/gui/kernel/qplatformmenu.h2
-rw-r--r--src/gui/kernel/qplatformscreen.cpp85
-rw-r--r--src/gui/kernel/qplatformscreen.h17
-rw-r--r--src/gui/kernel/qplatformsystemtrayicon.h2
-rw-r--r--src/gui/kernel/qplatformtheme.cpp4
-rw-r--r--src/gui/kernel/qplatformtheme.h2
-rw-r--r--src/gui/kernel/qplatformthemefactory.cpp4
-rw-r--r--src/gui/kernel/qplatformwindow.cpp131
-rw-r--r--src/gui/kernel/qplatformwindow.h15
-rw-r--r--src/gui/kernel/qrasterwindow.cpp2
-rw-r--r--src/gui/kernel/qrasterwindow.h2
-rw-r--r--src/gui/kernel/qscreen.cpp85
-rw-r--r--src/gui/kernel/qscreen.h8
-rw-r--r--src/gui/kernel/qscreen_p.h25
-rw-r--r--src/gui/kernel/qshapedpixmapdndwindow.cpp17
-rw-r--r--src/gui/kernel/qshapedpixmapdndwindow_p.h4
-rw-r--r--src/gui/kernel/qshortcutmap.cpp69
-rw-r--r--src/gui/kernel/qshortcutmap_p.h5
-rw-r--r--src/gui/kernel/qsimpledrag.cpp85
-rw-r--r--src/gui/kernel/qsimpledrag_p.h16
-rw-r--r--src/gui/kernel/qstylehints.cpp18
-rw-r--r--src/gui/kernel/qstylehints.h2
-rw-r--r--src/gui/kernel/qtouchdevice.cpp25
-rw-r--r--src/gui/kernel/qtouchdevice_p.h6
-rw-r--r--src/gui/kernel/qwindow.cpp164
-rw-r--r--src/gui/kernel/qwindow.h13
-rw-r--r--src/gui/kernel/qwindow_p.h3
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp422
-rw-r--r--src/gui/kernel/qwindowsysteminterface.h35
-rw-r--r--src/gui/kernel/qwindowsysteminterface_p.h30
-rw-r--r--src/gui/math3d/qmatrix4x4.h2
-rw-r--r--src/gui/math3d/qquaternion.h28
-rw-r--r--src/gui/math3d/qvector2d.h2
-rw-r--r--src/gui/math3d/qvector3d.h2
-rw-r--r--src/gui/math3d/qvector4d.h2
-rw-r--r--src/gui/opengl/opengl.pri3
-rw-r--r--src/gui/opengl/qopengl.cpp124
-rw-r--r--src/gui/opengl/qopengl.h12
-rw-r--r--src/gui/opengl/qopengl_p.h12
-rw-r--r--src/gui/opengl/qopenglbuffer.h2
-rw-r--r--src/gui/opengl/qopengldebug.h10
-rw-r--r--src/gui/opengl/qopenglengineshadermanager.cpp3
-rw-r--r--src/gui/opengl/qopenglextensions_p.h259
-rw-r--r--src/gui/opengl/qopenglextrafunctions.h1990
-rw-r--r--src/gui/opengl/qopenglframebufferobject.cpp491
-rw-r--r--src/gui/opengl/qopenglframebufferobject.h22
-rw-r--r--src/gui/opengl/qopenglframebufferobject_p.h27
-rw-r--r--src/gui/opengl/qopenglfunctions.cpp4285
-rw-r--r--src/gui/opengl/qopenglfunctions.h5
-rw-r--r--src/gui/opengl/qopenglgradientcache.cpp78
-rw-r--r--src/gui/opengl/qopenglgradientcache_p.h6
-rw-r--r--src/gui/opengl/qopenglpaintdevice.cpp7
-rw-r--r--src/gui/opengl/qopenglpaintdevice_p.h2
-rw-r--r--src/gui/opengl/qopenglpaintengine.cpp17
-rw-r--r--src/gui/opengl/qopenglpaintengine_p.h5
-rw-r--r--src/gui/opengl/qopenglpixeltransferoptions.h9
-rw-r--r--src/gui/opengl/qopenglshaderprogram.cpp2
-rw-r--r--src/gui/opengl/qopenglshaderprogram.h8
-rw-r--r--src/gui/opengl/qopengltexture.cpp293
-rw-r--r--src/gui/opengl/qopengltexture.h33
-rw-r--r--src/gui/opengl/qopengltexture_p.h3
-rw-r--r--src/gui/opengl/qopengltextureblitter.cpp257
-rw-r--r--src/gui/opengl/qopengltextureblitter_p.h4
-rw-r--r--src/gui/opengl/qopengltexturehelper.cpp208
-rw-r--r--src/gui/opengl/qopengltexturehelper_p.h37
-rw-r--r--src/gui/opengl/qopengltimerquery.h4
-rw-r--r--src/gui/opengl/qopenglversionfunctions.h5
-rw-r--r--src/gui/opengl/qopenglvertexarrayobject.h2
-rw-r--r--src/gui/opengl/qtriangulatingstroker.cpp4
-rw-r--r--src/gui/painting/painting.pri14
-rw-r--r--src/gui/painting/qbackingstore.cpp49
-rw-r--r--src/gui/painting/qbackingstore.h2
-rw-r--r--src/gui/painting/qblendfunctions.cpp187
-rw-r--r--src/gui/painting/qbrush.cpp1
-rw-r--r--src/gui/painting/qcolor.cpp96
-rw-r--r--src/gui/painting/qcolor.h42
-rw-r--r--src/gui/painting/qcompositionfunctions.cpp2197
-rw-r--r--src/gui/painting/qcosmeticstroker.cpp3
-rw-r--r--src/gui/painting/qdatabuffer_p.h1
-rw-r--r--src/gui/painting/qdrawhelper.cpp3634
-rw-r--r--src/gui/painting/qdrawhelper_neon.cpp101
-rw-r--r--src/gui/painting/qdrawhelper_neon_asm.S4
-rw-r--r--src/gui/painting/qdrawhelper_neon_p.h2
-rw-r--r--src/gui/painting/qdrawhelper_p.h249
-rw-r--r--src/gui/painting/qdrawhelper_sse2.cpp103
-rw-r--r--src/gui/painting/qdrawhelper_x86_p.h6
-rw-r--r--src/gui/painting/qimagescale.cpp152
-rw-r--r--src/gui/painting/qimagescale_sse4.cpp42
-rw-r--r--src/gui/painting/qmatrix.cpp24
-rw-r--r--src/gui/painting/qmatrix.h4
-rw-r--r--src/gui/painting/qpagedpaintdevice.cpp4
-rw-r--r--src/gui/painting/qpagedpaintdevice_p.h4
-rw-r--r--src/gui/painting/qpagelayout.h11
-rw-r--r--src/gui/painting/qpagesize.h10
-rw-r--r--src/gui/painting/qpaintdevice.cpp6
-rw-r--r--src/gui/painting/qpaintdevice.h6
-rw-r--r--src/gui/painting/qpaintdevice.qdoc29
-rw-r--r--src/gui/painting/qpaintengine.cpp4
-rw-r--r--src/gui/painting/qpaintengine.h4
-rw-r--r--src/gui/painting/qpaintengine_p.h3
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp113
-rw-r--r--src/gui/painting/qpainter.cpp17
-rw-r--r--src/gui/painting/qpainter.h10
-rw-r--r--src/gui/painting/qpainter_p.h3
-rw-r--r--src/gui/painting/qpathclipper.cpp10
-rw-r--r--src/gui/painting/qpathclipper_p.h3
-rw-r--r--src/gui/painting/qpdf.cpp49
-rw-r--r--src/gui/painting/qpdf_p.h4
-rw-r--r--src/gui/painting/qpen.cpp1
-rw-r--r--src/gui/painting/qplatformbackingstore.cpp162
-rw-r--r--src/gui/painting/qplatformbackingstore.h3
-rw-r--r--src/gui/painting/qpolygon.h22
-rw-r--r--src/gui/painting/qregion.cpp33
-rw-r--r--src/gui/painting/qrgb.h4
-rw-r--r--src/gui/painting/qrgba64.h228
-rw-r--r--src/gui/painting/qrgba64.qdoc303
-rw-r--r--src/gui/painting/qrgba64_p.h131
-rw-r--r--src/gui/painting/qtextureglyphcache.cpp33
-rw-r--r--src/gui/painting/qtextureglyphcache_p.h4
-rw-r--r--src/gui/painting/qtransform.cpp28
-rw-r--r--src/gui/painting/qtransform.h4
-rw-r--r--src/gui/text/qabstracttextdocumentlayout.cpp9
-rw-r--r--src/gui/text/qabstracttextdocumentlayout.h4
-rw-r--r--src/gui/text/qabstracttextdocumentlayout_p.h3
-rw-r--r--src/gui/text/qcssparser.cpp1
-rw-r--r--src/gui/text/qfont.cpp21
-rw-r--r--src/gui/text/qfontdatabase.cpp97
-rw-r--r--src/gui/text/qfontengine.cpp112
-rw-r--r--src/gui/text/qfontengine_ft.cpp188
-rw-r--r--src/gui/text/qfontengine_ft_p.h99
-rw-r--r--src/gui/text/qfontengine_p.h21
-rw-r--r--src/gui/text/qfontengineglyphcache.cpp43
-rw-r--r--src/gui/text/qfontengineglyphcache_p.h4
-rw-r--r--src/gui/text/qfontmetrics.h10
-rw-r--r--src/gui/text/qfontsubset.cpp41
-rw-r--r--src/gui/text/qfontsubset_p.h2
-rw-r--r--src/gui/text/qglyphrun.cpp1
-rw-r--r--src/gui/text/qglyphrun.h8
-rw-r--r--src/gui/text/qharfbuzzng.cpp10
-rw-r--r--src/gui/text/qplatformfontdatabase.cpp15
-rw-r--r--src/gui/text/qplatformfontdatabase.h2
-rw-r--r--src/gui/text/qrawfont.cpp1
-rw-r--r--src/gui/text/qrawfont.h10
-rw-r--r--src/gui/text/qstatictext.cpp8
-rw-r--r--src/gui/text/qstatictext.h7
-rw-r--r--src/gui/text/qstatictext_p.h5
-rw-r--r--src/gui/text/qsyntaxhighlighter.cpp8
-rw-r--r--src/gui/text/qtextcursor.h8
-rw-r--r--src/gui/text/qtextcursor_p.h3
-rw-r--r--src/gui/text/qtextdocument.cpp29
-rw-r--r--src/gui/text/qtextdocument.h18
-rw-r--r--src/gui/text/qtextdocumentlayout.cpp18
-rw-r--r--src/gui/text/qtextengine.cpp63
-rw-r--r--src/gui/text/qtextengine_p.h33
-rw-r--r--src/gui/text/qtextformat.cpp8
-rw-r--r--src/gui/text/qtextformat_p.h1
-rw-r--r--src/gui/text/qtextimagehandler.cpp36
-rw-r--r--src/gui/text/qtextlayout.cpp127
-rw-r--r--src/gui/text/qtextlayout.h24
-rw-r--r--src/gui/text/qtextobject.cpp5
-rw-r--r--src/gui/text/qtextobject.h6
-rw-r--r--src/gui/text/qtextodfwriter.cpp11
-rw-r--r--src/gui/text/qtextodfwriter_p.h2
-rw-r--r--src/gui/text/qtextoption.cpp6
-rw-r--r--src/gui/text/qtexttable.cpp17
-rw-r--r--src/gui/text/qtexttable.h4
-rw-r--r--src/gui/text/qzip.cpp83
-rw-r--r--src/gui/text/qzipreader_p.h18
-rw-r--r--src/gui/text/text.pri2
-rw-r--r--src/gui/util/qdesktopservices.cpp6
-rw-r--r--src/gui/util/qvalidator.h18
254 files changed, 17033 insertions, 4892 deletions
diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp
index e0ebcd18ce..1a8d263f94 100644
--- a/src/gui/accessible/qaccessible.cpp
+++ b/src/gui/accessible/qaccessible.cpp
@@ -443,14 +443,14 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QAccessibleInterface::~QAccessibleInterface()
-
- Destroys the object.
+ Destroys the QAccessibleInterface.
*/
+QAccessibleInterface::~QAccessibleInterface()
+{
+}
/*!
\typedef QAccessible::Id
- \relates QAccessible
Synonym for unsigned, used by the QAccessibleInterface cache.
*/
@@ -461,12 +461,12 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_LIBRARY
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QAccessibleFactoryInterface_iid, QLatin1String("/accessible")))
+typedef QHash<QString, QAccessiblePlugin*> QAccessiblePluginsHash;
+Q_GLOBAL_STATIC(QAccessiblePluginsHash, qAccessiblePlugins)
#endif
// FIXME turn this into one global static struct
Q_GLOBAL_STATIC(QList<QAccessible::InterfaceFactory>, qAccessibleFactories)
-typedef QHash<QString, QAccessiblePlugin*> QAccessiblePluginsHash;
-Q_GLOBAL_STATIC(QAccessiblePluginsHash, qAccessiblePlugins)
Q_GLOBAL_STATIC(QList<QAccessible::ActivationObserver *>, qAccessibleActivationObservers)
QAccessible::UpdateHandler QAccessible::updateHandler = 0;
@@ -608,6 +608,11 @@ QAccessible::RootObjectHandler QAccessible::installRootObjectHandler(RootObjectH
\sa installActivationObserver()
*/
+QAccessible::ActivationObserver::~ActivationObserver()
+{
+ // must be empty until ### Qt 6
+}
+
/*!
\internal
@@ -847,18 +852,17 @@ void QAccessible::updateAccessibility(QAccessibleEvent *event)
// during construction of widgets. If you see cases where the
// cache seems wrong, this call is "to blame", but the code that
// caches dynamic data should be updated to handle change events.
- if (!isActive() || !event->accessibleInterface())
- return;
-
- if (event->type() == QAccessible::TableModelChanged) {
- QAccessibleInterface *iface = event->accessibleInterface();
- if (iface && iface->tableInterface())
- iface->tableInterface()->modelChange(static_cast<QAccessibleTableModelChangeEvent*>(event));
- }
+ QAccessibleInterface *iface = event->accessibleInterface();
+ if (isActive() && iface) {
+ if (event->type() == QAccessible::TableModelChanged) {
+ if (iface->tableInterface())
+ iface->tableInterface()->modelChange(static_cast<QAccessibleTableModelChangeEvent*>(event));
+ }
- if (updateHandler) {
- updateHandler(event);
- return;
+ if (updateHandler) {
+ updateHandler(event);
+ return;
+ }
}
if (QPlatformAccessibility *pfAccessibility = platformAccessibility())
@@ -1254,10 +1258,6 @@ QColor QAccessibleInterface::backgroundColor() const
return QColor();
}
-QAccessibleInterface::~QAccessibleInterface()
-{
-}
-
/*!
\fn QAccessibleTextInterface *QAccessibleInterface::textInterface()
*/
@@ -1329,9 +1329,13 @@ QAccessibleInterface::~QAccessibleInterface()
the overload taking a \l QObject parameter as it might be cheaper.
*/
-/*! \fn QAccessibleEvent::~QAccessibleEvent()
+/*!
Destroys the event.
*/
+QAccessibleEvent::~QAccessibleEvent()
+{
+ // must be empty until ### Qt 6
+}
/*! \fn QAccessible::Event QAccessibleEvent::type() const
Returns the event type.
@@ -1400,6 +1404,13 @@ QAccessible::Id QAccessibleEvent::uniqueId() const
Returns the new value of the accessible object of this event.
*/
+/*!
+ \internal
+*/
+QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent()
+{
+ // must be empty until ### Qt 6
+}
/*!
\class QAccessibleStateChangeEvent
@@ -1437,7 +1448,13 @@ QAccessible::Id QAccessibleEvent::uniqueId() const
other hand tells about the change and has focused set to \c true since
the focus state is changed from \c true to \c false.
*/
-
+/*!
+ \internal
+*/
+QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent()
+{
+ // must be empty until ### Qt 6
+}
/*!
\class QAccessibleTableModelChangeEvent
@@ -1512,7 +1529,14 @@ QAccessible::Id QAccessibleEvent::uniqueId() const
change type \a changeType.
*/
/*!
- \class QAccessibleTextCursorEvent
+ \internal
+*/
+QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent()
+{
+ // must be empty until ### Qt 6
+}
+/*!
+ \class QAccessibleTextCursorEvent
\ingroup accessibility
\inmodule QtGui
@@ -1533,6 +1557,14 @@ QAccessible::Id QAccessibleEvent::uniqueId() const
Sets the cursor \a position for this event.
*/
+/*!
+ \internal
+*/
+QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent()
+{
+ // must be empty until ### Qt 6
+}
+
/*!
\fn QAccessibleTextCursorEvent(QAccessibleInterface *iface, int cursorPos)
@@ -1566,6 +1598,14 @@ QAccessible::Id QAccessibleEvent::uniqueId() const
Returns the text that has been inserted.
*/
+/*!
+ \internal
+*/
+QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent()
+{
+ // must be empty until ### Qt 6
+}
+
/*!
\class QAccessibleTextRemoveEvent
@@ -1602,6 +1642,14 @@ QAccessible::Id QAccessibleEvent::uniqueId() const
Returns the text that has been removed.
*/
/*!
+ \internal
+*/
+QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent()
+{
+ // must be empty until ### Qt 6
+}
+
+/*!
\fn QAccessibleTextSelectionEvent::QAccessibleTextSelectionEvent(QAccessibleInterface *iface, int start, int end)
Constructs a new QAccessibleTextSelectionEvent for \a iface. The new selection this
@@ -1655,6 +1703,14 @@ QAccessible::Id QAccessibleEvent::uniqueId() const
Returns the removed text.
*/
+/*!
+ \internal
+*/
+QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent()
+{
+ // must be empty until ### Qt 6
+}
+
/*!
\class QAccessibleTextSelectionEvent
@@ -1682,6 +1738,13 @@ QAccessible::Id QAccessibleEvent::uniqueId() const
Sets the selection for this event from position \a start to \a end.
*/
+/*!
+ \internal
+*/
+QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent()
+{
+ // must be empty until ### Qt 6
+}
@@ -1920,10 +1983,13 @@ QDebug operator<<(QDebug d, const QAccessibleEvent &ev)
*/
/*!
- \fn QAccessibleTextInterface::~QAccessibleTextInterface()
Destroys the QAccessibleTextInterface.
*/
+QAccessibleTextInterface::~QAccessibleTextInterface()
+{
+ // must be empty until ### Qt 6
+}
/*!
\fn void QAccessibleTextInterface::addSelection(int startOffset, int endOffset)
@@ -2306,10 +2372,13 @@ QString QAccessibleTextInterface::textAtOffset(int offset, QAccessible::TextBoun
*/
/*!
- \fn QAccessibleEditableTextInterface::~QAccessibleEditableTextInterface()
Destroys the QAccessibleEditableTextInterface.
*/
+QAccessibleEditableTextInterface::~QAccessibleEditableTextInterface()
+{
+ // must be empty until ### Qt 6
+}
/*!
\fn void QAccessibleEditableTextInterface::deleteText(int startOffset, int endOffset)
@@ -2348,10 +2417,13 @@ QString QAccessibleTextInterface::textAtOffset(int offset, QAccessible::TextBoun
*/
/*!
- \fn QAccessibleValueInterface::~QAccessibleValueInterface()
+ Destroys the QAccessibleValueInterface.
- Destructor.
*/
+QAccessibleValueInterface::~QAccessibleValueInterface()
+{
+ // must be empty until ### Qt 6
+}
/*!
\fn QVariant QAccessibleValueInterface::currentValue() const
@@ -2410,6 +2482,14 @@ QString QAccessibleTextInterface::textAtOffset(int offset, QAccessible::TextBoun
*/
/*!
+ Destroys the QAccessibleImageInterface.
+*/
+QAccessibleImageInterface::~QAccessibleImageInterface()
+{
+ // must be empty until ### Qt 6
+}
+
+/*!
\class QAccessibleTableCellInterface
\inmodule QtGui
\ingroup accessibility
@@ -2421,10 +2501,13 @@ QString QAccessibleTextInterface::textAtOffset(int offset, QAccessible::TextBoun
*/
/*!
- \fn virtual QAccessibleTableCellInterface::~QAccessibleTableCellInterface()
Destroys the QAccessibleTableCellInterface.
*/
+QAccessibleTableCellInterface::~QAccessibleTableCellInterface()
+{
+ // must be empty until ### Qt 6
+}
/*!
\fn virtual int QAccessibleTableCellInterface::columnExtent() const
@@ -2486,10 +2569,13 @@ QString QAccessibleTextInterface::textAtOffset(int offset, QAccessible::TextBoun
*/
/*!
- \fn virtual QAccessibleTableInterface::~QAccessibleTableInterface()
Destroys the QAccessibleTableInterface.
*/
+QAccessibleTableInterface::~QAccessibleTableInterface()
+{
+ // must be empty until ### Qt 6
+}
/*!
\fn virtual QAccessibleInterface *QAccessibleTableInterface::cellAt(int row, int column) const
@@ -2659,10 +2745,13 @@ QString QAccessibleTextInterface::textAtOffset(int offset, QAccessible::TextBoun
*/
/*!
- \fn QAccessibleActionInterface::~QAccessibleActionInterface()
Destroys the QAccessibleActionInterface.
*/
+QAccessibleActionInterface::~QAccessibleActionInterface()
+{
+ // must be empty until ### Qt 6
+}
/*!
\fn QStringList QAccessibleActionInterface::actionNames() const
diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h
index bfe1e6c542..63658260fc 100644
--- a/src/gui/accessible/qaccessible.h
+++ b/src/gui/accessible/qaccessible.h
@@ -396,10 +396,10 @@ public:
static UpdateHandler installUpdateHandler(UpdateHandler);
static RootObjectHandler installRootObjectHandler(RootObjectHandler);
- class ActivationObserver
+ class Q_GUI_EXPORT ActivationObserver
{
public:
- virtual ~ActivationObserver() {}
+ virtual ~ActivationObserver();
virtual void accessibilityActiveChanged(bool active) = 0;
};
static void installActivationObserver(ActivationObserver *);
@@ -505,7 +505,7 @@ public:
virtual void virtual_hook(int id, void *data);
virtual void *interface_cast(QAccessible::InterfaceType)
- { return 0; }
+ { return Q_NULLPTR; }
protected:
friend class QAccessibleCache;
@@ -514,7 +514,7 @@ protected:
class Q_GUI_EXPORT QAccessibleTextInterface
{
public:
- virtual ~QAccessibleTextInterface() {}
+ virtual ~QAccessibleTextInterface();
// selection
virtual void selection(int selectionIndex, int *startOffset, int *endOffset) const = 0;
virtual int selectionCount() const = 0;
@@ -547,7 +547,7 @@ public:
class Q_GUI_EXPORT QAccessibleEditableTextInterface
{
public:
- virtual ~QAccessibleEditableTextInterface() {}
+ virtual ~QAccessibleEditableTextInterface();
virtual void deleteText(int startOffset, int endOffset) = 0;
virtual void insertText(int offset, const QString &text) = 0;
@@ -557,8 +557,7 @@ public:
class Q_GUI_EXPORT QAccessibleValueInterface
{
public:
-
- virtual ~QAccessibleValueInterface() {}
+ virtual ~QAccessibleValueInterface();
virtual QVariant currentValue() const = 0;
virtual void setCurrentValue(const QVariant &value) = 0;
@@ -570,7 +569,7 @@ public:
class Q_GUI_EXPORT QAccessibleTableCellInterface
{
public:
- virtual ~QAccessibleTableCellInterface() {}
+ virtual ~QAccessibleTableCellInterface();
virtual bool isSelected() const = 0;
@@ -587,7 +586,7 @@ public:
class Q_GUI_EXPORT QAccessibleTableInterface
{
public:
- virtual ~QAccessibleTableInterface() {}
+ virtual ~QAccessibleTableInterface();
virtual QAccessibleInterface *caption() const = 0;
virtual QAccessibleInterface *summary() const = 0;
@@ -622,7 +621,7 @@ class Q_GUI_EXPORT QAccessibleActionInterface
{
Q_DECLARE_TR_FUNCTIONS(QAccessibleActionInterface)
public:
- virtual ~QAccessibleActionInterface() {}
+ virtual ~QAccessibleActionInterface();
virtual QStringList actionNames() const = 0;
virtual QString localizedActionName(const QString &name) const;
@@ -647,7 +646,7 @@ public:
class Q_GUI_EXPORT QAccessibleImageInterface
{
public:
- virtual ~QAccessibleImageInterface() {}
+ virtual ~QAccessibleImageInterface();
virtual QString imageDescription() const = 0;
virtual QSize imageSize() const = 0;
@@ -677,7 +676,7 @@ public:
}
inline QAccessibleEvent(QAccessibleInterface *iface, QAccessible::Event typ)
- : m_type(typ), m_object(0)
+ : m_type(typ), m_object(Q_NULLPTR)
{
Q_ASSERT(iface);
Q_ASSERT(m_type != QAccessible::ValueChanged);
@@ -691,8 +690,7 @@ public:
m_uniqueId = QAccessible::uniqueId(iface);
}
- virtual ~QAccessibleEvent()
- {}
+ virtual ~QAccessibleEvent();
QAccessible::Event type() const { return m_type; }
QObject *object() const { return m_object; }
@@ -726,6 +724,7 @@ public:
{
m_type = QAccessible::StateChanged;
}
+ ~QAccessibleStateChangeEvent();
QAccessible::State changedStates() const {
return m_changedStates;
@@ -752,6 +751,8 @@ public:
m_type = QAccessible::TextCaretMoved;
}
+ ~QAccessibleTextCursorEvent();
+
void setCursorPosition(int position) { m_cursorPosition = position; }
int cursorPosition() const { return m_cursorPosition; }
@@ -776,6 +777,8 @@ public:
m_type = QAccessible::TextSelectionChanged;
}
+ ~QAccessibleTextSelectionEvent();
+
void setSelection(int start, int end) {
m_selectionStart = start;
m_selectionEnd = end;
@@ -805,6 +808,8 @@ public:
m_type = QAccessible::TextInserted;
}
+ ~QAccessibleTextInsertEvent();
+
QString textInserted() const {
return m_text;
}
@@ -833,6 +838,8 @@ public:
m_type = QAccessible::TextRemoved;
}
+ ~QAccessibleTextRemoveEvent();
+
QString textRemoved() const {
return m_text;
}
@@ -860,6 +867,9 @@ public:
{
m_type = QAccessible::TextUpdated;
}
+
+ ~QAccessibleTextUpdateEvent();
+
QString textRemoved() const {
return m_oldText;
}
@@ -892,6 +902,8 @@ public:
m_type = QAccessible::ValueChanged;
}
+ ~QAccessibleValueChangeEvent();
+
void setValue(const QVariant & val) { m_value= val; }
QVariant value() const { return m_value; }
@@ -926,6 +938,8 @@ public:
m_type = QAccessible::TableModelChanged;
}
+ ~QAccessibleTableModelChangeEvent();
+
void setModelChangeType(ModelChangeType changeType) { m_modelChangeType = changeType; }
ModelChangeType modelChangeType() const { return m_modelChangeType; }
diff --git a/src/gui/accessible/qaccessiblebridge.h b/src/gui/accessible/qaccessiblebridge.h
index f0df5e1f39..277a8d201b 100644
--- a/src/gui/accessible/qaccessiblebridge.h
+++ b/src/gui/accessible/qaccessiblebridge.h
@@ -59,7 +59,7 @@ class Q_GUI_EXPORT QAccessibleBridgePlugin : public QObject
{
Q_OBJECT
public:
- explicit QAccessibleBridgePlugin(QObject *parent = 0);
+ explicit QAccessibleBridgePlugin(QObject *parent = Q_NULLPTR);
~QAccessibleBridgePlugin();
virtual QAccessibleBridge *create(const QString &key) = 0;
diff --git a/src/gui/accessible/qaccessibleplugin.h b/src/gui/accessible/qaccessibleplugin.h
index a4b782af11..44261788c7 100644
--- a/src/gui/accessible/qaccessibleplugin.h
+++ b/src/gui/accessible/qaccessibleplugin.h
@@ -53,7 +53,7 @@ class Q_GUI_EXPORT QAccessiblePlugin : public QObject
{
Q_OBJECT
public:
- explicit QAccessiblePlugin(QObject *parent = 0);
+ explicit QAccessiblePlugin(QObject *parent = Q_NULLPTR);
~QAccessiblePlugin();
virtual QAccessibleInterface *create(const QString &key, QObject *object) = 0;
diff --git a/src/gui/doc/qtgui.qdocconf b/src/gui/doc/qtgui.qdocconf
index 436e2e0b34..e34347b801 100644
--- a/src/gui/doc/qtgui.qdocconf
+++ b/src/gui/doc/qtgui.qdocconf
@@ -4,7 +4,7 @@ project = QtGui
description = Qt GUI Reference Documentation
version = $QT_VERSION
-examplesinstallpath = gui
+examplesinstallpath = qtbase/gui
qhp.projects = QtGui
diff --git a/src/gui/doc/snippets/qfileopenevent/Info.plist b/src/gui/doc/snippets/qfileopenevent/Info.plist
new file mode 100644
index 0000000000..6b8039bc7d
--- /dev/null
+++ b/src/gui/doc/snippets/qfileopenevent/Info.plist
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Samuel Gaist <samuel.gaist@edeltech.ch>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [Custom Info.plist]
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDocumentTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>png</string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ </dict>
+ </array>
+</dict>
+</plist>
+//! [Custom Info.plist] \ No newline at end of file
diff --git a/src/gui/doc/snippets/qfileopenevent/main.cpp b/src/gui/doc/snippets/qfileopenevent/main.cpp
new file mode 100644
index 0000000000..3fd1757bd7
--- /dev/null
+++ b/src/gui/doc/snippets/qfileopenevent/main.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Samuel Gaist <samuel.gaist@edeltech.ch>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [QApplication subclass]
+#include <QApplication>
+#include <QFileOpenEvent>
+#include <QtDebug>
+
+class MyApplication : public QApplication
+{
+public:
+ MyApplication(int &argc, char **argv)
+ : QApplication(argc, argv)
+ {
+ }
+
+ bool event(QEvent *event)
+ {
+ if (event->type() == QEvent::FileOpen) {
+ QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(event);
+ qDebug() << "Open file" << openEvent->file();
+ }
+
+ return QApplication::event(event);
+ }
+};
+//! [QApplication subclass]
+
+int main(int argc, char *argv[])
+{
+ MyApplication app(argc, argv);
+ QPushButton closeButton("Quit");
+ QObject::connect(&closeButton, &QPushButton::clicked, &app, &QApplication::quit);
+ closeButton.show();
+ return app.exec();
+}
diff --git a/src/gui/doc/snippets/qfontdatabase/main.cpp b/src/gui/doc/snippets/qfontdatabase/main.cpp
index e33ad5f539..aacd6f47fa 100644
--- a/src/gui/doc/snippets/qfontdatabase/main.cpp
+++ b/src/gui/doc/snippets/qfontdatabase/main.cpp
@@ -60,7 +60,7 @@ int main(int argc, char **argv)
QString sizes;
foreach (int points, database.smoothSizes(family, style))
- sizes += QString::number(points) + " ";
+ sizes += QString::number(points) + ' ';
styleItem->setText(1, sizes.trimmed());
}
diff --git a/src/gui/image/qbitmap.h b/src/gui/image/qbitmap.h
index f3ad90be20..be693af1cf 100644
--- a/src/gui/image/qbitmap.h
+++ b/src/gui/image/qbitmap.h
@@ -48,7 +48,7 @@ public:
QBitmap(const QPixmap &);
QBitmap(int w, int h);
explicit QBitmap(const QSize &);
- explicit QBitmap(const QString &fileName, const char *format=0);
+ explicit QBitmap(const QString &fileName, const char *format = Q_NULLPTR);
~QBitmap();
QBitmap &operator=(const QPixmap &);
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp
index 66bb77795e..d9e1347e4b 100644
--- a/src/gui/image/qicon.cpp
+++ b/src/gui/image/qicon.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com>
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -45,11 +46,7 @@
#include "qcache.h"
#include "qdebug.h"
#include "qpalette.h"
-
-#ifdef Q_DEAD_CODE_FROM_QT4_MAC
-#include <private/qt_mac_p.h>
-#include <private/qt_cocoa_helpers_mac_p.h>
-#endif
+#include "qmath.h"
#include "private/qhexstring_p.h"
#include "private/qguiapplication_p.h"
@@ -134,7 +131,8 @@ static qreal qt_effective_device_pixel_ratio(QWindow *window = 0)
QIconPrivate::QIconPrivate()
: engine(0), ref(1),
serialNum(serialNumCounter.fetchAndAddRelaxed(1)),
- detach_no(0)
+ detach_no(0),
+ is_mask(false)
{
}
@@ -362,7 +360,7 @@ static inline int origIcoDepth(const QImage &image)
return s.isEmpty() ? 32 : s.toInt();
}
-static inline int findBySize(const QList<QImage> &images, const QSize &size)
+static inline int findBySize(const QVector<QImage> &images, const QSize &size)
{
for (int i = 0; i < images.size(); ++i) {
if (images.at(i).size() == size)
@@ -426,7 +424,7 @@ void QPixmapIconEngine::addFile(const QString &fileName, const QSize &size, QIco
// these files may contain low-resolution images. As this information is lost,
// ICOReader sets the original format as an image text key value. Read all matching
// images into a list trying to find the highest quality per size.
- QList<QImage> icoImages;
+ QVector<QImage> icoImages;
while (imageReader.read(&image)) {
if (ignoreSize || image.size() == size) {
const int position = findBySize(icoImages, image.size());
@@ -599,6 +597,8 @@ QFactoryLoader *qt_iconEngineFactoryLoader()
\image icon.png QIcon
+ \note QIcon needs a QGuiApplication instance before the icon is created.
+
\sa {fowler}{GUI Design Handbook: Iconic Label}, {Icons Example}
*/
@@ -1028,19 +1028,13 @@ void QIcon::addFile(const QString &fileName, const QSize &size, Mode mode, State
} else {
detach();
}
+
d->engine->addFile(fileName, size, mode, state);
- // Check if a "@2x" file exists and add it.
- static bool disable2xImageLoading = !qEnvironmentVariableIsEmpty("QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING");
- if (!disable2xImageLoading && qApp->devicePixelRatio() > 1.0) {
- QString at2xfileName = fileName;
- int dotIndex = fileName.lastIndexOf(QLatin1Char('.'));
- if (dotIndex == -1) /* no dot */
- dotIndex = fileName.size(); /* append */
- at2xfileName.insert(dotIndex, QStringLiteral("@2x"));
- if (QFile::exists(at2xfileName))
- d->engine->addFile(at2xfileName, size, mode, state);
- }
+ // Check if a "@Nx" file exists and add it.
+ QString atNxFileName = qt_findAtNxFile(fileName, qApp->devicePixelRatio());
+ if (atNxFileName != fileName)
+ d->engine->addFile(atNxFileName, size, mode, state);
}
/*!
@@ -1185,8 +1179,6 @@ QIcon QIcon::fromTheme(const QString &name, const QIcon &fallback)
qtIconCache()->insert(name, cachedIcon);
}
- // Note the qapp check is to allow lazy loading of static icons
- // Supporting fallbacks will not work for this case.
if (qApp && icon.availableSizes().isEmpty())
return fallback;
@@ -1208,6 +1200,39 @@ bool QIcon::hasThemeIcon(const QString &name)
return icon.name() == name;
}
+/*!
+ \since 5.6
+
+ Indicate that this icon is a mask image, and hence can potentially
+ be modified based on where it's displayed.
+ \sa isMask()
+*/
+void QIcon::setIsMask(bool isMask)
+{
+ if (!d) {
+ d = new QIconPrivate;
+ d->engine = new QPixmapIconEngine;
+ } else {
+ detach();
+ }
+ d->is_mask = isMask;
+}
+
+/*!
+ \since 5.6
+
+ Returns \c true if this icon has been marked as a mask image.
+ Certain platforms render mask icons differently (for example,
+ menu icons on OS X).
+
+ \sa setIsMask()
+*/
+bool QIcon::isMask() const
+{
+ if (!d)
+ return false;
+ return d->is_mask;
+}
/*****************************************************************************
QIcon stream functions
@@ -1354,5 +1379,46 @@ QDebug operator<<(QDebug dbg, const QIcon &i)
\internal
*/
+/*!
+ \internal
+ \since 5.6
+ Attempts to find a suitable @Nx file for the given \a targetDevicePixelRatio
+ Returns the the \a baseFileName if no such file was found.
+
+ Given base foo.png and a target dpr of 2.5, this function will look for
+ foo@3x.png, then foo@2x, then fall back to foo.png if not found.
+
+ \a sourceDevicePixelRatio will be set to the value of N if the argument is
+ a non-null pointer
+*/
+QString qt_findAtNxFile(const QString &baseFileName, qreal targetDevicePixelRatio,
+ qreal *sourceDevicePixelRatio)
+{
+ if (targetDevicePixelRatio <= 1.0)
+ return baseFileName;
+
+ static bool disableNxImageLoading = !qEnvironmentVariableIsEmpty("QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING");
+ if (disableNxImageLoading)
+ return baseFileName;
+
+ int dotIndex = baseFileName.lastIndexOf(QLatin1Char('.'));
+ if (dotIndex == -1) /* no dot */
+ dotIndex = baseFileName.size(); /* append */
+
+ QString atNxfileName = baseFileName;
+ atNxfileName.insert(dotIndex, QLatin1String("@2x"));
+ // Check for @Nx, ..., @3x, @2x file versions,
+ for (int n = qMin(qCeil(targetDevicePixelRatio), 9); n > 1; --n) {
+ atNxfileName[dotIndex + 1] = QLatin1Char('0' + n);
+ if (QFile::exists(atNxfileName)) {
+ if (sourceDevicePixelRatio)
+ *sourceDevicePixelRatio = n;
+ return atNxfileName;
+ }
+ }
+
+ return baseFileName;
+}
+
QT_END_NAMESPACE
#endif //QT_NO_ICON
diff --git a/src/gui/image/qicon.h b/src/gui/image/qicon.h
index 63e77eef99..9ed7336502 100644
--- a/src/gui/image/qicon.h
+++ b/src/gui/image/qicon.h
@@ -56,8 +56,8 @@ public:
QIcon(const QIcon &other);
#ifdef Q_COMPILER_RVALUE_REFS
QIcon(QIcon &&other) Q_DECL_NOEXCEPT
- : d(0)
- { qSwap(d, other.d); }
+ : d(other.d)
+ { other.d = Q_NULLPTR; }
#endif
explicit QIcon(const QString &fileName); // file or resource name
explicit QIcon(QIconEngine *engine);
@@ -65,7 +65,7 @@ public:
QIcon &operator=(const QIcon &other);
#ifdef Q_COMPILER_RVALUE_REFS
inline QIcon &operator=(QIcon &&other) Q_DECL_NOEXCEPT
- { qSwap(d, other.d); return *this; }
+ { swap(other); return *this; }
#endif
inline void swap(QIcon &other) Q_DECL_NOEXCEPT
{ qSwap(d, other.d); }
@@ -102,6 +102,9 @@ public:
QList<QSize> availableSizes(Mode mode = Normal, State state = Off) const;
+ void setIsMask(bool isMask);
+ bool isMask() const;
+
static QIcon fromTheme(const QString &name, const QIcon &fallback = QIcon());
static bool hasThemeIcon(const QString &name);
@@ -136,6 +139,9 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QIcon &);
Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QIcon &);
#endif
+Q_GUI_EXPORT QString qt_findAtNxFile(const QString &baseFileName, qreal targetDevicePixelRatio,
+ qreal *sourceDevicePixelRatio = Q_NULLPTR);
+
QT_END_NAMESPACE
#endif // QICON_H
diff --git a/src/gui/image/qicon_p.h b/src/gui/image/qicon_p.h
index 8b42e770fa..2a4f584a0d 100644
--- a/src/gui/image/qicon_p.h
+++ b/src/gui/image/qicon_p.h
@@ -71,6 +71,7 @@ public:
QAtomicInt ref;
int serialNum;
int detach_no;
+ bool is_mask;
};
diff --git a/src/gui/image/qiconengine.cpp b/src/gui/image/qiconengine.cpp
index a25b216432..c09933d45f 100644
--- a/src/gui/image/qiconengine.cpp
+++ b/src/gui/image/qiconengine.cpp
@@ -77,6 +77,13 @@ QSize QIconEngine::actualSize(const QSize &size, QIcon::Mode /*mode*/, QIcon::St
return size;
}
+/*!
+ \since 5.6
+ Constructs the icon engine.
+ */
+QIconEngine::QIconEngine()
+{
+}
/*!
Destroys the icon engine.
diff --git a/src/gui/image/qiconengine.h b/src/gui/image/qiconengine.h
index 735da863fd..9977113054 100644
--- a/src/gui/image/qiconengine.h
+++ b/src/gui/image/qiconengine.h
@@ -44,6 +44,7 @@ QT_BEGIN_NAMESPACE
class Q_GUI_EXPORT QIconEngine
{
public:
+ QIconEngine();
virtual ~QIconEngine();
virtual void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) = 0;
virtual QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state);
diff --git a/src/gui/image/qiconengineplugin.h b/src/gui/image/qiconengineplugin.h
index 66684c871d..b05969f283 100644
--- a/src/gui/image/qiconengineplugin.h
+++ b/src/gui/image/qiconengineplugin.h
@@ -48,7 +48,7 @@ class Q_GUI_EXPORT QIconEnginePlugin : public QObject
{
Q_OBJECT
public:
- QIconEnginePlugin(QObject *parent = 0);
+ QIconEnginePlugin(QObject *parent = Q_NULLPTR);
~QIconEnginePlugin();
virtual QIconEngine *create(const QString &filename = QString()) = 0;
diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp
index fa14c84e83..3ead72dfbb 100644
--- a/src/gui/image/qiconloader.cpp
+++ b/src/gui/image/qiconloader.cpp
@@ -42,15 +42,10 @@
#include <QtGui/QIconEngine>
#include <QtGui/QPalette>
#include <QtCore/QList>
-#include <QtCore/QHash>
#include <QtCore/QDir>
#include <QtCore/QSettings>
#include <QtGui/QPainter>
-#ifdef Q_DEAD_CODE_FROM_QT4_MAC
-#include <private/qt_cocoa_helpers_mac_p.h>
-#endif
-
#include <private/qhexstring_p.h>
QT_BEGIN_NAMESPACE
@@ -73,9 +68,6 @@ QIconLoader::QIconLoader() :
{
}
-// We lazily initialize the loader to make static icons
-// work. Though we do not officially support this.
-
static inline QString systemThemeName()
{
if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
@@ -398,9 +390,6 @@ void QIconLoaderEngine::paint(QPainter *painter, const QRect &rect,
QIcon::Mode mode, QIcon::State state)
{
QSize pixmapSize = rect.size();
-#if defined(Q_DEAD_CODE_FROM_QT4_MAC)
- pixmapSize *= qt_mac_get_scalefactor();
-#endif
painter->drawPixmap(rect, pixmap(pixmapSize, mode, state));
}
diff --git a/src/gui/image/qiconloader_p.h b/src/gui/image/qiconloader_p.h
index 5b0362e218..ccf0a9d438 100644
--- a/src/gui/image/qiconloader_p.h
+++ b/src/gui/image/qiconloader_p.h
@@ -76,7 +76,7 @@ struct QIconDirInfo
short maxSize;
short minSize;
short threshold;
- Type type : 4;
+ Type type;
};
Q_DECLARE_TYPEINFO(QIconDirInfo, Q_MOVABLE_TYPE);
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 01cacad630..667b65431e 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -491,6 +491,10 @@ bool QImageData::checkForAlphaPixels() const
\snippet code/src_gui_image_qimage.cpp 1
\endtable
+ For images with more than 8-bit per color-channel. The methods
+ setPixelColor() and pixelColor() can be used to set and get
+ with QColor values.
+
QImage also provide the scanLine() function which returns a
pointer to the pixel data at the scanline with the given index,
and the bits() function which returns a pointer to the first pixel
@@ -1785,11 +1789,11 @@ void QImage::fill(const QColor &color)
break;
case QImage::Format_BGR30:
case QImage::Format_A2BGR30_Premultiplied:
- fill(qConvertArgb32ToA2rgb30<PixelOrderBGR>(color.rgba()));
+ fill(qConvertRgb64ToRgb30<PixelOrderBGR>(color.rgba64()));
break;
case QImage::Format_RGB30:
case QImage::Format_A2RGB30_Premultiplied:
- fill(qConvertArgb32ToA2rgb30<PixelOrderRGB>(color.rgba()));
+ fill(qConvertRgb64ToRgb30<PixelOrderRGB>(color.rgba64()));
break;
case QImage::Format_RGB16:
fill((uint) qConvertRgb32To16(color.rgba()));
@@ -2206,9 +2210,10 @@ int QImage::pixelIndex(int x, int y) const
If the \a position is not valid, the results are undefined.
\warning This function is expensive when used for massive pixel
- manipulations.
+ manipulations. Use constBits() or constScanLine() when many
+ pixels needs to be read.
- \sa setPixel(), valid(), {QImage#Pixel Manipulation}{Pixel
+ \sa setPixel(), valid(), constBits(), constScanLine(), {QImage#Pixel Manipulation}{Pixel
Manipulation}
*/
@@ -2219,12 +2224,12 @@ int QImage::pixelIndex(int x, int y) const
*/
QRgb QImage::pixel(int x, int y) const
{
- if (!d || x < 0 || x >= d->width || y < 0 || y >= height()) {
+ if (!d || x < 0 || x >= d->width || y < 0 || y >= d->height) {
qWarning("QImage::pixel: coordinate (%d,%d) out of range", x, y);
return 12345;
}
- const uchar * s = constScanLine(y);
+ const uchar *s = d->data + y * d->bytes_per_line;
switch(d->format) {
case Format_Mono:
return d->colortable.at((*(s + (x >> 3)) >> (~x & 7)) & 1);
@@ -2258,25 +2263,23 @@ QRgb QImage::pixel(int x, int y) const
return *layout->convertToARGB32PM(&result, ptr, 1, layout, 0);
}
-
/*!
\fn void QImage::setPixel(const QPoint &position, uint index_or_rgb)
Sets the pixel index or color at the given \a position to \a
index_or_rgb.
- If the image's format is either monochrome or 8-bit, the given \a
+ If the image's format is either monochrome or paletted, the given \a
index_or_rgb value must be an index in the image's color table,
otherwise the parameter must be a QRgb value.
If \a position is not a valid coordinate pair in the image, or if
\a index_or_rgb >= colorCount() in the case of monochrome and
- 8-bit images, the result is undefined.
+ paletted images, the result is undefined.
\warning This function is expensive due to the call of the internal
\c{detach()} function called within; if performance is a concern, we
- recommend the use of \l{QImage::}{scanLine()} to access pixel data
- directly.
+ recommend the use of scanLine() or bits() to access pixel data directly.
\sa pixel(), {QImage#Pixel Manipulation}{Pixel Manipulation}
*/
@@ -2364,6 +2367,116 @@ void QImage::setPixel(int x, int y, uint index_or_rgb)
}
/*!
+ \fn QColor QImage::pixelColor(const QPoint &position) const
+ \since 5.6
+
+ Returns the color of the pixel at the given \a position as a QColor.
+
+ If the \a position is not valid, an invalid QColor is returned.
+
+ \warning This function is expensive when used for massive pixel
+ manipulations. Use constBits() or constScanLine() when many
+ pixels needs to be read.
+
+ \sa setPixel(), valid(), constBits(), constScanLine(), {QImage#Pixel Manipulation}{Pixel
+ Manipulation}
+*/
+
+/*!
+ \overload
+ \since 5.6
+
+ Returns the color of the pixel at coordinates (\a x, \a y) as a QColor.
+*/
+QColor QImage::pixelColor(int x, int y) const
+{
+ if (!d || x < 0 || x >= d->width || y < 0 || y >= height()) {
+ qWarning("QImage::pixelColor: coordinate (%d,%d) out of range", x, y);
+ return QColor();
+ }
+
+ QRgba64 c;
+ const uchar * s = constScanLine(y);
+ switch (d->format) {
+ case Format_BGR30:
+ case Format_A2BGR30_Premultiplied:
+ c = qConvertA2rgb30ToRgb64<PixelOrderBGR>(reinterpret_cast<const quint32 *>(s)[x]);
+ break;
+ case Format_RGB30:
+ case Format_A2RGB30_Premultiplied:
+ c = qConvertA2rgb30ToRgb64<PixelOrderRGB>(reinterpret_cast<const quint32 *>(s)[x]);
+ break;
+ default:
+ c = QRgba64::fromArgb32(pixel(x, y));
+ break;
+ }
+ // QColor is always unpremultiplied
+ if (hasAlphaChannel() && qPixelLayouts[d->format].premultiplied)
+ c = c.unpremultiplied();
+ return QColor(c);
+}
+
+/*!
+ \fn void QImage::setPixelColor(const QPoint &position, const QColor &color)
+ \since 5.6
+
+ Sets the color at the given \a position to \a color.
+
+ If \a position is not a valid coordinate pair in the image, or
+ the image's format is either monochrome or paletted, the result is undefined.
+
+ \warning This function is expensive due to the call of the internal
+ \c{detach()} function called within; if performance is a concern, we
+ recommend the use of scanLine() or bits() to access pixel data directly.
+
+ \sa pixel(), bits(), scanLine(), {QImage#Pixel Manipulation}{Pixel Manipulation}
+*/
+
+/*!
+ \overload
+ \since 5.6
+
+ Sets the pixel color at (\a x, \a y) to \a color.
+*/
+void QImage::setPixelColor(int x, int y, const QColor &color)
+{
+ if (!d || x < 0 || x >= width() || y < 0 || y >= height() || !color.isValid()) {
+ qWarning("QImage::setPixelColor: coordinate (%d,%d) out of range", x, y);
+ return;
+ }
+ // QColor is always unpremultiplied
+ QRgba64 c = color.rgba64();
+ if (!hasAlphaChannel())
+ c.setAlpha(65535);
+ else if (qPixelLayouts[d->format].premultiplied)
+ c = c.premultiplied();
+ // detach is called from within scanLine
+ uchar * s = scanLine(y);
+ switch (d->format) {
+ case Format_Mono:
+ case Format_MonoLSB:
+ case Format_Indexed8:
+ qWarning("QImage::setPixelColor: called on monochrome or indexed format");
+ return;
+ case Format_BGR30:
+ ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderBGR>(c) | 0xc0000000;
+ return;
+ case Format_A2BGR30_Premultiplied:
+ ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderBGR>(c);
+ return;
+ case Format_RGB30:
+ ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderRGB>(c) | 0xc0000000;
+ return;
+ case Format_A2RGB30_Premultiplied:
+ ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderRGB>(c);
+ return;
+ default:
+ setPixel(x, y, c.toArgb32());
+ return;
+ }
+}
+
+/*!
Returns \c true if all the colors in the image are shades of gray
(i.e. their red, green and blue components are equal); otherwise
false.
@@ -3808,6 +3921,10 @@ int QImage::metric(PaintDeviceMetric metric) const
return d->devicePixelRatio;
break;
+ case PdmDevicePixelRatioScaled:
+ return d->devicePixelRatio * QPaintDevice::devicePixelRatioFScale();
+ break;
+
default:
qWarning("QImage::metric(): Unhandled metric type %d", metric);
break;
@@ -4521,32 +4638,7 @@ QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode
if (complex_xform || mode == Qt::SmoothTransformation) {
if (d->format < QImage::Format_RGB32 || !hasAlphaChannel()) {
- switch(d->format) {
- case QImage::Format_RGB16:
- target_format = Format_ARGB8565_Premultiplied;
- break;
- case QImage::Format_RGB555:
- target_format = Format_ARGB8555_Premultiplied;
- break;
- case QImage::Format_RGB666:
- target_format = Format_ARGB6666_Premultiplied;
- break;
- case QImage::Format_RGB444:
- target_format = Format_ARGB4444_Premultiplied;
- break;
- case QImage::Format_RGBX8888:
- target_format = Format_RGBA8888_Premultiplied;
- break;
- case QImage::Format_BGR30:
- target_format = Format_A2BGR30_Premultiplied;
- break;
- case QImage::Format_RGB30:
- target_format = Format_A2RGB30_Premultiplied;
- break;
- default:
- target_format = Format_ARGB32_Premultiplied;
- break;
- }
+ target_format = qt_alphaVersion(d->format);
}
}
diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h
index 26057f366c..888c7beb32 100644
--- a/src/gui/image/qimage.h
+++ b/src/gui/image/qimage.h
@@ -34,10 +34,11 @@
#ifndef QIMAGE_H
#define QIMAGE_H
-#include <QtGui/qtransform.h>
-#include <QtGui/qpaintdevice.h>
+#include <QtGui/qcolor.h>
#include <QtGui/qrgb.h>
+#include <QtGui/qpaintdevice.h>
#include <QtGui/qpixelformat.h>
+#include <QtGui/qtransform.h>
#include <QtCore/qbytearray.h>
#include <QtCore/qrect.h>
#include <QtCore/qstring.h>
@@ -124,15 +125,15 @@ public:
QImage() Q_DECL_NOEXCEPT;
QImage(const QSize &size, Format format);
QImage(int width, int height, Format format);
- QImage(uchar *data, int width, int height, Format format, QImageCleanupFunction cleanupFunction = 0, void *cleanupInfo = 0);
- QImage(const uchar *data, int width, int height, Format format, QImageCleanupFunction cleanupFunction = 0, void *cleanupInfo = 0);
- QImage(uchar *data, int width, int height, int bytesPerLine, Format format, QImageCleanupFunction cleanupFunction = 0, void *cleanupInfo = 0);
- QImage(const uchar *data, int width, int height, int bytesPerLine, Format format, QImageCleanupFunction cleanupFunction = 0, void *cleanupInfo = 0);
+ QImage(uchar *data, int width, int height, Format format, QImageCleanupFunction cleanupFunction = Q_NULLPTR, void *cleanupInfo = Q_NULLPTR);
+ QImage(const uchar *data, int width, int height, Format format, QImageCleanupFunction cleanupFunction = Q_NULLPTR, void *cleanupInfo = Q_NULLPTR);
+ QImage(uchar *data, int width, int height, int bytesPerLine, Format format, QImageCleanupFunction cleanupFunction = Q_NULLPTR, void *cleanupInfo = Q_NULLPTR);
+ QImage(const uchar *data, int width, int height, int bytesPerLine, Format format, QImageCleanupFunction cleanupFunction = Q_NULLPTR, void *cleanupInfo = Q_NULLPTR);
#ifndef QT_NO_IMAGEFORMAT_XPM
explicit QImage(const char * const xpm[]);
#endif
- explicit QImage(const QString &fileName, const char *format = 0);
+ explicit QImage(const QString &fileName, const char *format = Q_NULLPTR);
QImage(const QImage &);
#ifdef Q_COMPILER_RVALUE_REFS
@@ -220,6 +221,12 @@ public:
void setPixel(int x, int y, uint index_or_rgb);
void setPixel(const QPoint &pt, uint index_or_rgb);
+ QColor pixelColor(int x, int y) const;
+ QColor pixelColor(const QPoint &pt) const;
+
+ void setPixelColor(int x, int y, const QColor &c);
+ void setPixelColor(const QPoint &pt, const QColor &c);
+
QVector<QRgb> colorTable() const;
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
void setColorTable(const QVector<QRgb> &colors);
@@ -272,16 +279,16 @@ public:
bool load(QIODevice *device, const char* format);
- bool load(const QString &fileName, const char* format=0);
- bool loadFromData(const uchar *buf, int len, const char *format = 0);
- inline bool loadFromData(const QByteArray &data, const char* aformat=0)
+ bool load(const QString &fileName, const char *format = Q_NULLPTR);
+ bool loadFromData(const uchar *buf, int len, const char *format = Q_NULLPTR);
+ inline bool loadFromData(const QByteArray &data, const char *aformat = Q_NULLPTR)
{ return loadFromData(reinterpret_cast<const uchar *>(data.constData()), data.size(), aformat); }
- bool save(const QString &fileName, const char* format=0, int quality=-1) const;
- bool save(QIODevice *device, const char* format=0, int quality=-1) const;
+ bool save(const QString &fileName, const char *format = Q_NULLPTR, int quality = -1) const;
+ bool save(QIODevice *device, const char *format = Q_NULLPTR, int quality = -1) const;
- static QImage fromData(const uchar *data, int size, const char *format = 0);
- inline static QImage fromData(const QByteArray &data, const char *format = 0)
+ static QImage fromData(const uchar *data, int size, const char *format = Q_NULLPTR);
+ inline static QImage fromData(const QByteArray &data, const char *format = Q_NULLPTR)
{ return fromData(reinterpret_cast<const uchar *>(data.constData()), data.size(), format); }
#if QT_DEPRECATED_SINCE(5, 0)
@@ -352,6 +359,8 @@ inline bool QImage::valid(const QPoint &pt) const { return valid(pt.x(), pt.y())
inline int QImage::pixelIndex(const QPoint &pt) const { return pixelIndex(pt.x(), pt.y());}
inline QRgb QImage::pixel(const QPoint &pt) const { return pixel(pt.x(), pt.y()); }
inline void QImage::setPixel(const QPoint &pt, uint index_or_rgb) { setPixel(pt.x(), pt.y(), index_or_rgb); }
+inline QColor QImage::pixelColor(const QPoint &pt) const { return pixelColor(pt.x(), pt.y()); }
+inline void QImage::setPixelColor(const QPoint &pt, const QColor &c) { setPixelColor(pt.x(), pt.y(), c); }
#if QT_DEPRECATED_SINCE(5, 0)
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp
index 02f32aa34b..cc79e73534 100644
--- a/src/gui/image/qimage_conversions.cpp
+++ b/src/gui/image/qimage_conversions.cpp
@@ -375,7 +375,32 @@ static void convert_RGB888_to_RGB(QImageData *dest, const QImageData *src, Qt::I
}
}
+#ifdef __SSE2__
extern bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionFlags);
+#else
+static bool convert_ARGB_to_ARGB_PM_inplace(QImageData *data,Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_ARGB32 || data->format == QImage::Format_RGBA8888);
+
+ const int pad = (data->bytes_per_line >> 2) - data->width;
+ QRgb *rgb_data = (QRgb *) data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ const QRgb *end = rgb_data + data->width;
+ while (rgb_data < end) {
+ *rgb_data = qPremultiply(*rgb_data);
+ ++rgb_data;
+ }
+ rgb_data += pad;
+ }
+
+ if (data->format == QImage::Format_ARGB32)
+ data->format = QImage::Format_ARGB32_Premultiplied;
+ else
+ data->format = QImage::Format_RGBA8888_Premultiplied;
+ return true;
+}
+#endif
static void convert_ARGB_to_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
@@ -2592,7 +2617,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
#ifdef __SSE2__
convert_ARGB_to_ARGB_PM_inplace_sse2,
#else
- 0,
+ convert_ARGB_to_ARGB_PM_inplace,
#endif
0,
0,
@@ -2705,12 +2730,13 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
mask_alpha_converter_rgbx_inplace,
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN && __SSE2__
0,
+#ifdef __SSE2__
convert_ARGB_to_ARGB_PM_inplace_sse2,
+#elif Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ convert_ARGB_to_ARGB_PM_inplace,
#else
0,
- 0,
#endif
0, 0, 0, 0, 0, 0
}, // Format_RGBA8888
@@ -2894,7 +2920,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
} // Format_Grayscale8
};
-void qInitImageConversions()
+static void qInitImageConversions()
{
#if defined(__SSE2__) && defined(QT_COMPILER_SUPPORTS_SSSE3)
if (qCpuHasFeature(SSSE3)) {
@@ -2921,7 +2947,7 @@ void qInitImageConversions()
}
#endif
-#if defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64)
+#if defined(__ARM_NEON__)
extern void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
qimage_converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_neon;
qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_neon;
@@ -2941,4 +2967,6 @@ void qInitImageConversions()
#endif
}
+Q_CONSTRUCTOR_FUNCTION(qInitImageConversions);
+
QT_END_NAMESPACE
diff --git a/src/gui/image/qimage_neon.cpp b/src/gui/image/qimage_neon.cpp
index b51c43aa9d..5853510ee1 100644
--- a/src/gui/image/qimage_neon.cpp
+++ b/src/gui/image/qimage_neon.cpp
@@ -35,7 +35,7 @@
#include <private/qimage_p.h>
#include <private/qsimd_p.h>
-#if defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64)
+#if defined(__ARM_NEON__)
QT_BEGIN_NAMESPACE
@@ -55,6 +55,7 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, cons
if ((len - offsetToAlignOn8Bytes) >= 8) {
const quint32 *const simdEnd = end - 7;
+#if !defined(Q_PROCESSOR_ARM_64)
register uint8x8_t fullVector asm ("d3") = vdup_n_u8(0xff);
do {
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
@@ -76,6 +77,31 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, cons
);
#endif
} while (dst < simdEnd);
+#else
+ register uint8x8_t fullVector asm ("v3") = vdup_n_u8(0xff);
+ do {
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+ asm volatile (
+ "ld3 { v4.8b, v5.8b, v6.8b }, [%[SRC]], #24 \n\t"
+ "st4 { v3.8b, v4.8b, v5.8b, v6.8b }, [%[DST]], #32 \n\t"
+ : [DST]"+r" (dst), [SRC]"+r" (src)
+ : "w"(fullVector)
+ : "memory", "v4", "v5", "v6"
+ );
+#else
+ asm volatile (
+ "ld3 { v0.8b, v1.8b, v2.8b }, [%[SRC]], #24 \n\t"
+ "mov v4.8b, v2.8b\n\t"
+ "mov v2.8b, v0.8b\n\t"
+ "mov v0.8b, v4.8b\n\t"
+ "st4 { v0.8b, v1.8b, v2.8b, v3.8b }, [%[DST]], #32 \n\t"
+ : [DST]"+r" (dst), [SRC]"+r" (src)
+ : "w"(fullVector)
+ : "memory", "v0", "v1", "v2", "v4"
+ );
+#endif
+ } while (dst < simdEnd);
+#endif
}
while (dst != end) {
@@ -103,4 +129,4 @@ void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::I
QT_END_NAMESPACE
-#endif // defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64)
+#endif // defined(__ARM_NEON__)
diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h
index feeab60abd..f9ad6c0ac0 100644
--- a/src/gui/image/qimage_p.h
+++ b/src/gui/image/qimage_p.h
@@ -111,8 +111,6 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im
void dither_to_Mono(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags, bool fromalpha);
-void qInitImageConversions();
-
const uchar *qt_get_bitflip_array();
Q_GUI_EXPORT void qGamma_correct_back_to_linear_cs(QImage *image);
@@ -163,10 +161,45 @@ inline int qt_depthForFormat(QImage::Format format)
}
return depth;
}
+
#if defined(_M_ARM)
#pragma optimize("", on)
#endif
+inline QImage::Format qt_alphaVersion(QImage::Format format)
+{
+ switch (format) {
+ case QImage::Format_RGB16:
+ return QImage::Format_ARGB8565_Premultiplied;
+ case QImage::Format_RGB555:
+ return QImage::Format_ARGB8555_Premultiplied;
+ case QImage::Format_RGB666:
+ return QImage::Format_ARGB6666_Premultiplied;
+ case QImage::Format_RGB444:
+ return QImage::Format_ARGB4444_Premultiplied;
+ case QImage::Format_RGBX8888:
+ return QImage::Format_RGBA8888_Premultiplied;
+ case QImage::Format_BGR30:
+ return QImage::Format_A2BGR30_Premultiplied;
+ case QImage::Format_RGB30:
+ return QImage::Format_A2RGB30_Premultiplied;
+ default:
+ break;
+ }
+ return QImage::Format_ARGB32_Premultiplied;
+}
+
+inline QImage::Format qt_alphaVersionForPainting(QImage::Format format)
+{
+ QImage::Format toFormat = qt_alphaVersion(format);
+#if defined(__ARM_NEON__) || defined(__SSE2__)
+ // If we are switching depth anyway and we have optimized ARGB32PM routines, upgrade to that.
+ if (qt_depthForFormat(format) != qt_depthForFormat(toFormat))
+ toFormat = QImage::Format_ARGB32_Premultiplied;
+#endif
+ return toFormat;
+}
+
QT_END_NAMESPACE
#endif // QIMAGE_P_H
diff --git a/src/gui/image/qimageiohandler.h b/src/gui/image/qimageiohandler.h
index 80cd87c4c3..47a8a2b7c6 100644
--- a/src/gui/image/qimageiohandler.h
+++ b/src/gui/image/qimageiohandler.h
@@ -133,7 +133,7 @@ class Q_GUI_EXPORT QImageIOPlugin : public QObject
{
Q_OBJECT
public:
- explicit QImageIOPlugin(QObject *parent = 0);
+ explicit QImageIOPlugin(QObject *parent = Q_NULLPTR);
virtual ~QImageIOPlugin();
enum Capability {
diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index a35442308f..0ef587f333 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -252,7 +252,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
#ifdef QIMAGEREADER_DEBUG
qDebug() << "QImageReader::createReadHandler( device =" << (void *)device << ", format =" << format << "),"
- << keyMap.values().size() << "plugins available: " << keyMap.values();
+ << keyMap.size() << "plugins available: " << keyMap.values();
#endif
int suffixPluginIndex = -1;
@@ -312,7 +312,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
const qint64 pos = device ? device->pos() : 0;
if (autoDetectImageFormat) {
- const int keyCount = keyMap.keys().size();
+ const int keyCount = keyMap.size();
for (int i = 0; i < keyCount; ++i) {
if (i != suffixPluginIndex) {
QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(i));
@@ -392,7 +392,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
if (!handler && (autoDetectImageFormat || ignoresFormatAndExtension)) {
// check if any of our plugins recognize the file from its contents.
const qint64 pos = device ? device->pos() : 0;
- const int keyCount = keyMap.keys().size();
+ const int keyCount = keyMap.size();
for (int i = 0; i < keyCount; ++i) {
if (i != suffixPluginIndex) {
QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(i));
@@ -1168,7 +1168,8 @@ QImageIOHandler::Transformations QImageReader::transformation() const
/*!
\since 5.5
- Sets if images returned by read() should have transformation metadata automatically applied.
+ Determines that images returned by read() should have transformation metadata automatically
+ applied if \a enabled is \c true.
\sa autoTransform(), transformation(), read()
*/
@@ -1203,6 +1204,39 @@ bool QImageReader::autoTransform() const
}
/*!
+ \since 5.6
+
+ This is an image format specific function that forces images with
+ gamma information to be gamma corrected to \a gamma. For image formats
+ that do not support gamma correction, this value is ignored.
+
+ To gamma correct to a standard PC color-space, set gamma to \c 1/2.2.
+
+ \sa gamma()
+*/
+void QImageReader::setGamma(float gamma)
+{
+ if (d->initHandler() && d->handler->supportsOption(QImageIOHandler::Gamma))
+ d->handler->setOption(QImageIOHandler::Gamma, gamma);
+}
+
+/*!
+ \since 5.6
+
+ Returns the gamma level of the decoded image. If setGamma() has been
+ called and gamma correction is supported it will return the gamma set.
+ If gamma level is not supported by the image format, \c 0.0 is returned.
+
+ \sa setGamma()
+*/
+float QImageReader::gamma() const
+{
+ if (d->initHandler() && d->handler->supportsOption(QImageIOHandler::Gamma))
+ return d->handler->option(QImageIOHandler::Gamma).toFloat();
+ return 0.0;
+}
+
+/*!
Returns \c true if an image can be read for the device (i.e., the
image format is supported, and the device seems to contain valid
data); otherwise returns \c false.
diff --git a/src/gui/image/qimagereader.h b/src/gui/image/qimagereader.h
index 27a29bed49..6745c55b97 100644
--- a/src/gui/image/qimagereader.h
+++ b/src/gui/image/qimagereader.h
@@ -110,6 +110,9 @@ public:
void setAutoTransform(bool enabled);
bool autoTransform() const;
+ void setGamma(float gamma);
+ float gamma() const;
+
QByteArray subType() const;
QList<QByteArray> supportedSubTypes() const;
diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp
index e9de1db4b2..1cf75d8688 100644
--- a/src/gui/image/qimagewriter.cpp
+++ b/src/gui/image/qimagewriter.cpp
@@ -212,7 +212,7 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device,
#ifndef QT_NO_IMAGEFORMATPLUGIN
if (!testFormat.isEmpty()) {
- const int keyCount = keyMap.keys().size();
+ const int keyCount = keyMap.size();
for (int i = 0; i < keyCount; ++i) {
QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(i));
if (plugin && (plugin->capabilities(device, testFormat) & QImageIOPlugin::CanWrite)) {
@@ -621,7 +621,7 @@ bool QImageWriter::progressiveScanWrite() const
/*!
\since 5.5
- Sets the image transformations metadata including orientation.
+ Sets the image transformations metadata including orientation to \a transform.
If transformation metadata is not supported by the image format,
the transform is applied before writing.
diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp
index e29f9783a6..68709b708d 100644
--- a/src/gui/image/qjpeghandler.cpp
+++ b/src/gui/image/qjpeghandler.cpp
@@ -68,6 +68,7 @@ extern "C" {
}
QT_BEGIN_NAMESPACE
+QT_WARNING_DISABLE_GCC("-Wclobbered")
Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32(quint32 *dst, const uchar *src, int len);
typedef void (QT_FASTCALL *Rgb888ToRgb32Converter)(quint32 *dst, const uchar *src, int len);
@@ -977,9 +978,8 @@ extern "C" void qt_convert_rgb888_to_rgb32_mips_dspr2_asm(quint32 *dst, const uc
QJpegHandler::QJpegHandler()
: d(new QJpegHandlerPrivate(this))
{
-#if defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64)
+#if defined(__ARM_NEON__)
// from qimage_neon.cpp
-
if (qCpuHasFeature(NEON))
d->rgb888ToRgb32ConverterPtr = qt_convert_rgb888_to_rgb32_neon;
#endif
diff --git a/src/gui/image/qmovie.h b/src/gui/image/qmovie.h
index 13bc381f8e..a750e4a9fc 100644
--- a/src/gui/image/qmovie.h
+++ b/src/gui/image/qmovie.h
@@ -73,9 +73,9 @@ public:
};
Q_ENUM(CacheMode)
- explicit QMovie(QObject *parent = 0);
- explicit QMovie(QIODevice *device, const QByteArray &format = QByteArray(), QObject *parent = 0);
- explicit QMovie(const QString &fileName, const QByteArray &format = QByteArray(), QObject *parent = 0);
+ explicit QMovie(QObject *parent = Q_NULLPTR);
+ explicit QMovie(QIODevice *device, const QByteArray &format = QByteArray(), QObject *parent = Q_NULLPTR);
+ explicit QMovie(const QString &fileName, const QByteArray &format = QByteArray(), QObject *parent = Q_NULLPTR);
~QMovie();
static QList<QByteArray> supportedFormats();
diff --git a/src/gui/image/qpaintengine_pic.cpp b/src/gui/image/qpaintengine_pic.cpp
index 9ab1e2c30b..47480ebbae 100644
--- a/src/gui/image/qpaintengine_pic.cpp
+++ b/src/gui/image/qpaintengine_pic.cpp
@@ -398,6 +398,7 @@ void QPicturePaintEngine::drawPolygon(const QPointF *points, int numPoints, Poly
int pos;
QPolygonF polygon;
+ polygon.reserve(numPoints);
for (int i=0; i<numPoints; ++i)
polygon << points[i];
diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp
index b63be19153..2b184466f4 100644
--- a/src/gui/image/qpicture.cpp
+++ b/src/gui/image/qpicture.cpp
@@ -961,6 +961,9 @@ int QPicture::metric(PaintDeviceMetric m) const
case PdmDevicePixelRatio:
val = 1;
break;
+ case PdmDevicePixelRatioScaled:
+ val = 1 * QPaintDevice::devicePixelRatioFScale();
+ break;
default:
val = 0;
qWarning("QPicture::metric: Invalid metric command");
@@ -1216,7 +1219,9 @@ QList<QByteArray> QPicture::inputFormats()
static QStringList qToStringList(const QList<QByteArray> &arr)
{
QStringList list;
- for (int i = 0; i < arr.count(); ++i)
+ const int count = arr.count();
+ list.reserve(count);
+ for (int i = 0; i < count; ++i)
list.append(QString::fromLatin1(arr.at(i)));
return list;
}
diff --git a/src/gui/image/qpicture.h b/src/gui/image/qpicture.h
index c3897a1935..a71d1deb02 100644
--- a/src/gui/image/qpicture.h
+++ b/src/gui/image/qpicture.h
@@ -62,10 +62,10 @@ public:
bool play(QPainter *p);
- bool load(QIODevice *dev, const char *format = 0);
- bool load(const QString &fileName, const char *format = 0);
- bool save(QIODevice *dev, const char *format = 0);
- bool save(const QString &fileName, const char *format = 0);
+ bool load(QIODevice *dev, const char *format = Q_NULLPTR);
+ bool load(const QString &fileName, const char *format = Q_NULLPTR);
+ bool save(QIODevice *dev, const char *format = Q_NULLPTR);
+ bool save(const QString &fileName, const char *format = Q_NULLPTR);
QRect boundingRect() const;
void setBoundingRect(const QRect &r);
diff --git a/src/gui/image/qpicture_p.h b/src/gui/image/qpicture_p.h
index 56e6e1249c..a414a122f1 100644
--- a/src/gui/image/qpicture_p.h
+++ b/src/gui/image/qpicture_p.h
@@ -48,6 +48,7 @@
#include "QtCore/qatomic.h"
#include "QtCore/qbuffer.h"
#include "QtCore/qobjectdefs.h"
+#include "QtCore/qvector.h"
#include "QtGui/qpicture.h"
#include "QtGui/qpixmap.h"
#include "QtGui/qpen.h"
@@ -150,8 +151,8 @@ public:
QRect override_rect;
QScopedPointer<QPaintEngine> paintEngine;
bool in_memory_only;
- QList<QImage> image_list;
- QList<QPixmap> pixmap_list;
+ QVector<QImage> image_list;
+ QVector<QPixmap> pixmap_list;
QList<QBrush> brush_list;
QList<QPen> pen_list;
};
diff --git a/src/gui/image/qpictureformatplugin.h b/src/gui/image/qpictureformatplugin.h
index 773c0180d3..9ad938fa79 100644
--- a/src/gui/image/qpictureformatplugin.h
+++ b/src/gui/image/qpictureformatplugin.h
@@ -53,7 +53,7 @@ class Q_GUI_EXPORT QPictureFormatPlugin : public QObject
{
Q_OBJECT
public:
- explicit QPictureFormatPlugin(QObject *parent = 0);
+ explicit QPictureFormatPlugin(QObject *parent = Q_NULLPTR);
~QPictureFormatPlugin();
virtual bool loadPicture(const QString &format, const QString &filename, QPicture *pic);
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index e53af8038f..fb62889e40 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -907,7 +907,7 @@ void QPixmap::fill(const QPaintDevice *device, const QPoint &p)
{
Q_UNUSED(device)
Q_UNUSED(p)
- qWarning("%s is deprecated, ignored", Q_FUNC_INFO);
+ qWarning("this function is deprecated, ignored");
}
@@ -1703,8 +1703,8 @@ QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionF
QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h)
{
- qWarning("%s is deprecated, use QScreen::grabWindow() instead."
- " Defaulting to primary screen.", Q_FUNC_INFO);
+ qWarning("this function is deprecated, use QScreen::grabWindow() instead."
+ " Defaulting to primary screen.");
return QGuiApplication::primaryScreen()->grabWindow(window, x, y, w, h);
}
diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h
index 51b02acfcf..48db7a3840 100644
--- a/src/gui/image/qpixmap.h
+++ b/src/gui/image/qpixmap.h
@@ -58,7 +58,7 @@ public:
explicit QPixmap(QPlatformPixmap *data);
QPixmap(int w, int h);
explicit QPixmap(const QSize &);
- QPixmap(const QString& fileName, const char *format = 0, Qt::ImageConversionFlags flags = Qt::AutoColor);
+ QPixmap(const QString& fileName, const char *format = Q_NULLPTR, Qt::ImageConversionFlags flags = Qt::AutoColor);
#ifndef QT_NO_IMAGEFORMAT_XPM
explicit QPixmap(const char * const xpm[]);
#endif
@@ -131,19 +131,19 @@ public:
}
#endif
- bool load(const QString& fileName, const char *format = 0, Qt::ImageConversionFlags flags = Qt::AutoColor);
- bool loadFromData(const uchar *buf, uint len, const char* format = 0, Qt::ImageConversionFlags flags = Qt::AutoColor);
- inline bool loadFromData(const QByteArray &data, const char* format = 0, Qt::ImageConversionFlags flags = Qt::AutoColor);
- bool save(const QString& fileName, const char* format = 0, int quality = -1) const;
- bool save(QIODevice* device, const char* format = 0, int quality = -1) const;
+ bool load(const QString& fileName, const char *format = Q_NULLPTR, Qt::ImageConversionFlags flags = Qt::AutoColor);
+ bool loadFromData(const uchar *buf, uint len, const char* format = Q_NULLPTR, Qt::ImageConversionFlags flags = Qt::AutoColor);
+ inline bool loadFromData(const QByteArray &data, const char* format = Q_NULLPTR, Qt::ImageConversionFlags flags = Qt::AutoColor);
+ bool save(const QString& fileName, const char* format = Q_NULLPTR, int quality = -1) const;
+ bool save(QIODevice* device, const char* format = Q_NULLPTR, int quality = -1) const;
bool convertFromImage(const QImage &img, Qt::ImageConversionFlags flags = Qt::AutoColor);
inline QPixmap copy(int x, int y, int width, int height) const;
QPixmap copy(const QRect &rect = QRect()) const;
- inline void scroll(int dx, int dy, int x, int y, int width, int height, QRegion *exposed = 0);
- void scroll(int dx, int dy, const QRect &rect, QRegion *exposed = 0);
+ inline void scroll(int dx, int dy, int x, int y, int width, int height, QRegion *exposed = Q_NULLPTR);
+ void scroll(int dx, int dy, const QRect &rect, QRegion *exposed = Q_NULLPTR);
#if QT_DEPRECATED_SINCE(5, 0)
QT_DEPRECATED inline int serialNumber() const { return cacheKey() >> 32; }
diff --git a/src/gui/image/qpixmap_blitter.cpp b/src/gui/image/qpixmap_blitter.cpp
index f24cbc3db9..b254c5a2af 100644
--- a/src/gui/image/qpixmap_blitter.cpp
+++ b/src/gui/image/qpixmap_blitter.cpp
@@ -115,6 +115,8 @@ int QBlittablePlatformPixmap::metric(QPaintDevice::PaintDeviceMetric metric) con
return qt_defaultDpiY();
case QPaintDevice::PdmDevicePixelRatio:
return devicePixelRatio();
+ case QPaintDevice::PdmDevicePixelRatioScaled:
+ return devicePixelRatio() * QPaintDevice::devicePixelRatioFScale();
default:
qWarning("QRasterPlatformPixmap::metric(): Unhandled metric type %d", metric);
break;
diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp
index 9c8835a7a0..bbdf77355e 100644
--- a/src/gui/image/qpixmap_raster.cpp
+++ b/src/gui/image/qpixmap_raster.cpp
@@ -178,20 +178,7 @@ void QRasterPlatformPixmap::fill(const QColor &color)
int alpha = color.alpha();
if (alpha != 255) {
if (!image.hasAlphaChannel()) {
- QImage::Format toFormat;
-#if !(defined(__ARM_NEON__) || defined(__SSE2__))
- if (image.format() == QImage::Format_RGB16)
- toFormat = QImage::Format_ARGB8565_Premultiplied;
- else if (image.format() == QImage::Format_RGB666)
- toFormat = QImage::Format_ARGB6666_Premultiplied;
- else if (image.format() == QImage::Format_RGB555)
- toFormat = QImage::Format_ARGB8555_Premultiplied;
- else if (image.format() == QImage::Format_RGB444)
- toFormat = QImage::Format_ARGB4444_Premultiplied;
- else
-#endif
- toFormat = QImage::Format_ARGB32_Premultiplied;
-
+ QImage::Format toFormat = qt_alphaVersionForPainting(image.format());
if (!image.isNull() && qt_depthForFormat(image.format()) == qt_depthForFormat(toFormat)) {
image.detach();
image.d->format = toFormat;
@@ -288,6 +275,9 @@ int QRasterPlatformPixmap::metric(QPaintDevice::PaintDeviceMetric metric) const
return qt_defaultDpiY();
case QPaintDevice::PdmDevicePixelRatio:
return image.devicePixelRatio();
+ case QPaintDevice::PdmDevicePixelRatioScaled:
+ return image.devicePixelRatio() * QPaintDevice::devicePixelRatioFScale();
+
default:
qWarning("QRasterPlatformPixmap::metric(): Unhandled metric type %d", metric);
break;
@@ -311,17 +301,7 @@ void QRasterPlatformPixmap::createPixmapForImage(QImage &sourceImage, Qt::ImageC
: QImage::Format_RGB32;
} else {
QImage::Format opaqueFormat = QNativeImage::systemFormat();
- QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied;
-
-#if !defined(__ARM_NEON__) && !defined(__SSE2__)
- switch (opaqueFormat) {
- case QImage::Format_RGB16:
- alphaFormat = QImage::Format_ARGB8565_Premultiplied;
- break;
- default: // We don't care about the others...
- break;
- }
-#endif
+ QImage::Format alphaFormat = qt_alphaVersionForPainting(opaqueFormat);
if (!sourceImage.hasAlphaChannel()) {
format = opaqueFormat;
diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp
index 12e19440dc..a7a9b375ff 100644
--- a/src/gui/image/qpixmap_win.cpp
+++ b/src/gui/image/qpixmap_win.cpp
@@ -345,9 +345,22 @@ static QImage qt_imageFromWinIconHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h)
return image;
}
+static inline bool hasAlpha(const QImage &image)
+{
+ const int w = image.width();
+ const int h = image.height();
+ for (int y = 0; y < h; ++y) {
+ const QRgb *scanLine = reinterpret_cast<const QRgb *>(image.scanLine(y));
+ for (int x = 0; x < w; ++x) {
+ if (qAlpha(scanLine[x]) != 0)
+ return true;
+ }
+ }
+ return false;
+}
+
Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon)
{
- bool foundAlpha = false;
HDC screenDevice = GetDC(0);
HDC hdc = CreateCompatibleDC(screenDevice);
ReleaseDC(0, screenDevice);
@@ -356,6 +369,7 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon)
const bool result = GetIconInfo(icon, &iconinfo); //x and y Hotspot describes the icon center
if (!result) {
qErrnoWarning("QPixmap::fromWinHICON(), failed to GetIconInfo()");
+ DeleteDC(hdc);
return QPixmap();
}
@@ -371,17 +385,7 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon)
DrawIconEx( hdc, 0, 0, icon, iconinfo.xHotspot * 2, iconinfo.yHotspot * 2, 0, 0, DI_NORMAL);
QImage image = qt_imageFromWinIconHBITMAP(hdc, winBitmap, w, h);
- for (int y = 0 ; y < h && !foundAlpha ; y++) {
- const QRgb *scanLine= reinterpret_cast<const QRgb *>(image.scanLine(y));
- for (int x = 0; x < w ; x++) {
- if (qAlpha(scanLine[x]) != 0) {
- foundAlpha = true;
- break;
- }
- }
- }
- if (!foundAlpha) {
- //If no alpha was found, we use the mask to set alpha values
+ if (!image.isNull() && !hasAlpha(image)) { //If no alpha was found, we use the mask to set alpha values
DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_MASK);
const QImage mask = qt_imageFromWinIconHBITMAP(hdc, winBitmap, w, h);
diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp
index 3836976975..d29ddcf978 100644
--- a/src/gui/image/qpixmapcache.cpp
+++ b/src/gui/image/qpixmapcache.cpp
@@ -73,7 +73,7 @@ QT_BEGIN_NAMESPACE
memory.
The \e{Qt Quarterly} article
- \l{http://doc.qt.digia.com/qq/qq12-qpixmapcache.html}{Optimizing
+ \l{http://doc.qt.io/archives/qq/qq12-qpixmapcache.html}{Optimizing
with QPixmapCache} explains how to use QPixmapCache to speed up
applications by caching the results of painting.
@@ -138,6 +138,24 @@ bool QPixmapCache::Key::operator ==(const Key &key) const
*/
/*!
+ \fn QPixmapCache::Key::Key(Key &&)
+ \internal
+ \since 5.6
+*/
+
+/*!
+ \fn QPixmapCache::Key &QPixmapCache::Key::operator=(Key &&)
+ \internal
+ \since 5.6
+*/
+
+/*!
+ \fn void QPixmapCache::Key::swap(Key &)
+ \internal
+ \since 5.6
+*/
+
+/*!
\internal
*/
QPixmapCache::Key &QPixmapCache::Key::operator =(const Key &other)
@@ -179,7 +197,6 @@ public:
static QPixmapCache::KeyData* getKeyData(QPixmapCache::Key *key);
- QList< QPair<QString,QPixmap> > allPixmaps() const;
bool flushDetachedPixmaps(bool nt);
private:
@@ -423,20 +440,6 @@ QPixmapCache::KeyData* QPMCache::getKeyData(QPixmapCache::Key *key)
return key->d;
}
-QList< QPair<QString,QPixmap> > QPMCache::allPixmaps() const
-{
- QList< QPair<QString,QPixmap> > r;
- QHash<QString, QPixmapCache::Key>::const_iterator it = cacheKeys.begin();
- while (it != cacheKeys.end()) {
- QPixmap *ptr = QCache<QPixmapCache::Key, QPixmapCacheEntry>::object(it.value());
- if (ptr)
- r.append(QPair<QString,QPixmap>(it.key(),*ptr));
- ++it;
- }
- return r;
-}
-
-
Q_GLOBAL_STATIC(QPMCache, pm_cache)
int Q_AUTOTEST_EXPORT q_QPixmapCache_keyHashSize()
@@ -639,7 +642,8 @@ void QPixmapCache::remove(const Key &key)
void QPixmapCache::clear()
{
QT_TRY {
- pm_cache()->clear();
+ if (pm_cache.exists())
+ pm_cache->clear();
} QT_CATCH(const std::bad_alloc &) {
// if we ran out of memory during pm_cache(), it's no leak,
// so just ignore it.
@@ -656,10 +660,6 @@ int QPixmapCache::totalUsed()
return (pm_cache()->totalCost()+1023) / 1024;
}
-QList< QPair<QString,QPixmap> > QPixmapCache::allPixmaps()
-{
- return pm_cache()->allPixmaps();
-}
/*!
\fn QPixmapCache::KeyData::KeyData()
@@ -667,7 +667,6 @@ QList< QPair<QString,QPixmap> > QPixmapCache::allPixmaps()
*/
/*!
\fn QPixmapCache::KeyData::KeyData(const KeyData &other)
-
\internal
*/
/*!
diff --git a/src/gui/image/qpixmapcache.h b/src/gui/image/qpixmapcache.h
index 345389e987..37a0588e06 100644
--- a/src/gui/image/qpixmapcache.h
+++ b/src/gui/image/qpixmapcache.h
@@ -36,10 +36,6 @@
#include <QtGui/qpixmap.h>
-#ifdef Q_TEST_QPIXMAPCACHE
-#include <QtCore/qpair.h>
-#endif
-
QT_BEGIN_NAMESPACE
@@ -52,12 +48,18 @@ public:
public:
Key();
Key(const Key &other);
+#ifdef Q_COMPILER_RVALUE_REFS
+ Key(Key &&other) Q_DECL_NOTHROW : d(other.d) { other.d = Q_NULLPTR; }
+ Key &operator =(Key &&other) Q_DECL_NOTHROW { swap(other); return *this; }
+#endif
~Key();
bool operator ==(const Key &key) const;
inline bool operator !=(const Key &key) const
{ return !operator==(key); }
Key &operator =(const Key &other);
+ void swap(Key &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
+
private:
KeyData *d;
friend class QPMCache;
@@ -80,9 +82,9 @@ public:
#ifdef Q_TEST_QPIXMAPCACHE
static void flushDetachedPixmaps();
static int totalUsed();
- static QList< QPair<QString,QPixmap> > allPixmaps();
#endif
};
+Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QPixmapCache::Key)
QT_END_NAMESPACE
diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp
index 7fbd24787e..e9944e1750 100644
--- a/src/gui/image/qpnghandler.cpp
+++ b/src/gui/image/qpnghandler.cpp
@@ -43,13 +43,8 @@
#include <qvariant.h>
#include <qvector.h>
-#ifdef QT_USE_BUNDLED_LIBPNG
-#include <../../3rdparty/libpng/png.h>
-#include <../../3rdparty/libpng/pngconf.h>
-#else
#include <png.h>
#include <pngconf.h>
-#endif
#if PNG_LIBPNG_VER >= 10400 && PNG_LIBPNG_VER <= 10502 \
&& defined(PNG_PEDANTIC_WARNINGS_SUPPORTED)
@@ -108,10 +103,11 @@ public:
};
QPngHandlerPrivate(QPngHandler *qq)
- : gamma(0.0), quality(2), png_ptr(0), info_ptr(0), end_info(0), state(Ready), q(qq)
+ : gamma(0.0), fileGamma(0.0), quality(2), png_ptr(0), info_ptr(0), end_info(0), state(Ready), q(qq)
{ }
float gamma;
+ float fileGamma;
int quality;
QString description;
QSize scaledSize;
@@ -234,13 +230,10 @@ void CALLBACK_CALL_TYPE qpiw_flush_fn(png_structp /* png_ptr */)
}
static
-void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scaledSize, bool *doScaledRead, float screen_gamma=0.0)
+void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scaledSize, bool *doScaledRead, float screen_gamma=0.0, float file_gamma=0.0)
{
- if (screen_gamma != 0.0 && png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA)) {
- double file_gamma;
- png_get_gAMA(png_ptr, info_ptr, &file_gamma);
- png_set_gamma(png_ptr, screen_gamma, file_gamma);
- }
+ if (screen_gamma != 0.0 && file_gamma != 0.0)
+ png_set_gamma(png_ptr, 1.0f / screen_gamma, file_gamma);
png_uint_32 width;
png_uint_32 height;
@@ -557,6 +550,12 @@ bool Q_INTERNAL_WIN_NO_THROW QPngHandlerPrivate::readPngHeader()
readPngTexts(info_ptr);
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA)) {
+ double file_gamma = 0.0;
+ png_get_gAMA(png_ptr, info_ptr, &file_gamma);
+ fileGamma = file_gamma;
+ }
+
state = ReadHeader;
return true;
}
@@ -580,7 +579,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPngHandlerPrivate::readPngImage(QImage *outImage)
}
bool doScaledRead = false;
- setup_qt(*outImage, png_ptr, info_ptr, scaledSize, &doScaledRead, gamma);
+ setup_qt(*outImage, png_ptr, info_ptr, scaledSize, &doScaledRead, gamma, fileGamma);
if (outImage->isNull()) {
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
@@ -1063,7 +1062,7 @@ QVariant QPngHandler::option(ImageOption option) const
return QVariant();
if (option == Gamma)
- return d->gamma;
+ return d->gamma == 0.0 ? d->fileGamma : d->gamma;
else if (option == Quality)
return d->quality;
else if (option == Description)
diff --git a/src/gui/image/qpnghandler.pri b/src/gui/image/qpnghandler.pri
index 9ab175d628..505d214130 100644
--- a/src/gui/image/qpnghandler.pri
+++ b/src/gui/image/qpnghandler.pri
@@ -1,9 +1,4 @@
HEADERS += $$PWD/qpnghandler_p.h
SOURCES += $$PWD/qpnghandler.cpp
-contains(QT_CONFIG, system-png) {
- if(unix|mingw): LIBS_PRIVATE += -lpng
- else:win32: LIBS += libpng.lib
-} else {
- include($$PWD/../../3rdparty/libpng.pri)
-}
+include($$PWD/../../3rdparty/png_dependency.pri)
diff --git a/src/gui/image/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp
index f460431c2b..7f23656c02 100644
--- a/src/gui/image/qppmhandler.cpp
+++ b/src/gui/image/qppmhandler.cpp
@@ -46,13 +46,21 @@ QT_BEGIN_NAMESPACE
PBM/PGM/PPM (ASCII and RAW) image read/write functions
*****************************************************************************/
+static void discard_pbm_line(QIODevice *d)
+{
+ const int buflen = 100;
+ char buf[buflen];
+ int res = 0;
+ do {
+ res = d->readLine(buf, buflen);
+ } while (res > 0 && buf[res-1] != '\n');
+}
+
static int read_pbm_int(QIODevice *d)
{
char c;
int val = -1;
bool digit;
- const int buflen = 100;
- char buf[buflen];
for (;;) {
if (!d->getChar(&c)) // end of file
break;
@@ -63,7 +71,7 @@ static int read_pbm_int(QIODevice *d)
continue;
} else {
if (c == '#') // comment
- d->readLine(buf, buflen);
+ discard_pbm_line(d);
break;
}
}
@@ -72,7 +80,7 @@ static int read_pbm_int(QIODevice *d)
else if (isspace((uchar) c))
continue;
else if (c == '#')
- (void)d->readLine(buf, buflen);
+ discard_pbm_line(d);
else
break;
}
diff --git a/src/gui/itemmodels/qstandarditemmodel.cpp b/src/gui/itemmodels/qstandarditemmodel.cpp
index 8d848b662f..25b82b94b5 100644
--- a/src/gui/itemmodels/qstandarditemmodel.cpp
+++ b/src/gui/itemmodels/qstandarditemmodel.cpp
@@ -1224,7 +1224,7 @@ void QStandardItem::setSelectable(bool selectable)
The item delegate will render a checkable item with a check box next to the
item's text.
- \sa isCheckable(), setCheckState(), setTristate()
+ \sa isCheckable(), setCheckState(), setUserTristate(), setAutoTristate()
*/
void QStandardItem::setCheckable(bool checkable)
{
@@ -1244,34 +1244,88 @@ void QStandardItem::setCheckable(bool checkable)
The default value is false.
- \sa setCheckable(), checkState(), isTristate()
+ \sa setCheckable(), checkState(), isUserTristate(), isAutoTristate()
*/
/*!
- Sets whether the item is tristate. If \a tristate is true, the
- item is checkable with three separate states; otherwise, the item
- is checkable with two states. (Note that this also requires that
- the item is checkable; see isCheckable().)
+ \fn void QStandardItem::setTristate(bool tristate)
+ \obsolete
- \sa isTristate(), setCheckable(), setCheckState()
+ Use QStandardItem::setAutoTristate(bool tristate) instead.
+ For a tristate checkbox that the user can change between all three
+ states, use QStandardItem::setUserTristate(bool tristate) instead.
*/
-void QStandardItem::setTristate(bool tristate)
+
+/*!
+ \fn void QStandardItem::isTristate() const
+ \obsolete
+
+ Use QStandardItem::isAutoTristate() instead.
+ For a tristate checkbox that the user can change between all three
+ states, use QStandardItem::isUserTristate() instead.
+*/
+
+/*!
+ Determines that the item is tristate and controlled by QTreeWidget if \a tristate
+ is \c true.
+ This enables automatic management of the state of parent items in QTreeWidget
+ (checked if all children are checked, unchecked if all children are unchecked,
+ or partially checked if only some children are checked).
+
+ \since 5.6
+ \sa isAutoTristate(), setCheckable(), setCheckState()
+*/
+void QStandardItem::setAutoTristate(bool tristate)
{
Q_D(QStandardItem);
- d->changeFlags(tristate, Qt::ItemIsTristate);
+ d->changeFlags(tristate, Qt::ItemIsAutoTristate);
}
/*!
- \fn bool QStandardItem::isTristate() const
+ \fn bool QStandardItem::isAutoTristate() const
+
+ Returns whether the item is tristate and is controlled by QTreeWidget.
+
+ The default value is false.
+
+ \since 5.6
+ \sa setAutoTristate(), isCheckable(), checkState()
+*/
+
+/*!
+ Sets whether the item is tristate and controlled by the user.
+ If \a tristate is true, the user can cycle through three separate states;
+ otherwise, the item is checkable with two states.
+ (Note that this also requires that the item is checkable; see isCheckable().)
+
+ \since 5.6
+ \sa isUserTristate(), setCheckable(), setCheckState()
+*/
+void QStandardItem::setUserTristate(bool tristate)
+{
+ Q_D(QStandardItem);
+ d->changeFlags(tristate, Qt::ItemIsUserTristate);
+}
+
+/*!
+ \fn bool QStandardItem::isUserTristate() const
+ \since 5.6
Returns whether the item is tristate; that is, if it's checkable with three
- separate states.
+ separate states and the user can cycle through all three states.
The default value is false.
- \sa setTristate(), isCheckable(), checkState()
+ \sa setUserTristate(), isCheckable(), checkState()
*/
+#if QT_DEPRECATED_SINCE(5, 6)
+void QStandardItem::setTristate(bool tristate)
+{
+ setAutoTristate(tristate);
+}
+#endif
+
#ifndef QT_NO_DRAGANDDROP
/*!
@@ -1750,6 +1804,7 @@ QList<QStandardItem*> QStandardItem::takeRow(int row)
int index = d->childIndex(row, 0); // Will return -1 if there are no columns
if (index != -1) {
int col_count = d->columnCount();
+ items.reserve(col_count);
for (int column = 0; column < col_count; ++column) {
QStandardItem *ch = d->children.at(index + column);
if (ch)
@@ -2467,7 +2522,9 @@ QList<QStandardItem*> QStandardItemModel::findItems(const QString &text,
QModelIndexList indexes = match(index(0, column, QModelIndex()),
Qt::DisplayRole, text, -1, flags);
QList<QStandardItem*> items;
- for (int i = 0; i < indexes.size(); ++i)
+ const int numIndexes = indexes.size();
+ items.reserve(numIndexes);
+ for (int i = 0; i < numIndexes; ++i)
items.append(itemFromIndex(indexes.at(i)));
return items;
}
diff --git a/src/gui/itemmodels/qstandarditemmodel.h b/src/gui/itemmodels/qstandarditemmodel.h
index 3dd613f907..8740f7940b 100644
--- a/src/gui/itemmodels/qstandarditemmodel.h
+++ b/src/gui/itemmodels/qstandarditemmodel.h
@@ -158,10 +158,20 @@ public:
}
void setCheckable(bool checkable);
- inline bool isTristate() const {
- return (flags() & Qt::ItemIsTristate) != 0;
+ inline bool isAutoTristate() const {
+ return (flags() & Qt::ItemIsAutoTristate) != 0;
}
- void setTristate(bool tristate);
+ void setAutoTristate(bool tristate);
+
+ inline bool isUserTristate() const {
+ return (flags() & Qt::ItemIsUserTristate) != 0;
+ }
+ void setUserTristate(bool tristate);
+
+#if QT_DEPRECATED_SINCE(5, 6)
+ QT_DEPRECATED bool isTristate() const { return isAutoTristate(); }
+ QT_DEPRECATED void setTristate(bool tristate);
+#endif
#ifndef QT_NO_DRAGANDDROP
inline bool isDragEnabled() const {
@@ -310,8 +320,8 @@ class Q_GUI_EXPORT QStandardItemModel : public QAbstractItemModel
Q_PROPERTY(int sortRole READ sortRole WRITE setSortRole)
public:
- explicit QStandardItemModel(QObject *parent = 0);
- QStandardItemModel(int rows, int columns, QObject *parent = 0);
+ explicit QStandardItemModel(QObject *parent = Q_NULLPTR);
+ QStandardItemModel(int rows, int columns, QObject *parent = Q_NULLPTR);
~QStandardItemModel();
void setItemRoleNames(const QHash<int,QByteArray> &roleNames);
@@ -405,7 +415,7 @@ Q_SIGNALS:
void itemChanged(QStandardItem *item);
protected:
- QStandardItemModel(QStandardItemModelPrivate &dd, QObject *parent = 0);
+ QStandardItemModel(QStandardItemModelPrivate &dd, QObject *parent = Q_NULLPTR);
private:
friend class QStandardItemPrivate;
diff --git a/src/gui/itemmodels/qstandarditemmodel_p.h b/src/gui/itemmodels/qstandarditemmodel_p.h
index 491a49f9c2..b49045d283 100644
--- a/src/gui/itemmodels/qstandarditemmodel_p.h
+++ b/src/gui/itemmodels/qstandarditemmodel_p.h
@@ -61,7 +61,7 @@ class QStandardItemData
{
public:
inline QStandardItemData() : role(-1) {}
- inline QStandardItemData(int r, QVariant v) : role(r), value(v) {}
+ inline QStandardItemData(int r, const QVariant &v) : role(r), value(v) {}
int role;
QVariant value;
inline bool operator==(const QStandardItemData &other) const { return role == other.role && value == other.value; }
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index af6a417608..73a5a7b6ab 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -75,7 +75,9 @@ HEADERS += \
kernel/qplatformgraphicsbuffer.h \
kernel/qplatformgraphicsbufferhelper.h \
kernel/qinputdevicemanager_p.h \
- kernel/qinputdevicemanager_p_p.h
+ kernel/qinputdevicemanager_p_p.h \
+ kernel/qhighdpiscaling_p.h
+
SOURCES += \
kernel/qgenericpluginfactory.cpp \
@@ -131,7 +133,9 @@ SOURCES += \
kernel/qrasterwindow.cpp \
kernel/qplatformgraphicsbuffer.cpp \
kernel/qplatformgraphicsbufferhelper.cpp \
- kernel/qinputdevicemanager.cpp
+ kernel/qinputdevicemanager.cpp \
+ kernel/qhighdpiscaling.cpp
+
contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) {
HEADERS += \
diff --git a/src/gui/kernel/qcursor.cpp b/src/gui/kernel/qcursor.cpp
index 6b01952647..c25f3c2665 100644
--- a/src/gui/kernel/qcursor.cpp
+++ b/src/gui/kernel/qcursor.cpp
@@ -43,6 +43,7 @@
#include <qpa/qplatformcursor.h>
#include <private/qguiapplication_p.h>
+#include <private/qhighdpiscaling_p.h>
QT_BEGIN_NAMESPACE
@@ -177,9 +178,14 @@ QT_BEGIN_NAMESPACE
*/
QPoint QCursor::pos(const QScreen *screen)
{
- if (screen)
- if (const QPlatformCursor *cursor = screen->handle()->cursor())
- return cursor->pos();
+ if (screen) {
+ if (const QPlatformCursor *cursor = screen->handle()->cursor()) {
+ const QPlatformScreen *ps = screen->handle();
+ QPoint nativePos = cursor->pos();
+ ps = ps->screenForPosition(nativePos);
+ return QHighDpi::fromNativePixels(nativePos, ps->screen());
+ }
+ }
return QGuiApplicationPrivate::lastCursorPosition.toPoint();
}
@@ -231,12 +237,12 @@ void QCursor::setPos(QScreen *screen, int x, int y)
{
if (screen) {
if (QPlatformCursor *cursor = screen->handle()->cursor()) {
- const QPoint pos = QPoint(x, y);
+ const QPoint devicePos = QHighDpi::toNativePixels(QPoint(x, y), screen);
// Need to check, since some X servers generate null mouse move
// events, causing looping in applications which call setPos() on
// every mouse move event.
- if (pos != cursor->pos())
- cursor->setPos(pos);
+ if (devicePos != cursor->pos())
+ cursor->setPos(devicePos);
}
}
}
diff --git a/src/gui/kernel/qdnd.cpp b/src/gui/kernel/qdnd.cpp
index 3ce8ab95ec..b05da1bfd0 100644
--- a/src/gui/kernel/qdnd.cpp
+++ b/src/gui/kernel/qdnd.cpp
@@ -147,7 +147,9 @@ static QStringList imageReadMimeFormats()
{
QStringList formats;
QList<QByteArray> imageFormats = QImageReader::supportedImageFormats();
- for (int i = 0; i < imageFormats.size(); ++i) {
+ const int numImageFormats = imageFormats.size();
+ formats.reserve(numImageFormats);
+ for (int i = 0; i < numImageFormats; ++i) {
QString format = QLatin1String("image/");
format += QString::fromLatin1(imageFormats.at(i).toLower());
formats.append(format);
@@ -166,7 +168,9 @@ static QStringList imageWriteMimeFormats()
{
QStringList formats;
QList<QByteArray> imageFormats = QImageWriter::supportedImageFormats();
- for (int i = 0; i < imageFormats.size(); ++i) {
+ const int numImageFormats = imageFormats.size();
+ formats.reserve(numImageFormats);
+ for (int i = 0; i < numImageFormats; ++i) {
QString format = QLatin1String("image/");
format += QString::fromLatin1(imageFormats.at(i).toLower());
formats.append(format);
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index c231c47576..2ca17692db 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -171,6 +171,8 @@ QInputEvent::~QInputEvent()
\fn ulong QInputEvent::timestamp() const
Returns the window system's timestamp for this event.
+ It will normally be in milliseconds since some arbitrary point
+ in time, such as the time when the system was started.
*/
/*! \fn void QInputEvent::setTimestamp(ulong atimestamp)
@@ -309,6 +311,36 @@ QMouseEvent::QMouseEvent(Type type, const QPointF &localPos, const QPointF &wind
{}
/*!
+ \since 5.6
+
+ Constructs a mouse event object.
+
+ The \a type parameter must be QEvent::MouseButtonPress,
+ QEvent::MouseButtonRelease, QEvent::MouseButtonDblClick,
+ or QEvent::MouseMove.
+
+ The points \a localPos, \a windowPos and \a screenPos specify the
+ mouse cursor's position relative to the receiving widget or item,
+ window, and screen, respectively.
+
+ The \a button that caused the event is given as a value from the
+ \l Qt::MouseButton enum. If the event \a type is \l MouseMove,
+ the appropriate button for this event is Qt::NoButton. \a buttons
+ is the state of all buttons at the time of the event, \a modifiers
+ is the state of all keyboard modifiers.
+
+ The source of the event is specified by \a source.
+
+*/
+QMouseEvent::QMouseEvent(QEvent::Type type, const QPointF &localPos, const QPointF &windowPos, const QPointF &screenPos,
+ Qt::MouseButton button, Qt::MouseButtons buttons,
+ Qt::KeyboardModifiers modifiers, Qt::MouseEventSource source)
+ : QInputEvent(type, modifiers), l(localPos), w(windowPos), s(screenPos), b(button), mouseState(buttons), caps(0)
+{
+ QGuiApplicationPrivate::setMouseEventSource(this, source);
+}
+
+/*!
\internal
*/
QMouseEvent::~QMouseEvent()
@@ -997,8 +1029,10 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos,
when keys are pressed or released.
A key event contains a special accept flag that indicates whether
- the receiver will handle the key event. This flag is set by default,
- so there is no need to call accept() when acting on a key event.
+ the receiver will handle the key event. This flag is set by default
+ for QEvent::KeyPress and QEvent::KeyRelease, so there is no need to
+ call accept() when acting on a key event. For QEvent::ShortcutOverride
+ the receiver needs to explicitly accept the event to trigger the override.
Calling ignore() on a key event will propagate it to the parent widget.
The event is propagated up the parent widget chain until a widget
accepts it or an event filter consumes it.
@@ -1033,6 +1067,8 @@ QKeyEvent::QKeyEvent(Type type, int key, Qt::KeyboardModifiers modifiers, const
nScanCode(0), nVirtualKey(0), nModifiers(0),
c(count), autor(autorep)
{
+ if (type == QEvent::ShortcutOverride)
+ ignore();
}
/*!
@@ -1060,6 +1096,8 @@ QKeyEvent::QKeyEvent(Type type, int key, Qt::KeyboardModifiers modifiers,
nScanCode(nativeScanCode), nVirtualKey(nativeVirtualKey), nModifiers(nativeModifiers),
c(count), autor(autorep)
{
+ if (type == QEvent::ShortcutOverride)
+ ignore();
}
@@ -1987,6 +2025,11 @@ QInputMethodEvent::QInputMethodEvent(const QInputMethodEvent &other)
{
}
+QInputMethodEvent::~QInputMethodEvent()
+{
+ // must be empty until ### Qt 6
+}
+
/*!
Sets the commit string to \a commitString.
@@ -3374,6 +3417,21 @@ QShowEvent::~QShowEvent()
It may be safely ignored.
\note This class is currently supported for OS X only.
+
+ \section1 OS X Example
+
+ In order to trigger the event on OS X, the application must be configured
+ to let the OS know what kind of file(s) it should react on.
+
+ For example, the following \c Info.plist file declares that the application
+ can act as a viewer for files with a PNG extension:
+
+ \snippet qfileopenevent/Info.plist Custom Info.plist
+
+ The following implementation of a QApplication subclass prints the path to
+ the file that was, for example, dropped on the Dock icon of the application.
+
+ \snippet qfileopenevent/main.cpp QApplication subclass
*/
/*!
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index a1f32026ac..b90fce97e0 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -106,6 +106,9 @@ public:
QMouseEvent(Type type, const QPointF &localPos, const QPointF &windowPos, const QPointF &screenPos,
Qt::MouseButton button, Qt::MouseButtons buttons,
Qt::KeyboardModifiers modifiers);
+ QMouseEvent(Type type, const QPointF &localPos, const QPointF &windowPos, const QPointF &screenPos,
+ Qt::MouseButton button, Qt::MouseButtons buttons,
+ Qt::KeyboardModifiers modifiers, Qt::MouseEventSource source);
~QMouseEvent();
#ifndef QT_NO_INTEGER_EVENT_COORDINATES
@@ -519,7 +522,7 @@ public:
};
class Attribute {
public:
- Attribute(AttributeType t, int s, int l, QVariant val) : type(t), start(s), length(l), value(val) {}
+ Attribute(AttributeType t, int s, int l, QVariant val) : type(t), start(s), length(l), value(qMove(val)) {}
AttributeType type;
int start;
@@ -528,6 +531,8 @@ public:
};
QInputMethodEvent();
QInputMethodEvent(const QString &preeditText, const QList<Attribute> &attributes);
+ ~QInputMethodEvent();
+
void setCommitString(const QString &commitString, int replaceFrom = 0, int replaceLength = 0);
inline const QList<Attribute> &attributes() const { return attrs; }
inline const QString &preeditString() const { return preedit; }
@@ -694,7 +699,7 @@ class Q_GUI_EXPORT QActionEvent : public QEvent
{
QAction *act, *bef;
public:
- QActionEvent(int type, QAction *action, QAction *before = 0);
+ QActionEvent(int type, QAction *action, QAction *before = Q_NULLPTR);
~QActionEvent();
inline QAction *action() const { return act; }
@@ -871,9 +876,9 @@ public:
#endif
explicit QTouchEvent(QEvent::Type eventType,
- QTouchDevice *device = 0,
+ QTouchDevice *device = Q_NULLPTR,
Qt::KeyboardModifiers modifiers = Qt::NoModifier,
- Qt::TouchPointStates touchPointStates = 0,
+ Qt::TouchPointStates touchPointStates = Qt::TouchPointStates(),
const QList<QTouchEvent::TouchPoint> &touchPoints = QList<QTouchEvent::TouchPoint>());
~QTouchEvent();
diff --git a/src/gui/kernel/qgenericplugin.h b/src/gui/kernel/qgenericplugin.h
index cfab34d081..03c1df7fba 100644
--- a/src/gui/kernel/qgenericplugin.h
+++ b/src/gui/kernel/qgenericplugin.h
@@ -48,7 +48,7 @@ class Q_GUI_EXPORT QGenericPlugin : public QObject
{
Q_OBJECT
public:
- explicit QGenericPlugin(QObject *parent = 0);
+ explicit QGenericPlugin(QObject *parent = Q_NULLPTR);
~QGenericPlugin();
virtual QObject* create(const QString& name, const QString &spec) = 0;
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index c2b561aa93..7d469dd25e 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -99,6 +99,9 @@
#elif defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
# include <QtCore/qt_windows.h>
# include <QtCore/QLibraryInfo>
+# if defined(Q_OS_WINPHONE)
+# include <Objbase.h>
+# endif
#endif // Q_OS_WIN && !Q_OS_WINCE
#include <ctype.h>
@@ -124,8 +127,12 @@ Qt::MouseButtons QGuiApplicationPrivate::tabletState = Qt::NoButton;
QWindow *QGuiApplicationPrivate::tabletPressTarget = 0;
QWindow *QGuiApplicationPrivate::currentMouseWindow = 0;
+QString QGuiApplicationPrivate::styleOverride;
+
Qt::ApplicationState QGuiApplicationPrivate::applicationState = Qt::ApplicationInactive;
+bool QGuiApplicationPrivate::highDpiScalingUpdated = false;
+
QPlatformIntegration *QGuiApplicationPrivate::platform_integration = 0;
QPlatformTheme *QGuiApplicationPrivate::platform_theme = 0;
@@ -156,7 +163,7 @@ int QGuiApplicationPrivate::mouse_double_click_distance = -1;
QWindow *QGuiApplicationPrivate::currentMousePressWindow = 0;
-static Qt::LayoutDirection layout_direction = Qt::LeftToRight;
+static Qt::LayoutDirection layout_direction = Qt::LayoutDirectionAuto;
static bool force_reverse = false;
QGuiApplicationPrivate *QGuiApplicationPrivate::self = 0;
@@ -185,9 +192,6 @@ extern void qRegisterGuiVariant();
#ifndef QT_NO_ANIMATION
extern void qRegisterGuiGetInterpolator();
#endif
-extern void qInitBlendFunctions();
-extern void qInitDrawhelperAsm();
-extern void qInitImageConversions();
static bool qt_detectRTLLanguage()
{
@@ -869,7 +873,7 @@ QWindowList QGuiApplication::topLevelWindows()
if (!list.at(i)->parent() && list.at(i)->type() != Qt::Desktop) {
// Top windows of embedded QAxServers do not have QWindow parents,
// but they are not true top level windows, so do not include them.
- const bool embedded = list.at(i)->handle() && list.at(i)->handle()->isEmbedded(0);
+ const bool embedded = list.at(i)->handle() && list.at(i)->handle()->isEmbedded();
if (!embedded)
topLevelWindows.prepend(list.at(i));
}
@@ -877,16 +881,6 @@ QWindowList QGuiApplication::topLevelWindows()
return topLevelWindows;
}
-/*!
- Returns the primary (or default) screen of the application, or null if there is none
-
- This will be the screen where QWindows are initially shown, unless otherwise specified.
-
- On some platforms, it may be null when there are actually no screens connected.
- It is not possible to start a new QGuiApplication while there are no screens.
- Applications which were running at the time the primary screen was removed
- will stop rendering graphics until one or more screens are restored.
-*/
QScreen *QGuiApplication::primaryScreen()
{
if (QGuiApplicationPrivate::screen_list.isEmpty())
@@ -908,7 +902,7 @@ QList<QScreen *> QGuiApplication::screens()
This signal is emitted whenever a new screen \a screen has been added to the system.
- \sa screens(), primaryScreen(), screenRemoved()
+ \sa screens(), primaryScreen, screenRemoved()
*/
/*!
@@ -925,6 +919,23 @@ QList<QScreen *> QGuiApplication::screens()
/*!
+ \property QGuiApplication::primaryScreen
+
+ \brief the primary (or default) screen of the application, or null if there is none.
+
+ This will be the screen where QWindows are initially shown, unless otherwise specified.
+
+ On some platforms, it may be null when there are actually no screens connected.
+ It is not possible to start a new QGuiApplication while there are no screens.
+ Applications which were running at the time the primary screen was removed
+ will stop rendering graphics until one or more screens are restored.
+
+ The primaryScreenChanged signal was introduced in Qt 5.6.
+
+ \sa screens()
+*/
+
+/*!
Returns the highest screen device pixel ratio found on
the system. This is the ratio between physical pixels and
device-independent pixels.
@@ -955,16 +966,38 @@ qreal QGuiApplication::devicePixelRatio() const
*/
QWindow *QGuiApplication::topLevelAt(const QPoint &pos)
{
- QList<QScreen *> screens = QGuiApplication::screens();
- QList<QScreen *>::const_iterator screen = screens.constBegin();
- QList<QScreen *>::const_iterator end = screens.constEnd();
+ const QList<QScreen *> screens = QGuiApplication::screens();
+ if (!screens.isEmpty()) {
+ const QList<QScreen *> primaryScreens = screens.first()->virtualSiblings();
+ QScreen *windowScreen = Q_NULLPTR;
+
+ // Find the window on the primary virtual desktop first
+ foreach (QScreen *screen, primaryScreens) {
+ if (screen->geometry().contains(pos)) {
+ windowScreen = screen;
+ break;
+ }
+ }
- while (screen != end) {
- if ((*screen)->geometry().contains(pos))
- return (*screen)->handle()->topLevelAt(pos);
- ++screen;
+ // If the window is not found on primary virtual desktop, find it on all screens
+ // except the first which was for sure in the previous loop. Some other screens
+ // may repeat. Find only when there is more than one virtual desktop.
+ if (!windowScreen && screens.count() != primaryScreens.count()) {
+ for (int i = 1; i < screens.size(); ++i) {
+ QScreen *screen = screens[i];
+ if (screen->geometry().contains(pos)) {
+ windowScreen = screen;
+ break;
+ }
+ }
+ }
+
+ if (windowScreen) {
+ const QPoint devicePosition = QHighDpi::toNativePixels(pos, windowScreen);
+ return windowScreen->handle()->topLevelAt(devicePosition);
+ }
}
- return 0;
+ return Q_NULLPTR;
}
/*!
@@ -1041,6 +1074,13 @@ static void init_platform(const QString &pluginArgument, const QString &platform
return;
}
+ // Many platforms have created QScreens at this point. Finish initializing
+ // QHighDpiScaling to be prepared for early calls to qt_defaultDpi().
+ if (QGuiApplication::primaryScreen()) {
+ QGuiApplicationPrivate::highDpiScalingUpdated = true;
+ QHighDpiScaling::updateHighDpiScaling();
+ }
+
// Create the platform theme:
// 1) Fetch the platform name from the environment if present.
@@ -1117,6 +1157,9 @@ void QGuiApplicationPrivate::createPlatformIntegration()
// this flag.
QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, true);
+
+ QHighDpiScaling::initHighDpiScaling();
+
// Load the platform integration
QString platformPluginPath = QString::fromLocal8Bit(qgetenv("QT_QPA_PLATFORM_PLUGIN_PATH"));
@@ -1138,30 +1181,32 @@ void QGuiApplicationPrivate::createPlatformIntegration()
int j = argc ? 1 : 0;
for (int i=1; i<argc; i++) {
- if (argv[i] && *argv[i] != '-') {
+ if (!argv[i])
+ continue;
+ if (*argv[i] != '-') {
argv[j++] = argv[i];
continue;
}
const bool isXcb = platformName == "xcb";
- QByteArray arg = argv[i];
- if (arg.startsWith("--"))
- arg.remove(0, 1);
- if (arg == "-platformpluginpath") {
+ const char *arg = argv[i];
+ if (arg[1] == '-') // startsWith("--")
+ ++arg;
+ if (strcmp(arg, "-platformpluginpath") == 0) {
if (++i < argc)
platformPluginPath = QString::fromLocal8Bit(argv[i]);
- } else if (arg == "-platform") {
+ } else if (strcmp(arg, "-platform") == 0) {
if (++i < argc)
platformName = argv[i];
- } else if (arg == "-platformtheme") {
+ } else if (strcmp(arg, "-platformtheme") == 0) {
if (++i < argc)
platformThemeName = QString::fromLocal8Bit(argv[i]);
- } else if (arg == "-qwindowgeometry" || (isXcb && arg == "-geometry")) {
+ } else if (strcmp(arg, "-qwindowgeometry") == 0 || (isXcb && strcmp(arg, "-geometry") == 0)) {
if (++i < argc)
windowGeometrySpecification = QWindowGeometrySpecification::fromArgument(argv[i]);
- } else if (arg == "-qwindowtitle" || (isXcb && arg == "-title")) {
+ } else if (strcmp(arg, "-qwindowtitle") == 0 || (isXcb && strcmp(arg, "-title") == 0)) {
if (++i < argc)
firstWindowTitle = QString::fromLocal8Bit(argv[i]);
- } else if (arg == "-qwindowicon" || (isXcb && arg == "-icon")) {
+ } else if (strcmp(arg, "-qwindowicon") == 0 || (isXcb && strcmp(arg, "-icon") == 0)) {
if (++i < argc) {
icon = QString::fromLocal8Bit(argv[i]);
}
@@ -1206,6 +1251,11 @@ void QGuiApplicationPrivate::eventDispatcherReady()
createPlatformIntegration();
platform_integration->initialize();
+
+ // All platforms should have added screens at this point. Finish
+ // QHighDpiScaling initialization if it has not been done so already.
+ if (!QGuiApplicationPrivate::highDpiScalingUpdated)
+ QHighDpiScaling::updateHighDpiScaling();
}
void QGuiApplicationPrivate::init()
@@ -1218,24 +1268,36 @@ void QGuiApplicationPrivate::init()
#ifndef QT_NO_SESSIONMANAGER
QString session_id;
QString session_key;
+# if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ wchar_t guidstr[40];
+ GUID guid;
+ CoCreateGuid(&guid);
+ StringFromGUID2(guid, guidstr, 40);
+ session_id = QString::fromWCharArray(guidstr);
+ CoCreateGuid(&guid);
+ StringFromGUID2(guid, guidstr, 40);
+ session_key = QString::fromWCharArray(guidstr);
+# endif
#endif
+ QString s;
int j = argc ? 1 : 0;
for (int i=1; i<argc; i++) {
- if (argv[i] && *argv[i] != '-') {
+ if (!argv[i])
+ continue;
+ if (*argv[i] != '-') {
argv[j++] = argv[i];
continue;
}
- QByteArray arg = argv[i];
- if (arg.startsWith("--"))
- arg.remove(0, 1);
- if (arg == "-plugin") {
+ const char *arg = argv[i];
+ if (arg[1] == '-') // startsWith("--")
+ ++arg;
+ if (strcmp(arg, "-plugin") == 0) {
if (++i < argc)
pluginList << argv[i];
- } else if (arg == "-reverse") {
+ } else if (strcmp(arg, "-reverse") == 0) {
force_reverse = true;
- QGuiApplication::setLayoutDirection(Qt::RightToLeft);
#ifdef Q_OS_MAC
- } else if (arg.startsWith("-psn_")) {
+ } else if (strncmp(arg, "-psn_", 5) == 0) {
// eat "-psn_xxxx" on Mac, which is passed when starting an app from Finder.
// special hack to change working directory (for an app bundle) when running from finder
if (QDir::currentPath() == QLatin1String("/")) {
@@ -1247,7 +1309,7 @@ void QGuiApplicationPrivate::init()
}
#endif
#ifndef QT_NO_SESSIONMANAGER
- } else if (arg == "-session" && i < argc-1) {
+ } else if (strcmp(arg, "-session") == 0 && i < argc - 1) {
++i;
if (argv[i] && *argv[i]) {
session_id = QString::fromLatin1(argv[i]);
@@ -1259,11 +1321,18 @@ void QGuiApplicationPrivate::init()
is_session_restored = true;
}
#endif
- } else if (arg == "-testability") {
+ } else if (strcmp(arg, "-testability") == 0) {
loadTestability = true;
+ } else if (strncmp(arg, "-style=", 7) == 0) {
+ s = QString::fromLocal8Bit(arg + 7).toLower();
+ } else if (strcmp(arg, "-style") == 0 && i < argc - 1) {
+ s = QString::fromLocal8Bit(argv[++i]).toLower();
} else {
argv[j++] = argv[i];
}
+
+ if (!s.isEmpty())
+ styleOverride = s;
}
if (j < argc) {
@@ -1281,13 +1350,6 @@ void QGuiApplicationPrivate::init()
if (platform_integration == 0)
createPlatformIntegration();
- // Set up blend function tables.
- qInitBlendFunctions();
- // Set up which span functions should be used in raster engine...
- qInitDrawhelperAsm();
- // and QImage conversion functions
- qInitImageConversions();
-
initPalette();
QFont::initialize();
@@ -1330,6 +1392,9 @@ void QGuiApplicationPrivate::init()
#endif
#ifndef QT_NO_LIBRARY
+ if (qEnvironmentVariableIntValue("QT_LOAD_TESTABILITY") > 0)
+ loadTestability = true;
+
if (loadTestability) {
QLibrary testLib(QStringLiteral("qttestability"));
if (testLib.load()) {
@@ -1344,7 +1409,12 @@ void QGuiApplicationPrivate::init()
qCritical() << "Library qttestability load failed:" << testLib.errorString();
}
}
+#else
+ Q_UNUSED(loadTestability);
#endif // QT_NO_LIBRARY
+
+ if (layout_direction == Qt::LayoutDirectionAuto || force_reverse)
+ QGuiApplication::setLayoutDirection(qt_detectRTLLanguage() ? Qt::RightToLeft : Qt::LeftToRight);
}
extern void qt_cleanupFontDatabase();
@@ -1693,12 +1763,14 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
// A mouse event should not change both position and buttons at the same time. Instead we
// should first send a move event followed by a button changed event. Since this is not the case
// with the current event, we split it in two.
- QWindowSystemInterfacePrivate::MouseEvent *mouseButtonEvent = new QWindowSystemInterfacePrivate::MouseEvent(
- e->window.data(), e->timestamp, e->type, e->localPos, e->globalPos, e->buttons, e->modifiers);
+ QWindowSystemInterfacePrivate::MouseEvent mouseButtonEvent(
+ e->window.data(), e->timestamp, e->type, e->localPos, e->globalPos, e->buttons, e->modifiers, e->source);
if (e->flags & QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic)
- mouseButtonEvent->flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic;
- QWindowSystemInterfacePrivate::windowSystemEventQueue.prepend(mouseButtonEvent);
- stateChange = Qt::NoButton;
+ mouseButtonEvent.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic;
+ e->buttons = buttons;
+ processMouseEvent(e);
+ processMouseEvent(&mouseButtonEvent);
+ return;
}
QWindow *window = e->window.data();
@@ -1767,17 +1839,23 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
if (!window)
return;
- QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, buttons, e->modifiers);
- ev.setTimestamp(e->timestamp);
- setMouseEventSource(&ev, e->source);
#ifndef QT_NO_CURSOR
if (!e->synthetic()) {
if (const QScreen *screen = window->screen())
- if (QPlatformCursor *cursor = screen->handle()->cursor())
+ if (QPlatformCursor *cursor = screen->handle()->cursor()) {
+ const QPointF nativeLocalPoint = QHighDpi::toNativePixels(localPoint, screen);
+ const QPointF nativeGlobalPoint = QHighDpi::toNativePixels(globalPoint, screen);
+ QMouseEvent ev(type, nativeLocalPoint, nativeLocalPoint, nativeGlobalPoint,
+ button, buttons, e->modifiers, e->source);
+ ev.setTimestamp(e->timestamp);
cursor->pointerEvent(ev);
+ }
}
#endif
+ QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, buttons, e->modifiers, e->source);
+ ev.setTimestamp(e->timestamp);
+
if (window->d_func()->blockedByModalWindow) {
// a modal window is blocking this window, don't allow mouse events through
return;
@@ -1789,6 +1867,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
}
QGuiApplication::sendSpontaneousEvent(window, &ev);
+ e->eventAccepted = ev.isAccepted();
if (!e->synthetic() && !ev.isAccepted()
&& !frameStrut
&& qApp->testAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents)) {
@@ -1817,7 +1896,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
points << point;
QEvent::Type type;
- QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::convertTouchPoints(points, &type);
+ QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::fromNativeTouchPoints(points, window, &type);
QWindowSystemInterfacePrivate::TouchEvent fake(window, e->timestamp, type, m_fakeTouchDevice, touchPoints, e->modifiers);
fake.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic;
@@ -1828,9 +1907,8 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
if (!e->window.isNull() || e->nullWindow()) { // QTBUG-36364, check if window closed in response to press
const QEvent::Type doubleClickType = frameStrut ? QEvent::NonClientAreaMouseButtonDblClick : QEvent::MouseButtonDblClick;
QMouseEvent dblClickEvent(doubleClickType, localPoint, localPoint, globalPoint,
- button, buttons, e->modifiers);
+ button, buttons, e->modifiers, e->source);
dblClickEvent.setTimestamp(e->timestamp);
- setMouseEventSource(&dblClickEvent, e->source);
QGuiApplication::sendSpontaneousEvent(window, &dblClickEvent);
}
}
@@ -1882,19 +1960,6 @@ void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyE
window = QGuiApplication::focusWindow();
}
-#if !defined(Q_OS_OSX)
- // On OS X the shortcut override is checked earlier, see: QWindowSystemInterface::handleKeyEvent()
- const bool checkShortcut = e->keyType == QEvent::KeyPress && window != 0;
- if (checkShortcut) {
- QKeyEvent override(QEvent::ShortcutOverride, e->key, e->modifiers,
- e->nativeScanCode, e->nativeVirtualKey, e->nativeModifiers,
- e->unicode, e->repeat, e->repeatCount);
- override.setTimestamp(e->timestamp);
- if (QWindowSystemInterface::tryHandleShortcutOverrideEvent(window, &override))
- return;
- }
-#endif // Q_OS_OSX
-
QKeyEvent ev(e->keyType, e->key, e->modifiers,
e->nativeScanCode, e->nativeVirtualKey, e->nativeModifiers,
e->unicode, e->repeat, e->repeatCount);
@@ -1922,6 +1987,7 @@ void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyE
}
}
#endif
+ e->eventAccepted = ev.isAccepted();
}
void QGuiApplicationPrivate::processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent *e)
@@ -2030,10 +2096,17 @@ void QGuiApplicationPrivate::processWindowStateChangedEvent(QWindowSystemInterfa
void QGuiApplicationPrivate::processWindowScreenChangedEvent(QWindowSystemInterfacePrivate::WindowScreenChangedEvent *wse)
{
if (QWindow *window = wse->window.data()) {
- if (QScreen *screen = wse->screen.data())
- window->d_func()->setTopLevelScreen(screen, false /* recreate */);
- else // Fall back to default behavior, and try to find some appropriate screen
- window->setScreen(0);
+ if (window->isTopLevel()) {
+ if (QScreen *screen = wse->screen.data())
+ window->d_func()->setTopLevelScreen(screen, false /* recreate */);
+ else // Fall back to default behavior, and try to find some appropriate screen
+ window->setScreen(0);
+ }
+ // we may have changed scaling, so trigger resize event if needed
+ if (window->handle()) {
+ QWindowSystemInterfacePrivate::GeometryChangeEvent gce(window, QHighDpi::fromNativePixels(window->handle()->geometry(), window), QRect());
+ processGeometryChangeEvent(&gce);
+ }
}
}
@@ -3201,7 +3274,10 @@ void QGuiApplication::setLayoutDirection(Qt::LayoutDirection direction)
Qt::LayoutDirection QGuiApplication::layoutDirection()
{
- return layout_direction;
+ // layout_direction is only ever Qt::LayoutDirectionAuto if setLayoutDirection
+ // was never called, or called with Qt::LayoutDirectionAuto (which is a no-op).
+ // In that case we return the default LeftToRight.
+ return layout_direction == Qt::LayoutDirectionAuto ? Qt::LeftToRight : layout_direction;
}
/*!
diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h
index c89268d8d4..d995387d66 100644
--- a/src/gui/kernel/qguiapplication.h
+++ b/src/gui/kernel/qguiapplication.h
@@ -70,6 +70,7 @@ class Q_GUI_EXPORT QGuiApplication : public QCoreApplication
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
Q_PROPERTY(QString platformName READ platformName STORED false)
Q_PROPERTY(bool quitOnLastWindowClosed READ quitOnLastWindowClosed WRITE setQuitOnLastWindowClosed)
+ Q_PROPERTY(QScreen *primaryScreen READ primaryScreen NOTIFY primaryScreenChanged STORED false)
public:
#ifdef Q_QDOC
@@ -158,6 +159,7 @@ Q_SIGNALS:
void fontDatabaseChanged();
void screenAdded(QScreen *screen);
void screenRemoved(QScreen *screen);
+ void primaryScreenChanged(QScreen *screen);
void lastWindowClosed();
void focusObjectChanged(QObject *focusObject);
void focusWindowChanged(QWindow *focusWindow);
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 0559442049..7c7da9790b 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -202,6 +202,7 @@ public:
static QWindow *currentMouseWindow;
static QWindow *currentMousePressWindow;
static Qt::ApplicationState applicationState;
+ static bool highDpiScalingUpdated;
#ifndef QT_NO_CLIPBOARD
static QClipboard *qt_clipboard;
@@ -219,6 +220,7 @@ public:
static QFont *app_font;
+ static QString styleOverride;
static QStyleHints *styleHints;
static bool obey_desktop_settings;
QInputMethod *inputMethod;
diff --git a/src/gui/kernel/qguivariant.cpp b/src/gui/kernel/qguivariant.cpp
index ce4a0ec09e..a0769ca671 100644
--- a/src/gui/kernel/qguivariant.cpp
+++ b/src/gui/kernel/qguivariant.cpp
@@ -175,7 +175,8 @@ static bool convert(const QVariant::Private *d, int t,
switch (t) {
case QVariant::ByteArray:
if (d->type == QVariant::Color) {
- *static_cast<QByteArray *>(result) = v_cast<QColor>(d)->name().toLatin1();
+ const QColor *c = v_cast<QColor>(d);
+ *static_cast<QByteArray *>(result) = c->name(c->alpha() != 255 ? QColor::HexArgb : QColor::HexRgb).toLatin1();
return true;
}
break;
@@ -190,9 +191,11 @@ static bool convert(const QVariant::Private *d, int t,
case QVariant::Font:
*str = v_cast<QFont>(d)->toString();
return true;
- case QVariant::Color:
- *str = v_cast<QColor>(d)->name();
+ case QVariant::Color: {
+ const QColor *c = v_cast<QColor>(d);
+ *str = c->name(c->alpha() != 255 ? QColor::HexArgb : QColor::HexRgb);
return true;
+ }
default:
break;
}
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
new file mode 100644
index 0000000000..b0ef2a284f
--- /dev/null
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -0,0 +1,423 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhighdpiscaling_p.h"
+#include "qguiapplication.h"
+#include "qscreen.h"
+#include "qplatformintegration.h"
+#include "private/qscreen_p.h"
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(lcScaling, "qt.scaling");
+
+#ifndef QT_NO_HIGHDPISCALING
+static const char legacyDevicePixelEnvVar[] = "QT_DEVICE_PIXEL_RATIO";
+static const char scaleFactorEnvVar[] = "QT_SCALE_FACTOR";
+static const char autoScreenEnvVar[] = "QT_AUTO_SCREEN_SCALE_FACTOR";
+static const char screenFactorsEnvVar[] = "QT_SCREEN_SCALE_FACTORS";
+
+static inline qreal initialGlobalScaleFactor()
+{
+
+ qreal result = 1;
+ if (qEnvironmentVariableIsSet(scaleFactorEnvVar)) {
+ bool ok;
+ const qreal f = qgetenv(scaleFactorEnvVar).toDouble(&ok);
+ if (ok && f > 0) {
+ qCDebug(lcScaling) << "Apply " << scaleFactorEnvVar << f;
+ result = f;
+ }
+ } else {
+ if (qEnvironmentVariableIsSet(legacyDevicePixelEnvVar)) {
+ qWarning() << "Warning:" << legacyDevicePixelEnvVar << "is deprecated. Instead use:" << endl
+ << " " << autoScreenEnvVar << "to enable platform plugin controlled per-screen factors." << endl
+ << " " << screenFactorsEnvVar << "to set per-screen factors." << endl
+ << " " << scaleFactorEnvVar << "to set the application global scale factor.";
+
+ int dpr = qEnvironmentVariableIntValue(legacyDevicePixelEnvVar);
+ if (dpr > 0)
+ result = dpr;
+ }
+ }
+ return result;
+}
+
+/*!
+ \class QHighDpiScaling
+ \since 5.6
+ \internal
+ \preliminary
+ \ingroup qpa
+
+ \brief Collection of utility functions for UI scaling.
+
+ QHighDpiScaling implements utility functions for high-dpi scaling for use
+ on operating systems that provide limited support for native scaling. In
+ addition this functionality can be used for simulation and testing purposes.
+
+ The functions support scaling between the device independent coordinate
+ system used by Qt applications and the native coordinate system used by
+ the platform plugins. Intended usage locations are the low level / platform
+ plugin interfacing parts of QtGui, for example the QWindow, QScreen and
+ QWindowSystemInterface implementation.
+
+ There are now up to three active coordinate systems in Qt:
+
+ ---------------------------------------------------
+ | Application Device Independent Pixels | devicePixelRatio
+ | Qt Widgets | =
+ | Qt Gui |
+ |---------------------------------------------------| Qt Scale Factor
+ | Qt Gui QPlatform* Native Pixels | *
+ | Qt platform plugin |
+ |---------------------------------------------------| OS Scale Factor
+ | Display Device Pixels |
+ | (Graphics Buffers) |
+ -----------------------------------------------------
+
+ This is an simplification and shows the main coordinate system. All layers
+ may work with device pixels in specific cases: OpenGL, creating the backing
+ store, and QPixmap management. The "Native Pixels" coordinate system is
+ internal to Qt and should not be exposed to Qt users: Seen from the outside
+ there are only two coordinate systems: device independent pixels and device
+ pixels.
+
+ The devicePixelRatio seen by applications is the product of the Qt scale
+ factor and the OS scale factor. The value of the scale factors may be 1,
+ in which case two or more of the coordinate systems are equivalent. Platforms
+ that (may) have an OS scale factor include OS X, iOS and Wayland.
+
+ Note that the functions in this file do not work with the OS scale factor
+ directly and are limited to converting between device independent and native
+ pixels. The OS scale factor is accunted for by QWindow::devicePixelRatio()
+ and similar functions.
+
+ Configuration Examples:
+
+ 'Classic': Device Independent Pixels = Native Pixels = Device Pixels
+ --------------------------------------------------- devicePixelRatio: 1
+ | Application / Qt Gui 100 x 100 |
+ | | Qt Scale Factor: 1
+ | Qt Platform / OS 100 x 100 |
+ | | OS Scale Factor: 1
+ | Display 100 x 100 |
+ -----------------------------------------------------
+
+ 'Retina Device': Device Independent Pixels = Native Pixels
+ --------------------------------------------------- devicePixelRatio: 2
+ | Application / Qt Gui 100 x 100 |
+ | | Qt Scale Factor: 1
+ | Qt Platform / OS 100 x 100 |
+ |---------------------------------------------------| OS Scale Factor: 2
+ | Display 200 x 200 |
+ -----------------------------------------------------
+
+ '2x Qt Scaling': Native Pixels = Device Pixels
+ --------------------------------------------------- devicePixelRatio: 2
+ | Application / Qt Gui 100 x 100 |
+ |---------------------------------------------------| Qt Scale Factor: 2
+ | Qt Platform / OS 200 x 200 |
+ | | OS Scale Factor: 1
+ | Display 200 x 200 |
+ -----------------------------------------------------
+
+ The Qt Scale Factor is the product of two sub-scale factors, which
+ are independently either set or determined by the platform plugin.
+ Several APIs are offered for this, targeting both developers and
+ end users. All scale factors are of type qreal.
+
+ 1) A global scale factor
+ The QT_SCALE_FACTOR environment variable can be used to set
+ a global scale factor for all windows in the processs. This
+ is useful for testing and debugging (you can simulate any
+ devicePixelRatio without needing access to sepcial hardware),
+ and perhaps also for targeting a specific application to
+ a specific display type (embedded use cases).
+
+ 2) A per-screen scale factors
+ Some platform plugins support providing a per-screen scale
+ factor based on display density information. These platforms
+ include X11, Windows, and Android.
+
+ There are two APIs for enabling or disabling this behavior:
+ - The QT_AUTO_SCREEN_SCALE_FACTOR environment variable.
+ - The AA_EnableHighDpiScaling and AA_DisableHighDpiScaling
+ application attributes
+
+ Enabling either will make QHighDpiScaling call QPlatformScreen::pixelDensity()
+ and use the value provided as the scale factor for the screen in
+ question. Disabling is done on a 'veto' basis where either the
+ environment or the application source can disable. The intended use
+ cases are 'My system is not providing correct display density
+ information' and 'My application needs to work in display pixels',
+ respectively.
+
+ The QT_SCREEN_SCALE_FACTORS environment variable can be used to set the screen
+ scale factors manually.Set this to a semicolon-separated
+ list of scale factors (matching the order of QGuiApplications::screens()),
+ or to a list of name=value pairs (where name matches QScreen::name()).
+
+ Coordinate conversion functions must be used when writing code that passes
+ geometry across the Qt Gui / Platform plugin boundary. The main conversion
+ functions are:
+ T toNativePixels(T, QWindow *)
+ T fromNativePixels(T, QWindow*)
+
+ The following classes in QtGui use native pixels, for the convenience of the
+ plataform plugins:
+ QPlatformWindow
+ QPlatformScreen
+ QWindowSystemInterface (API only - Events are in device independent pixels)
+
+ As a special consideration platform plugin code should be careful about
+ calling QtGui geometry accessor functions:
+ QRect r = window->geometry();
+ Here the returned geometry is in device independent pixels. Add a conversion call:
+ QRect r = QHighDpi::toNativePixels(window->geometry());
+ (Avoiding calling QWindow and instead using the QPlatformWindow geometry
+ might be a better course of action in this case.)
+*/
+
+qreal QHighDpiScaling::m_factor = 1.0;
+bool QHighDpiScaling::m_active = false; //"overall active" - is there any scale factor set.
+bool QHighDpiScaling::m_usePixelDensity = false; // use scale factor from platform plugin
+bool QHighDpiScaling::m_pixelDensityScalingActive = false; // pixel density scale factor > 1
+bool QHighDpiScaling::m_globalScalingActive = false; // global scale factor is active
+bool QHighDpiScaling::m_screenFactorSet = false; // QHighDpiScaling::setScreenFactor has been used
+QDpi QHighDpiScaling::m_logicalDpi = QDpi(-1,-1); // The scaled logical DPI of the primary screen
+
+/*
+ Initializes the QHighDpiScaling global variables. Called before the
+ platform plugin is created.
+*/
+
+static inline bool usePixelDensity()
+{
+ // Determine if we should set a scale factor based on the pixel density
+ // reported by the platform plugin. There are several enablers and several
+ // disablers. A single disable may veto all other enablers.
+ if (QCoreApplication::testAttribute(Qt::AA_DisableHighDpiScaling))
+ return false;
+ bool screenEnvValueOk;
+ const int screenEnvValue = qEnvironmentVariableIntValue(autoScreenEnvVar, &screenEnvValueOk);
+ if (screenEnvValueOk && screenEnvValue < 1)
+ return false;
+ return QCoreApplication::testAttribute(Qt::AA_EnableHighDpiScaling)
+ || (screenEnvValueOk && screenEnvValue > 0)
+ || (qEnvironmentVariableIsSet(legacyDevicePixelEnvVar) && qgetenv(legacyDevicePixelEnvVar).toLower() == "auto");
+}
+
+void QHighDpiScaling::initHighDpiScaling()
+{
+ // Determine if there is a global scale factor set.
+ m_factor = initialGlobalScaleFactor();
+ m_globalScalingActive = !qFuzzyCompare(m_factor, qreal(1));
+
+ m_usePixelDensity = usePixelDensity();
+
+ m_pixelDensityScalingActive = false; //set in updateHighDpiScaling below
+
+ // we update m_active in updateHighDpiScaling, but while we create the
+ // screens, we have to assume that m_usePixelDensity implies scaling
+ m_active = m_globalScalingActive || m_usePixelDensity;
+}
+
+void QHighDpiScaling::updateHighDpiScaling()
+{
+ if (QCoreApplication::testAttribute(Qt::AA_DisableHighDpiScaling))
+ return;
+
+ if (m_usePixelDensity && !m_pixelDensityScalingActive) {
+ Q_FOREACH (QScreen *screen, QGuiApplication::screens()) {
+ if (!qFuzzyCompare(screenSubfactor(screen->handle()), qreal(1))) {
+ m_pixelDensityScalingActive = true;
+ break;
+ }
+ }
+ }
+ if (qEnvironmentVariableIsSet(screenFactorsEnvVar)) {
+ int i = 0;
+ Q_FOREACH (const QByteArray &spec, qgetenv(screenFactorsEnvVar).split(';')) {
+ QScreen *screen = 0;
+ int equalsPos = spec.lastIndexOf('=');
+ double factor = 0;
+ if (equalsPos > 0) {
+ // support "name=factor"
+ QByteArray name = spec.mid(0, equalsPos);
+ QByteArray f = spec.mid(equalsPos + 1);
+ bool ok;
+ factor = f.toDouble(&ok);
+ if (ok) {
+ Q_FOREACH (QScreen *s, QGuiApplication::screens()) {
+ if (s->name() == QString::fromLocal8Bit(name)) {
+ screen = s;
+ break;
+ }
+ }
+ }
+ } else {
+ // listing screens in order
+ bool ok;
+ factor = spec.toDouble(&ok);
+ if (ok && i < QGuiApplication::screens().count())
+ screen = QGuiApplication::screens().at(i);
+ }
+ if (screen)
+ setScreenFactor(screen, factor);
+ ++i;
+ }
+ }
+ m_active = m_globalScalingActive || m_screenFactorSet || m_pixelDensityScalingActive;
+
+ QPlatformScreen *primaryScreen = QGuiApplication::primaryScreen()->handle();
+ qreal sf = screenSubfactor(primaryScreen);
+ QDpi primaryDpi = primaryScreen->logicalDpi();
+ m_logicalDpi = QDpi(primaryDpi.first / sf, primaryDpi.second / sf);
+}
+
+/*
+ Sets the global scale factor which is applied to all windows.
+*/
+void QHighDpiScaling::setGlobalFactor(qreal factor)
+{
+ if (qFuzzyCompare(factor, m_factor))
+ return;
+ if (!QGuiApplication::allWindows().isEmpty())
+ qWarning("QHighDpiScaling::setFactor: Should only be called when no windows exist.");
+
+ m_globalScalingActive = !qFuzzyCompare(factor, qreal(1));
+ m_factor = m_globalScalingActive ? factor : qreal(1);
+ m_active = m_globalScalingActive || m_screenFactorSet || m_pixelDensityScalingActive;
+ Q_FOREACH (QScreen *screen, QGuiApplication::screens())
+ screen->d_func()->updateHighDpi();
+}
+
+static const char scaleFactorProperty[] = "_q_scaleFactor";
+
+/*
+ Sets a per-screen scale factor.
+*/
+void QHighDpiScaling::setScreenFactor(QScreen *screen, qreal factor)
+{
+ m_screenFactorSet = true;
+ m_active = true;
+ screen->setProperty(scaleFactorProperty, QVariant(factor));
+
+ // hack to force re-evaluation of screen geometry
+ if (screen->handle())
+ screen->d_func()->setPlatformScreen(screen->handle()); // updates geometries based on scale factor
+}
+
+QPoint QHighDpiScaling::mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen)
+{
+ if (!platformScreen)
+ return pos;
+ const qreal scaleFactor = factor(platformScreen);
+ const QPoint topLeft = platformScreen->geometry().topLeft();
+ return (pos - topLeft) * scaleFactor + topLeft;
+}
+
+QPoint QHighDpiScaling::mapPositionFromNative(const QPoint &pos, const QPlatformScreen *platformScreen)
+{
+ if (!platformScreen)
+ return pos;
+ const qreal scaleFactor = factor(platformScreen);
+ const QPoint topLeft = platformScreen->geometry().topLeft();
+ return (pos - topLeft) / scaleFactor + topLeft;
+}
+
+qreal QHighDpiScaling::screenSubfactor(const QPlatformScreen *screen)
+{
+ qreal factor = qreal(1.0);
+ if (screen) {
+ if (m_usePixelDensity)
+ factor *= screen->pixelDensity();
+ if (m_screenFactorSet) {
+ QVariant screenFactor = screen->screen()->property(scaleFactorProperty);
+ if (screenFactor.isValid())
+ factor *= screenFactor.toReal();
+ }
+ }
+ return factor;
+}
+
+QDpi QHighDpiScaling::logicalDpi()
+{
+ return m_logicalDpi;
+}
+
+qreal QHighDpiScaling::factor(const QScreen *screen)
+{
+ // Fast path for when scaling in Qt is not used at all.
+ if (!m_active)
+ return qreal(1.0);
+
+ // The effective factor for a given screen is the product of the
+ // screen and global sub-factors
+ qreal factor = m_factor;
+ if (screen)
+ factor *= screenSubfactor(screen->handle());
+ return factor;
+}
+
+qreal QHighDpiScaling::factor(const QPlatformScreen *platformScreen)
+{
+ if (!m_active)
+ return qreal(1.0);
+
+ return m_factor * screenSubfactor(platformScreen);
+}
+
+qreal QHighDpiScaling::factor(const QWindow *window)
+{
+ if (!m_active)
+ return qreal(1.0);
+
+ return factor(window ? window->screen() : QGuiApplication::primaryScreen());
+}
+
+QPoint QHighDpiScaling::origin(const QScreen *screen)
+{
+ return screen->geometry().topLeft();
+}
+
+QPoint QHighDpiScaling::origin(const QPlatformScreen *platformScreen)
+{
+ return platformScreen->geometry().topLeft();
+}
+
+#endif //QT_NO_HIGHDPISCALING
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h
new file mode 100644
index 0000000000..9e33787f53
--- /dev/null
+++ b/src/gui/kernel/qhighdpiscaling_p.h
@@ -0,0 +1,514 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHIGHDPISCALING_P_H
+#define QHIGHDPISCALING_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qmargins.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qvector.h>
+#include <QtCore/qloggingcategory.h>
+#include <QtGui/qregion.h>
+#include <QtGui/qscreen.h>
+#include <QtGui/qwindow.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(lcScaling);
+
+class QScreen;
+class QPlatformScreen;
+typedef QPair<qreal, qreal> QDpi;
+
+#ifndef QT_NO_HIGHDPISCALING
+class Q_GUI_EXPORT QHighDpiScaling {
+public:
+ static void initHighDpiScaling();
+ static void updateHighDpiScaling();
+ static void setGlobalFactor(qreal factor);
+ static void setScreenFactor(QScreen *window, qreal factor);
+
+ static bool isActive() { return m_active; }
+ static qreal factor(const QWindow *window);
+ static qreal factor(const QScreen *screen);
+ static qreal factor(const QPlatformScreen *platformScreen);
+ static QPoint origin(const QScreen *screen);
+ static QPoint origin(const QPlatformScreen *platformScreen);
+ static QPoint mapPositionFromNative(const QPoint &pos, const QPlatformScreen *platformScreen);
+ static QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen);
+ static QDpi logicalDpi();
+
+private:
+ static qreal screenSubfactor(const QPlatformScreen *screen);
+
+ static qreal m_factor;
+ static bool m_active;
+ static bool m_usePixelDensity;
+ static bool m_globalScalingActive;
+ static bool m_pixelDensityScalingActive;
+ static bool m_screenFactorSet;
+ static QDpi m_logicalDpi;
+};
+
+// Coordinate system conversion functions:
+// QHighDpi::fromNativePixels : from physical(screen/backing) to logical pixels
+// QHighDpi::toNativePixels : from logical to physical pixels
+
+namespace QHighDpi {
+
+inline QPointF fromNative(const QPointF &pos, qreal scaleFactor, const QPointF &origin)
+{
+ return (pos - origin) / scaleFactor + origin;
+}
+
+inline QPointF toNative(const QPointF &pos, qreal scaleFactor, const QPointF &origin)
+{
+ return (pos - origin) * scaleFactor + origin;
+}
+
+inline QPoint fromNative(const QPoint &pos, qreal scaleFactor, const QPoint &origin)
+{
+ return (pos - origin) / scaleFactor + origin;
+}
+
+inline QPoint toNative(const QPoint &pos, qreal scaleFactor, const QPoint &origin)
+{
+ return (pos - origin) * scaleFactor + origin;
+}
+
+inline QPoint fromNative(const QPoint &pos, qreal scaleFactor)
+{
+ return pos / scaleFactor;
+}
+
+inline QPoint toNative(const QPoint &pos, qreal scaleFactor)
+{
+ return pos * scaleFactor;
+}
+
+inline QSize fromNative(const QSize &size, qreal scaleFactor)
+{
+ return size / scaleFactor; // TODO: should we round up?
+}
+
+inline QSize toNative(const QSize &size, qreal scaleFactor)
+{
+ return size * scaleFactor;
+}
+
+inline QSizeF fromNative(const QSizeF &size, qreal scaleFactor)
+{
+ return size / scaleFactor;
+}
+
+inline QSizeF toNative(const QSizeF &size, qreal scaleFactor)
+{
+ return size * scaleFactor;
+}
+
+inline QRect fromNative(const QRect &rect, qreal scaleFactor, const QPoint &origin)
+{
+ return QRect(fromNative(rect.topLeft(), scaleFactor, origin), fromNative(rect.size(), scaleFactor));
+}
+
+inline QRect toNative(const QRect &rect, qreal scaleFactor, const QPoint &origin)
+{
+ return QRect(toNative(rect.topLeft(), scaleFactor, origin), toNative(rect.size(), scaleFactor));
+
+}
+
+inline QRect fromNative(const QRect &rect, const QScreen *screen, const QPoint &screenOrigin)
+{
+ return toNative(rect, QHighDpiScaling::factor(screen), screenOrigin);
+}
+
+inline QRect fromNativeScreenGeometry(const QRect &nativeScreenGeometry, const QScreen *screen)
+{
+ return QRect(nativeScreenGeometry.topLeft(),
+ fromNative(nativeScreenGeometry.size(), QHighDpiScaling::factor(screen)));
+}
+
+inline QPoint fromNativeLocalPosition(const QPoint &pos, const QWindow *window)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return pos / scaleFactor;
+}
+
+inline QPoint toNativeLocalPosition(const QPoint &pos, const QWindow *window)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return pos * scaleFactor;
+}
+
+inline QPointF fromNativeLocalPosition(const QPointF &pos, const QWindow *window)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return pos / scaleFactor;
+}
+
+inline QPointF toNativeLocalPosition(const QPointF &pos, const QWindow *window)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return pos * scaleFactor;
+}
+
+inline QRect fromNativePixels(const QRect &pixelRect, const QPlatformScreen *platformScreen)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(platformScreen);
+ const QPoint origin = QHighDpiScaling::origin(platformScreen);
+ return QRect(fromNative(pixelRect.topLeft(), scaleFactor, origin),
+ fromNative(pixelRect.size(), scaleFactor));
+}
+
+inline QRect toNativePixels(const QRect &pointRect, const QPlatformScreen *platformScreen)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(platformScreen);
+ const QPoint origin = QHighDpiScaling::origin(platformScreen);
+ return QRect(toNative(pointRect.topLeft(), scaleFactor, origin),
+ toNative(pointRect.size(), scaleFactor));
+}
+
+inline QRect fromNativePixels(const QRect &pixelRect, const QScreen *screen)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(screen);
+ const QPoint origin = QHighDpiScaling::origin(screen);
+ return QRect(fromNative(pixelRect.topLeft(), scaleFactor, origin),
+ fromNative(pixelRect.size(), scaleFactor));
+}
+
+inline QRect toNativePixels(const QRect &pointRect, const QScreen *screen)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(screen);
+ const QPoint origin = QHighDpiScaling::origin(screen);
+ return QRect(toNative(pointRect.topLeft(), scaleFactor, origin),
+ toNative(pointRect.size(), scaleFactor));
+}
+
+inline QRect fromNativePixels(const QRect &pixelRect, const QWindow *window)
+{
+ if (window && window->isTopLevel() && window->screen()) {
+ return fromNativePixels(pixelRect, window->screen());
+ } else {
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return QRect(pixelRect.topLeft() / scaleFactor, fromNative(pixelRect.size(), scaleFactor));
+ }
+}
+
+inline QRectF toNativePixels(const QRectF &pointRect, const QScreen *screen)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(screen);
+ const QPoint origin = QHighDpiScaling::origin(screen);
+ return QRectF(toNative(pointRect.topLeft(), scaleFactor, origin),
+ toNative(pointRect.size(), scaleFactor));
+}
+
+inline QRect toNativePixels(const QRect &pointRect, const QWindow *window)
+{
+ if (window && window->isTopLevel() && window->screen()) {
+ return toNativePixels(pointRect, window->screen());
+ } else {
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return QRect(pointRect.topLeft() * scaleFactor, toNative(pointRect.size(), scaleFactor));
+ }
+}
+
+inline QRectF fromNativePixels(const QRectF &pixelRect, const QScreen *screen)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(screen);
+ const QPoint origin = QHighDpiScaling::origin(screen);
+ return QRectF(fromNative(pixelRect.topLeft(), scaleFactor, origin),
+ fromNative(pixelRect.size(), scaleFactor));
+}
+
+inline QRectF fromNativePixels(const QRectF &pixelRect, const QWindow *window)
+{
+ if (window && window->isTopLevel() && window->screen()) {
+ return fromNativePixels(pixelRect, window->screen());
+ } else {
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return QRectF(pixelRect.topLeft() / scaleFactor, pixelRect.size() / scaleFactor);
+ }
+}
+
+inline QRectF toNativePixels(const QRectF &pointRect, const QWindow *window)
+{
+ if (window && window->isTopLevel() && window->screen()) {
+ return toNativePixels(pointRect, window->screen());
+ } else {
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return QRectF(pointRect.topLeft() * scaleFactor, pointRect.size() * scaleFactor);
+ }
+}
+
+inline QSize fromNativePixels(const QSize &pixelSize, const QWindow *window)
+{
+ return pixelSize / QHighDpiScaling::factor(window);
+}
+
+inline QSize toNativePixels(const QSize &pointSize, const QWindow *window)
+{
+ return pointSize * QHighDpiScaling::factor(window);
+}
+
+inline QSizeF fromNativePixels(const QSizeF &pixelSize, const QWindow *window)
+{
+ return pixelSize / QHighDpiScaling::factor(window);
+}
+
+inline QSizeF toNativePixels(const QSizeF &pointSize, const QWindow *window)
+{
+ return pointSize * QHighDpiScaling::factor(window);
+}
+
+inline QPoint fromNativePixels(const QPoint &pixelPoint, const QScreen *screen)
+{
+ return fromNative(pixelPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen));
+}
+
+inline QPoint fromNativePixels(const QPoint &pixelPoint, const QWindow *window)
+{
+ if (window && window->isTopLevel() && window->screen())
+ return fromNativePixels(pixelPoint, window->screen());
+ else
+ return pixelPoint / QHighDpiScaling::factor(window);
+}
+
+inline QPoint toNativePixels(const QPoint &pointPoint, const QScreen *screen)
+{
+ return toNative(pointPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen));
+}
+
+inline QPoint toNativePixels(const QPoint &pointPoint, const QWindow *window)
+{
+ if (window && window->isTopLevel() && window->screen())
+ return toNativePixels(pointPoint, window->screen());
+ else
+ return pointPoint * QHighDpiScaling::factor(window);
+}
+
+inline QPointF fromNativePixels(const QPointF &pixelPoint, const QScreen *screen)
+{
+ return fromNative(pixelPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen));
+}
+
+inline QPointF fromNativePixels(const QPointF &pixelPoint, const QWindow *window)
+{
+ if (window && window->isTopLevel() && window->screen())
+ return fromNativePixels(pixelPoint, window->screen());
+ else
+ return pixelPoint / QHighDpiScaling::factor(window);
+}
+
+inline QPointF toNativePixels(const QPointF &pointPoint, const QScreen *screen)
+{
+ return toNative(pointPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen));
+}
+
+inline QPointF toNativePixels(const QPointF &pointPoint, const QWindow *window)
+{
+ if (window && window->isTopLevel() && window->screen())
+ return toNativePixels(pointPoint, window->screen());
+ else
+ return pointPoint * QHighDpiScaling::factor(window);
+}
+
+inline QMargins fromNativePixels(const QMargins &pixelMargins, const QWindow *window)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return QMargins(pixelMargins.left() / scaleFactor, pixelMargins.top() / scaleFactor,
+ pixelMargins.right() / scaleFactor, pixelMargins.bottom() / scaleFactor);
+}
+
+inline QMargins toNativePixels(const QMargins &pointMargins, const QWindow *window)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return QMargins(pointMargins.left() * scaleFactor, pointMargins.top() * scaleFactor,
+ pointMargins.right() * scaleFactor, pointMargins.bottom() * scaleFactor);
+}
+
+inline QRegion fromNativeLocalRegion(const QRegion &pixelRegion, const QWindow *window)
+{
+ if (!QHighDpiScaling::isActive())
+ return pixelRegion;
+
+ qreal scaleFactor = QHighDpiScaling::factor(window);
+ QRegion pointRegion;
+ foreach (const QRect &rect, pixelRegion.rects()) {
+ pointRegion += QRect(fromNative(rect.topLeft(), scaleFactor),
+ fromNative(rect.size(), scaleFactor));
+ }
+ return pointRegion;
+}
+
+inline QRegion toNativeLocalRegion(const QRegion &pointRegion, const QWindow *window)
+{
+ if (!QHighDpiScaling::isActive())
+ return pointRegion;
+
+ qreal scaleFactor = QHighDpiScaling::factor(window);
+ QRegion pixelRegon;
+ foreach (const QRect &rect, pointRegion.rects()) {
+ pixelRegon += QRect(toNative(rect.topLeft(), scaleFactor),
+ toNative(rect.size(), scaleFactor));
+ }
+ return pixelRegon;
+}
+
+// Any T that has operator/()
+template <typename T>
+T fromNativePixels(const T &pixelValue, const QWindow *window)
+{
+ if (!QHighDpiScaling::isActive())
+ return pixelValue;
+
+ return pixelValue / QHighDpiScaling::factor(window);
+
+}
+
+ //##### ?????
+template <typename T>
+T fromNativePixels(const T &pixelValue, const QScreen *screen)
+{
+ if (!QHighDpiScaling::isActive())
+ return pixelValue;
+
+ return pixelValue / QHighDpiScaling::factor(screen);
+
+}
+
+// Any T that has operator*()
+template <typename T>
+T toNativePixels(const T &pointValue, const QWindow *window)
+{
+ if (!QHighDpiScaling::isActive())
+ return pointValue;
+
+ return pointValue * QHighDpiScaling::factor(window);
+}
+
+template <typename T>
+T toNativePixels(const T &pointValue, const QScreen *screen)
+{
+ if (!QHighDpiScaling::isActive())
+ return pointValue;
+
+ return pointValue * QHighDpiScaling::factor(screen);
+}
+
+
+// Any QVector<T> where T has operator/()
+template <typename T>
+QVector<T> fromNativePixels(const QVector<T> &pixelValues, const QWindow *window)
+{
+ if (!QHighDpiScaling::isActive())
+ return pixelValues;
+
+ QVector<T> pointValues;
+ foreach (const T& pixelValue, pixelValues)
+ pointValues.append(pixelValue / QHighDpiScaling::factor(window));
+ return pointValues;
+}
+
+// Any QVector<T> where T has operator*()
+template <typename T>
+QVector<T> toNativePixels(const QVector<T> &pointValues, const QWindow *window)
+{
+ if (!QHighDpiScaling::isActive())
+ return pointValues;
+
+ QVector<T> pixelValues;
+ foreach (const T& pointValue, pointValues)
+ pixelValues.append(pointValue * QHighDpiScaling::factor(window));
+ return pixelValues;
+}
+
+} // namespace QHighDpi
+#else // QT_NO_HIGHDPISCALING
+class Q_GUI_EXPORT QHighDpiScaling {
+public:
+ static inline void initHighDpiScaling() {}
+ static inline void updateHighDpiScaling() {}
+ static inline void setGlobalFactor(qreal) {}
+ static inline void setScreenFactor(QScreen *, qreal) {}
+
+ static inline bool isActive() { return false; }
+ static inline qreal factor(const QWindow *) { return 1.0; }
+ static inline qreal factor(const QScreen *) { return 1.0; }
+ static inline qreal factor(const QPlatformScreen *) { return 1.0; }
+ static inline QPoint origin(const QScreen *) { return QPoint(); }
+ static inline QPoint origin(const QPlatformScreen *) { return QPoint(); }
+ static inline QPoint mapPositionFromNative(const QPoint &pos, const QPlatformScreen *) { return pos; }
+ static inline QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *) { return pos; }
+ static inline QDpi logicalDpi() { return QDpi(-1,-1); }
+};
+
+namespace QHighDpi {
+ template <typename T> inline
+ T toNative(const T &value, ...) { return value; }
+ template <typename T> inline
+ T fromNative(const T &value, ...) { return value; }
+
+ template <typename T> inline
+ T fromNativeLocalPosition(const T &value, ...) { return value; }
+ template <typename T> inline
+ T toNativeLocalPosition(const T &value, ...) { return value; }
+
+ template <typename T> inline
+ T fromNativeLocalRegion(const T &value, ...) { return value; }
+ template <typename T> inline
+ T toNativeLocalRegion(const T &value, ...) { return value; }
+
+ template <typename T> inline
+ T fromNativeScreenGeometry(const T &value, ...) { return value; }
+
+ template <typename T, typename U> inline
+ T toNativePixels(const T &value, const U*) {return value;}
+ template <typename T, typename U> inline
+ T fromNativePixels(const T &value, const U*) {return value;}
+}
+#endif // QT_NO_HIGHDPISCALING
+QT_END_NAMESPACE
+
+#endif // QHIGHDPISCALING_P_H
diff --git a/src/gui/kernel/qinputmethod.cpp b/src/gui/kernel/qinputmethod.cpp
index 8d51be853a..2684c43518 100644
--- a/src/gui/kernel/qinputmethod.cpp
+++ b/src/gui/kernel/qinputmethod.cpp
@@ -147,6 +147,9 @@ QRectF QInputMethod::cursorRectangle() const
/*!
\property QInputMethod::keyboardRectangle
\brief Virtual keyboard's geometry in window coordinates.
+
+ This might be an empty rectangle if it is not possible to know the geometry
+ of the keyboard. This is the case for a floating keyboard on android.
*/
QRectF QInputMethod::keyboardRectangle() const
{
diff --git a/src/gui/kernel/qinputmethod.h b/src/gui/kernel/qinputmethod.h
index 3e801bff3c..d7a7b1db8a 100644
--- a/src/gui/kernel/qinputmethod.h
+++ b/src/gui/kernel/qinputmethod.h
@@ -82,7 +82,7 @@ public:
QLocale locale() const;
Qt::LayoutDirection inputDirection() const;
- static QVariant queryFocusObject(Qt::InputMethodQuery query, QVariant argument);
+ static QVariant queryFocusObject(Qt::InputMethodQuery query, QVariant argument); // ### Qt 6: QVariant by const-ref
public Q_SLOTS:
void show();
diff --git a/src/gui/kernel/qkeymapper_p.h b/src/gui/kernel/qkeymapper_p.h
index 20dcbbc139..34003cdf41 100644
--- a/src/gui/kernel/qkeymapper_p.h
+++ b/src/gui/kernel/qkeymapper_p.h
@@ -50,7 +50,6 @@
#include <qlist.h>
#include <qlocale.h>
#include <qevent.h>
-#include <qhash.h>
QT_BEGIN_NAMESPACE
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index 5bf22b9394..881d7cc76a 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -39,6 +39,7 @@
#ifndef QT_NO_SHORTCUT
#include "qdebug.h"
+#include <QtCore/qhashfunctions.h>
#ifndef QT_NO_REGEXP
# include "qregexp.h"
#endif
@@ -290,6 +291,7 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni
\row \li InsertParagraphSeparator \li Enter \li Enter \li Enter \li Enter
\row \li InsertLineSeparator \li Shift+Enter \li Meta+Enter, Meta+O \li Shift+Enter \li Shift+Enter
\row \li Backspace \li (none) \li Meta+H \li (none) \li (none)
+ \row \li Cancel \li Escape \li Escape, Ctrl+. \li Escape \li Escape
\endtable
Note that, since the key sequences used for the standard shortcuts differ
@@ -751,6 +753,7 @@ static const struct {
\value ZoomIn Zoom in.
\value ZoomOut Zoom out.
\value FullScreen Toggle the window state to/from full screen.
+ \value Cancel Cancel the current operation.
*/
/*!
@@ -818,6 +821,7 @@ QKeySequence::QKeySequence(const QString &key, QKeySequence::SequenceFormat form
assign(key, format);
}
+Q_STATIC_ASSERT_X(QKeySequencePrivate::MaxKeyCount == 4, "Change docs and ctor impl below");
/*!
Constructs a key sequence with up to 4 keys \a k1, \a k2,
\a k3 and \a k4.
@@ -876,26 +880,19 @@ QKeySequence::~QKeySequence()
void QKeySequence::setKey(int key, int index)
{
- Q_ASSERT_X(index >= 0 && index < 4, "QKeySequence::setKey", "index out of range");
+ Q_ASSERT_X(index >= 0 && index < QKeySequencePrivate::MaxKeyCount, "QKeySequence::setKey", "index out of range");
qAtomicDetach(d);
d->key[index] = key;
}
+Q_STATIC_ASSERT_X(QKeySequencePrivate::MaxKeyCount == 4, "Change docs below");
/*!
Returns the number of keys in the key sequence.
The maximum is 4.
*/
int QKeySequence::count() const
{
- if (!d->key[0])
- return 0;
- if (!d->key[1])
- return 1;
- if (!d->key[2])
- return 2;
- if (!d->key[3])
- return 3;
- return 4;
+ return int(std::distance(d->key, std::find(d->key, d->key + QKeySequencePrivate::MaxKeyCount, 0)));
}
@@ -987,8 +984,8 @@ int QKeySequence::assign(const QString &ks, QKeySequence::SequenceFormat format)
int p = 0, diff = 0;
// Run through the whole string, but stop
- // if we have 4 keys before the end.
- while (keyseq.length() && n < 4) {
+ // if we have MaxKeyCount keys before the end.
+ while (keyseq.length() && n < QKeySequencePrivate::MaxKeyCount) {
// We MUST use something to separate each sequence, and space
// does not cut it, since some of the key names have space
// in them.. (Let's hope no one translate with a comma in it:)
@@ -1022,9 +1019,10 @@ struct QModifKeyName {
int qt_key;
QString name;
};
+Q_DECLARE_TYPEINFO(QModifKeyName, Q_MOVABLE_TYPE);
-Q_GLOBAL_STATIC(QList<QModifKeyName>, globalModifs)
-Q_GLOBAL_STATIC(QList<QModifKeyName>, globalPortableModifs)
+Q_GLOBAL_STATIC(QVector<QModifKeyName>, globalModifs)
+Q_GLOBAL_STATIC(QVector<QModifKeyName>, globalPortableModifs)
/*!
Constructs a single key from the string \a str.
@@ -1040,7 +1038,7 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence
QString accel = str.toLower();
bool nativeText = (format == QKeySequence::NativeText);
- QList<QModifKeyName> *gmodifs;
+ QVector<QModifKeyName> *gmodifs;
if (nativeText) {
gmodifs = globalModifs();
if (gmodifs->isEmpty()) {
@@ -1076,7 +1074,7 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence
if (!gmodifs) return ret;
- QList<QModifKeyName> modifs;
+ QVector<QModifKeyName> modifs;
if (nativeText) {
modifs << QModifKeyName(Qt::CTRL, QCoreApplication::translate("QShortcut", "Ctrl").toLower().append(QLatin1Char('+')))
<< QModifKeyName(Qt::SHIFT, QCoreApplication::translate("QShortcut", "Shift").toLower().append(QLatin1Char('+')))
@@ -1100,7 +1098,7 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence
int i = 0;
int lastI = 0;
while ((i = sl.indexOf(QLatin1Char('+'), i + 1)) != -1) {
- const QString sub = sl.mid(lastI, i - lastI + 1);
+ const QStringRef sub = sl.midRef(lastI, i - lastI + 1);
// If we get here the shortcuts contains at least one '+'. We break up
// along the following strategy:
// Meta+Ctrl++ ( "Meta+", "Ctrl+", "+" )
@@ -1366,7 +1364,7 @@ QKeySequence::operator QVariant() const
*/
int QKeySequence::operator[](uint index) const
{
- Q_ASSERT_X(index < 4, "QKeySequence::operator[]", "index out of range");
+ Q_ASSERT_X(index < QKeySequencePrivate::MaxKeyCount, "QKeySequence::operator[]", "index out of range");
return d->key[index];
}
@@ -1409,6 +1407,16 @@ bool QKeySequence::operator==(const QKeySequence &other) const
d->key[3] == other.d->key[3]);
}
+/*!
+ \since 5.6
+
+ Calculates the hash value of \a key, using
+ \a seed to seed the calculation.
+*/
+uint qHash(const QKeySequence &key, uint seed) Q_DECL_NOTHROW
+{
+ return qHashRange(key.d->key, key.d->key + QKeySequencePrivate::MaxKeyCount, seed);
+}
/*!
Provides an arbitrary comparison of this key sequence and
@@ -1424,10 +1432,8 @@ bool QKeySequence::operator==(const QKeySequence &other) const
*/
bool QKeySequence::operator< (const QKeySequence &other) const
{
- for (int i = 0; i < 4; ++i)
- if (d->key[i] != other.d->key[i])
- return d->key[i] < other.d->key[i];
- return false;
+ return std::lexicographical_compare(d->key, d->key + QKeySequencePrivate::MaxKeyCount,
+ other.d->key, other.d->key + QKeySequencePrivate::MaxKeyCount);
}
/*!
@@ -1523,6 +1529,7 @@ QList<QKeySequence> QKeySequence::listFromString(const QString &str, SequenceFor
QList<QKeySequence> result;
QStringList strings = str.split(QLatin1String("; "));
+ result.reserve(strings.count());
foreach (const QString &string, strings) {
result << fromString(string, format);
}
@@ -1565,15 +1572,14 @@ QString QKeySequence::listToString(const QList<QKeySequence> &list, SequenceForm
*/
QDataStream &operator<<(QDataStream &s, const QKeySequence &keysequence)
{
- QList<quint32> list;
- list << keysequence.d->key[0];
-
- if (s.version() >= 5 && keysequence.count() > 1) {
- list << keysequence.d->key[1];
- list << keysequence.d->key[2];
- list << keysequence.d->key[3];
+ Q_STATIC_ASSERT_X(QKeySequencePrivate::MaxKeyCount == 4, "Forgot to adapt QDataStream &operator<<(QDataStream &s, const QKeySequence &keysequence) to new QKeySequence::MaxKeyCount");
+ const bool extended = s.version() >= 5 && keysequence.count() > 1;
+ s << quint32(extended ? 4 : 1) << quint32(keysequence.d->key[0]);
+ if (extended) {
+ s << quint32(keysequence.d->key[1])
+ << quint32(keysequence.d->key[2])
+ << quint32(keysequence.d->key[3]);
}
- s << list;
return s;
}
@@ -1588,11 +1594,19 @@ QDataStream &operator<<(QDataStream &s, const QKeySequence &keysequence)
*/
QDataStream &operator>>(QDataStream &s, QKeySequence &keysequence)
{
+ const quint32 MaxKeys = QKeySequencePrivate::MaxKeyCount;
+ quint32 c;
+ s >> c;
+ quint32 keys[MaxKeys] = {0};
+ for (uint i = 0; i < qMin(c, MaxKeys); ++i) {
+ if (s.atEnd()) {
+ qWarning("Premature EOF while reading QKeySequence");
+ return s;
+ }
+ s >> keys[i];
+ }
qAtomicDetach(keysequence.d);
- QList<quint32> list;
- s >> list;
- for (int i = 0; i < 4; ++i)
- keysequence.d->key[i] = list.value(i);
+ std::copy(keys, keys + MaxKeys, keysequence.d->key);
return s;
}
diff --git a/src/gui/kernel/qkeysequence.h b/src/gui/kernel/qkeysequence.h
index cd7af5718f..98a611aab5 100644
--- a/src/gui/kernel/qkeysequence.h
+++ b/src/gui/kernel/qkeysequence.h
@@ -43,11 +43,12 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_SHORTCUT
+class QKeySequence;
+
/*****************************************************************************
QKeySequence stream functions
*****************************************************************************/
#ifndef QT_NO_DATASTREAM
-class QKeySequence;
Q_GUI_EXPORT QDataStream &operator<<(QDataStream &in, const QKeySequence &ks);
Q_GUI_EXPORT QDataStream &operator>>(QDataStream &out, QKeySequence &ks);
#endif
@@ -59,6 +60,8 @@ void qt_set_sequence_auto_mnemonic(bool b);
class QVariant;
class QKeySequencePrivate;
+Q_GUI_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QKeySequence &key, uint seed = 0) Q_DECL_NOTHROW;
+
class Q_GUI_EXPORT QKeySequence
{
Q_GADGET
@@ -134,7 +137,8 @@ public:
FullScreen,
Deselect,
DeleteCompleteLine,
- Backspace
+ Backspace,
+ Cancel
};
Q_ENUM(StandardKey)
@@ -177,10 +181,10 @@ public:
int operator[](uint i) const;
QKeySequence &operator=(const QKeySequence &other);
#ifdef Q_COMPILER_RVALUE_REFS
- inline QKeySequence &operator=(QKeySequence &&other)
- { qSwap(d, other.d); return *this; }
+ QKeySequence &operator=(QKeySequence &&other) Q_DECL_NOTHROW { swap(other); return *this; }
#endif
- inline void swap(QKeySequence &other) { qSwap(d, other.d); }
+ void swap(QKeySequence &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
+
bool operator==(const QKeySequence &other) const;
inline bool operator!= (const QKeySequence &other) const
{ return !(*this == other); }
@@ -204,6 +208,7 @@ private:
friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &in, const QKeySequence &ks);
friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &in, QKeySequence &ks);
+ friend Q_GUI_EXPORT uint qHash(const QKeySequence &key, uint seed) Q_DECL_NOTHROW;
friend class QShortcutMap;
friend class QShortcut;
diff --git a/src/gui/kernel/qkeysequence_p.h b/src/gui/kernel/qkeysequence_p.h
index 97416943d0..3e4c5bae88 100644
--- a/src/gui/kernel/qkeysequence_p.h
+++ b/src/gui/kernel/qkeysequence_p.h
@@ -47,6 +47,8 @@
#include "qkeysequence.h"
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
#ifndef QT_NO_SHORTCUT
@@ -61,20 +63,17 @@ struct Q_AUTOTEST_EXPORT QKeyBinding
class Q_AUTOTEST_EXPORT QKeySequencePrivate
{
public:
- enum { MaxKeyCount = 4 }; // used in QKeySequenceEdit
+ enum { MaxKeyCount = 4 }; // also used in QKeySequenceEdit
inline QKeySequencePrivate() : ref(1)
{
- key[0] = key[1] = key[2] = key[3] = 0;
+ std::fill_n(key, uint(MaxKeyCount), 0);
}
inline QKeySequencePrivate(const QKeySequencePrivate &copy) : ref(1)
{
- key[0] = copy.key[0];
- key[1] = copy.key[1];
- key[2] = copy.key[2];
- key[3] = copy.key[3];
+ std::copy(copy.key, copy.key + MaxKeyCount, key);
}
QAtomicInt ref;
- int key[4];
+ int key[MaxKeyCount];
static QString encodeString(int key, QKeySequence::SequenceFormat format);
static int decodeString(const QString &keyStr, QKeySequence::SequenceFormat format);
};
diff --git a/src/gui/kernel/qoffscreensurface.h b/src/gui/kernel/qoffscreensurface.h
index 909a1ef256..17bc8a7d17 100644
--- a/src/gui/kernel/qoffscreensurface.h
+++ b/src/gui/kernel/qoffscreensurface.h
@@ -51,7 +51,7 @@ class Q_GUI_EXPORT QOffscreenSurface : public QObject, public QSurface
public:
- explicit QOffscreenSurface(QScreen *screen = 0);
+ explicit QOffscreenSurface(QScreen *screen = Q_NULLPTR);
virtual ~QOffscreenSurface();
SurfaceType surfaceType() const Q_DECL_OVERRIDE;
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
index 56a3729a4a..3c033ea39e 100644
--- a/src/gui/kernel/qopenglcontext.cpp
+++ b/src/gui/kernel/qopenglcontext.cpp
@@ -226,7 +226,7 @@ public:
QOpenGLContext *context;
};
-static QThreadStorage<QGuiGLThreadContext *> qwindow_context_storage;
+Q_GLOBAL_STATIC(QThreadStorage<QGuiGLThreadContext *>, qwindow_context_storage);
static QOpenGLContext *global_share_context = 0;
#ifndef QT_NO_DEBUG
@@ -336,14 +336,14 @@ QOpenGLContext *qt_gl_global_share_context()
*/
QOpenGLContext *QOpenGLContextPrivate::setCurrentContext(QOpenGLContext *context)
{
- QGuiGLThreadContext *threadContext = qwindow_context_storage.localData();
+ QGuiGLThreadContext *threadContext = qwindow_context_storage()->localData();
if (!threadContext) {
if (!QThread::currentThread()) {
qWarning("No QTLS available. currentContext won't work");
return 0;
}
threadContext = new QGuiGLThreadContext;
- qwindow_context_storage.setLocalData(threadContext);
+ qwindow_context_storage()->setLocalData(threadContext);
}
QOpenGLContext *previous = threadContext->context;
threadContext->context = context;
@@ -412,8 +412,8 @@ int QOpenGLContextPrivate::maxTextureSize()
*/
QOpenGLContext* QOpenGLContext::currentContext()
{
- QGuiGLThreadContext *threadContext = qwindow_context_storage.localData();
- if(threadContext) {
+ QGuiGLThreadContext *threadContext = qwindow_context_storage()->localData();
+ if (threadContext) {
return threadContext->context;
}
return 0;
@@ -462,8 +462,7 @@ QPlatformOpenGLContext *QOpenGLContext::shareHandle() const
QOpenGLContext::QOpenGLContext(QObject *parent)
: QObject(*new QOpenGLContextPrivate(), parent)
{
- Q_D(QOpenGLContext);
- d->screen = QGuiApplication::primaryScreen();
+ setScreen(QGuiApplication::primaryScreen());
}
/*!
@@ -499,9 +498,20 @@ void QOpenGLContext::setShareContext(QOpenGLContext *shareContext)
void QOpenGLContext::setScreen(QScreen *screen)
{
Q_D(QOpenGLContext);
+ if (d->screen)
+ disconnect(d->screen, SIGNAL(destroyed(QObject*)), this, SLOT(_q_screenDestroyed(QObject*)));
d->screen = screen;
if (!d->screen)
d->screen = QGuiApplication::primaryScreen();
+ if (d->screen)
+ connect(d->screen, SIGNAL(destroyed(QObject*)), this, SLOT(_q_screenDestroyed(QObject*)));
+}
+
+void QOpenGLContextPrivate::_q_screenDestroyed(QObject *object)
+{
+ Q_Q(QOpenGLContext);
+ if (object == static_cast<QObject *>(screen))
+ q->setScreen(0);
}
/*!
@@ -719,6 +729,28 @@ QOpenGLFunctions *QOpenGLContext::functions() const
}
/*!
+ Get the QOpenGLExtraFunctions instance for this context.
+
+ QOpenGLContext offers this as a convenient way to access QOpenGLExtraFunctions
+ without having to manage it manually.
+
+ The context or a sharing context must be current.
+
+ The returned QOpenGLExtraFunctions instance is ready to be used and it
+ does not need initializeOpenGLFunctions() to be called.
+
+ \note QOpenGLExtraFunctions contains functionality that is not guaranteed to
+ be available at runtime. Runtime availability depends on the platform,
+ graphics driver, and the OpenGL version requested by the application.
+
+ \sa QOpenGLFunctions, QOpenGLExtraFunctions
+*/
+QOpenGLExtraFunctions *QOpenGLContext::extraFunctions() const
+{
+ return static_cast<QOpenGLExtraFunctions *>(functions());
+}
+
+/*!
\fn T *QOpenGLContext::versionFunctions() const
\overload versionFunctions()
@@ -1427,11 +1459,11 @@ void QOpenGLContextGroupPrivate::deletePendingResources(QOpenGLContext *ctx)
{
QMutexLocker locker(&m_mutex);
- QList<QOpenGLSharedResource *> pending = m_pendingDeletion;
+ const QList<QOpenGLSharedResource *> pending = m_pendingDeletion;
m_pendingDeletion.clear();
- QList<QOpenGLSharedResource *>::iterator it = pending.begin();
- QList<QOpenGLSharedResource *>::iterator end = pending.end();
+ QList<QOpenGLSharedResource *>::const_iterator it = pending.begin();
+ QList<QOpenGLSharedResource *>::const_iterator end = pending.end();
while (it != end) {
(*it)->freeResource(ctx);
delete *it;
@@ -1604,4 +1636,6 @@ void QOpenGLMultiGroupSharedResource::cleanup(QOpenGLContextGroup *group, QOpenG
m_groups.removeOne(group);
}
+#include "moc_qopenglcontext.cpp"
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qopenglcontext.h b/src/gui/kernel/qopenglcontext.h
index a529957ad6..841967a545 100644
--- a/src/gui/kernel/qopenglcontext.h
+++ b/src/gui/kernel/qopenglcontext.h
@@ -54,7 +54,10 @@
#include <QtGui/qopengl.h>
#include <QtGui/qopenglversionfunctions.h>
+#if QT_DEPRECATED_SINCE(5, 5)
#include <QtCore/qhash.h>
+#endif
+#include <QtCore/qhashfunctions.h>
#include <QtCore/qpair.h>
#include <QtCore/qvariant.h>
@@ -63,6 +66,7 @@ QT_BEGIN_NAMESPACE
class QOpenGLContextPrivate;
class QOpenGLContextGroupPrivate;
class QOpenGLFunctions;
+class QOpenGLExtraFunctions;
class QPlatformOpenGLContext;
class QScreen;
@@ -140,7 +144,7 @@ class Q_GUI_EXPORT QOpenGLContext : public QObject
Q_OBJECT
Q_DECLARE_PRIVATE(QOpenGLContext)
public:
- explicit QOpenGLContext(QObject *parent = 0);
+ explicit QOpenGLContext(QObject *parent = Q_NULLPTR);
~QOpenGLContext();
void setFormat(const QSurfaceFormat &format);
@@ -174,6 +178,7 @@ public:
QPlatformOpenGLContext *shareHandle() const;
QOpenGLFunctions *functions() const;
+ QOpenGLExtraFunctions *extraFunctions() const;
QAbstractOpenGLFunctions *versionFunctions(const QOpenGLVersionProfile &versionProfile = QOpenGLVersionProfile()) const;
@@ -236,6 +241,8 @@ private:
void setTextureFunctions(QOpenGLTextureHelper* textureFuncs);
void destroy();
+
+ Q_PRIVATE_SLOT(d_func(), void _q_screenDestroyed(QObject *object))
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qopenglcontext_p.h b/src/gui/kernel/qopenglcontext_p.h
index f9f3ce2c5f..4a746bf12b 100644
--- a/src/gui/kernel/qopenglcontext_p.h
+++ b/src/gui/kernel/qopenglcontext_p.h
@@ -270,6 +270,8 @@ public:
static QHash<QOpenGLContext *, bool> makeCurrentTracker;
static QMutex makeCurrentTrackerMutex;
#endif
+
+ void _q_screenDestroyed(QObject *object);
};
Q_GUI_EXPORT void qt_gl_set_global_share_context(QOpenGLContext *context);
diff --git a/src/gui/kernel/qopenglwindow.cpp b/src/gui/kernel/qopenglwindow.cpp
index b2025faaf1..3a1126d318 100644
--- a/src/gui/kernel/qopenglwindow.cpp
+++ b/src/gui/kernel/qopenglwindow.cpp
@@ -664,15 +664,10 @@ int QOpenGLWindow::metric(PaintDeviceMetric metric) const
if (d->paintDevice)
return d->paintDevice->depth();
break;
- case PdmDevicePixelRatio:
- if (d->paintDevice)
- return devicePixelRatio();
- break;
default:
break;
}
return QPaintDeviceWindow::metric(metric);
-
}
/*!
diff --git a/src/gui/kernel/qopenglwindow.h b/src/gui/kernel/qopenglwindow.h
index f274275c3f..0c2b44c1c7 100644
--- a/src/gui/kernel/qopenglwindow.h
+++ b/src/gui/kernel/qopenglwindow.h
@@ -58,8 +58,8 @@ public:
PartialUpdateBlend
};
- explicit QOpenGLWindow(UpdateBehavior updateBehavior = NoPartialUpdate, QWindow *parent = 0);
- explicit QOpenGLWindow(QOpenGLContext *shareContext, UpdateBehavior updateBehavior = NoPartialUpdate, QWindow *parent = 0);
+ explicit QOpenGLWindow(UpdateBehavior updateBehavior = NoPartialUpdate, QWindow *parent = Q_NULLPTR);
+ explicit QOpenGLWindow(QOpenGLContext *shareContext, UpdateBehavior updateBehavior = NoPartialUpdate, QWindow *parent = Q_NULLPTR);
~QOpenGLWindow();
UpdateBehavior updateBehavior() const;
diff --git a/src/gui/kernel/qpaintdevicewindow.cpp b/src/gui/kernel/qpaintdevicewindow.cpp
index ff661d017d..cd894866c3 100644
--- a/src/gui/kernel/qpaintdevicewindow.cpp
+++ b/src/gui/kernel/qpaintdevicewindow.cpp
@@ -155,8 +155,10 @@ int QPaintDeviceWindow::metric(PaintDeviceMetric metric) const
return qRound(screen->physicalDotsPerInchY());
break;
case PdmDevicePixelRatio:
- if (screen)
- return screen->devicePixelRatio();
+ return int(QWindow::devicePixelRatio());
+ break;
+ case PdmDevicePixelRatioScaled:
+ return int(QWindow::devicePixelRatio() * devicePixelRatioFScale());
break;
default:
break;
diff --git a/src/gui/kernel/qpaintdevicewindow_p.h b/src/gui/kernel/qpaintdevicewindow_p.h
index e234906fe0..071f2ee54c 100644
--- a/src/gui/kernel/qpaintdevicewindow_p.h
+++ b/src/gui/kernel/qpaintdevicewindow_p.h
@@ -34,6 +34,17 @@
#ifndef QPAINTDEVICEWINDOW_P_H
#define QPAINTDEVICEWINDOW_P_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include <QtGui/QPaintDeviceWindow>
#include <QtCore/QCoreApplication>
#include <QtGui/private/qwindow_p.h>
diff --git a/src/gui/kernel/qplatformcursor.cpp b/src/gui/kernel/qplatformcursor.cpp
index 7239ac7ba4..cd43fc42fe 100644
--- a/src/gui/kernel/qplatformcursor.cpp
+++ b/src/gui/kernel/qplatformcursor.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the QtOpenVG module of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
diff --git a/src/gui/kernel/qplatformcursor.h b/src/gui/kernel/qplatformcursor.h
index 4f4f9cc6ae..8c788fd27b 100644
--- a/src/gui/kernel/qplatformcursor.h
+++ b/src/gui/kernel/qplatformcursor.h
@@ -3,7 +3,7 @@
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the QtOpenVG module of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
diff --git a/src/gui/kernel/qplatformdialoghelper.cpp b/src/gui/kernel/qplatformdialoghelper.cpp
index 3d37088182..f69efe0935 100644
--- a/src/gui/kernel/qplatformdialoghelper.cpp
+++ b/src/gui/kernel/qplatformdialoghelper.cpp
@@ -36,7 +36,6 @@
#include <QtCore/QVariant>
#include <QtCore/QSharedData>
#include <QtCore/QSettings>
-#include <QtCore/QHash>
#include <QtCore/QUrl>
#include <QtGui/QColor>
@@ -120,6 +119,8 @@ static const int buttonRoleLayouts[2][5][14] =
QPlatformDialogHelper::QPlatformDialogHelper()
{
+ qRegisterMetaType<StandardButton>();
+ qRegisterMetaType<ButtonRole>();
}
QPlatformDialogHelper::~QPlatformDialogHelper()
@@ -423,6 +424,7 @@ public:
QUrl initialDirectory;
QString initiallySelectedNameFilter;
QList<QUrl> initiallySelectedFiles;
+ QStringList supportedSchemes;
};
QFileDialogOptions::QFileDialogOptions() : d(new QFileDialogOptionsPrivate)
@@ -614,6 +616,18 @@ void QFileDialogOptions::setInitiallySelectedFiles(const QList<QUrl> &files)
d->initiallySelectedFiles = files;
}
+// Schemes supported by the application
+void QFileDialogOptions::setSupportedSchemes(const QStringList &schemes)
+{
+ d->supportedSchemes = schemes;
+}
+
+QStringList QFileDialogOptions::supportedSchemes() const
+{
+ return d->supportedSchemes;
+}
+
+// Return true if the URL is supported by the filedialog implementation *and* by the application.
bool QPlatformFileDialogHelper::isSupportedUrl(const QUrl &url) const
{
return url.isLocalFile();
@@ -639,12 +653,13 @@ void QPlatformFileDialogHelper::setOptions(const QSharedPointer<QFileDialogOptio
}
const char *QPlatformFileDialogHelper::filterRegExp =
-"^(.*)\\(([a-zA-Z0-9_.*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$";
+"^(.*)\\(([a-zA-Z0-9_.,*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$";
// Makes a list of filters from a normal filter string "Image Files (*.png *.jpg)"
QStringList QPlatformFileDialogHelper::cleanFilterList(const QString &filter)
{
QRegExp regexp(QString::fromLatin1(filterRegExp));
+ Q_ASSERT(regexp.isValid());
QString f = filter;
int i = regexp.indexIn(f);
if (i >= 0)
diff --git a/src/gui/kernel/qplatformdialoghelper.h b/src/gui/kernel/qplatformdialoghelper.h
index 8b2b9881b7..5b2f4ece77 100644
--- a/src/gui/kernel/qplatformdialoghelper.h
+++ b/src/gui/kernel/qplatformdialoghelper.h
@@ -104,6 +104,7 @@ public:
};
Q_DECLARE_FLAGS(StandardButtons, StandardButton)
+ Q_FLAG(StandardButtons)
enum ButtonRole {
// keep this in sync with QDialogButtonBox::ButtonRole and QMessageBox::ButtonRole
@@ -128,6 +129,7 @@ public:
Reverse = 0x40000000,
EOL = InvalidRole
};
+ Q_ENUM(ButtonRole)
enum ButtonLayout {
// keep this in sync with QDialogButtonBox::ButtonLayout and QMessageBox::ButtonLayout
@@ -160,8 +162,14 @@ Q_SIGNALS:
void reject();
};
+QT_END_NAMESPACE
+Q_DECLARE_METATYPE(QPlatformDialogHelper::StandardButton)
+Q_DECLARE_METATYPE(QPlatformDialogHelper::ButtonRole)
+QT_BEGIN_NAMESPACE
+
class Q_GUI_EXPORT QColorDialogOptions
{
+ Q_GADGET
public:
enum ColorDialogOption {
ShowAlphaChannel = 0x00000001,
@@ -170,6 +178,7 @@ public:
};
Q_DECLARE_FLAGS(ColorDialogOptions, ColorDialogOption)
+ Q_FLAG(ColorDialogOptions)
QColorDialogOptions();
QColorDialogOptions(const QColorDialogOptions &rhs);
@@ -221,6 +230,7 @@ private:
class Q_GUI_EXPORT QFontDialogOptions
{
+ Q_GADGET
public:
enum FontDialogOption {
NoButtons = 0x00000001,
@@ -232,6 +242,7 @@ public:
};
Q_DECLARE_FLAGS(FontDialogOptions, FontDialogOption)
+ Q_FLAG(FontDialogOptions)
QFontDialogOptions();
QFontDialogOptions(const QFontDialogOptions &rhs);
@@ -274,11 +285,19 @@ private:
class Q_GUI_EXPORT QFileDialogOptions
{
+ Q_GADGET
public:
enum ViewMode { Detail, List };
+ Q_ENUM(ViewMode)
+
enum FileMode { AnyFile, ExistingFile, Directory, ExistingFiles, DirectoryOnly };
+ Q_ENUM(FileMode)
+
enum AcceptMode { AcceptOpen, AcceptSave };
+ Q_ENUM(AcceptMode)
+
enum DialogLabel { LookIn, FileName, FileType, Accept, Reject, DialogLabelCount };
+ Q_ENUM(DialogLabel)
enum FileDialogOption
{
@@ -292,6 +311,7 @@ public:
DontUseCustomDirectoryIcons = 0x00000080
};
Q_DECLARE_FLAGS(FileDialogOptions, FileDialogOption)
+ Q_FLAG(FileDialogOptions)
QFileDialogOptions();
QFileDialogOptions(const QFileDialogOptions &rhs);
@@ -348,6 +368,9 @@ public:
QList<QUrl> initiallySelectedFiles() const;
void setInitiallySelectedFiles(const QList<QUrl> &);
+ void setSupportedSchemes(const QStringList &schemes);
+ QStringList supportedSchemes() const;
+
private:
QSharedDataPointer<QFileDialogOptionsPrivate> d;
};
@@ -388,9 +411,11 @@ private:
class Q_GUI_EXPORT QMessageDialogOptions
{
+ Q_GADGET
public:
// Keep in sync with QMessageBox::Icon
enum Icon { NoIcon, Information, Warning, Critical, Question };
+ Q_ENUM(Icon)
QMessageDialogOptions();
QMessageDialogOptions(const QMessageDialogOptions &rhs);
diff --git a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp
index 2749b05691..52457ed606 100644
--- a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp
+++ b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp
@@ -40,6 +40,14 @@
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLFunctions>
+#ifndef GL_RGB10_A2
+#define GL_RGB10_A2 0x8059
+#endif
+
+#ifndef GL_UNSIGNED_INT_2_10_10_10_REV
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#endif
+
QT_BEGIN_NAMESPACE
/*!
@@ -64,23 +72,25 @@ QT_BEGIN_NAMESPACE
bound texture, otherwise returns false.
*/
bool QPlatformGraphicsBufferHelper::lockAndBindToTexture(QPlatformGraphicsBuffer *graphicsBuffer,
- bool *swizzle,
+ bool *swizzle, bool *premultiplied,
const QRect &rect)
{
if (graphicsBuffer->lock(QPlatformGraphicsBuffer::TextureAccess)) {
if (!graphicsBuffer->bindToTexture(rect)) {
- qWarning() << Q_FUNC_INFO << "Failed to bind graphicsbuffer to texture";
+ qWarning("Failed to bind %sgraphicsbuffer to texture", "");
return false;
}
if (swizzle)
*swizzle = false;
+ if (premultiplied)
+ *premultiplied = false;
} else if (graphicsBuffer->lock(QPlatformGraphicsBuffer::SWReadAccess)) {
- if (!bindSWToTexture(graphicsBuffer, swizzle, rect)) {
- qWarning() << Q_FUNC_INFO << "Failed to bind SW graphcisbuffer to texture";
+ if (!bindSWToTexture(graphicsBuffer, swizzle, premultiplied, rect)) {
+ qWarning("Failed to bind %sgraphicsbuffer to texture", "SW ");
return false;
}
} else {
- qWarning() << Q_FUNC_INFO << "Failed to lock";
+ qWarning("Failed to lock");
return false;
}
return true;
@@ -109,11 +119,12 @@ bool QPlatformGraphicsBufferHelper::lockAndBindToTexture(QPlatformGraphicsBuffer
Returns true on success, otherwise false.
*/
bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffer *graphicsBuffer,
- bool *swizzleRandB,
+ bool *swizzleRandB, bool *premultipliedB,
const QRect &subRect)
{
#ifndef QT_NO_OPENGL
- if (!QOpenGLContext::currentContext())
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ if (!ctx)
return false;
if (!(graphicsBuffer->isLocked() & QPlatformGraphicsBuffer::SWReadAccess))
@@ -123,27 +134,70 @@ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffe
Q_ASSERT(subRect.isEmpty() || QRect(QPoint(0,0), size).contains(subRect));
+ GLenum internalFormat = GL_RGBA;
+ GLuint pixelType = GL_UNSIGNED_BYTE;
+
+ bool needsConversion = false;
bool swizzle = false;
+ bool premultiplied = false;
QImage::Format imageformat = QImage::toImageFormat(graphicsBuffer->format());
QImage image(graphicsBuffer->data(), size.width(), size.height(), graphicsBuffer->bytesPerLine(), imageformat);
if (graphicsBuffer->bytesPerLine() != (size.width() * 4)) {
- image = image.convertToFormat(QImage::Format_RGBA8888);
- } else if (imageformat == QImage::Format_RGB32) {
- swizzle = true;
- } else if (imageformat != QImage::Format_RGBA8888) {
- image = image.convertToFormat(QImage::Format_RGBA8888);
+ needsConversion = true;
+ } else {
+ switch (imageformat) {
+ case QImage::Format_ARGB32_Premultiplied:
+ premultiplied = true;
+ // no break
+ case QImage::Format_RGB32:
+ case QImage::Format_ARGB32:
+ swizzle = true;
+ break;
+ case QImage::Format_RGBA8888_Premultiplied:
+ premultiplied = true;
+ // no break
+ case QImage::Format_RGBX8888:
+ case QImage::Format_RGBA8888:
+ break;
+ case QImage::Format_BGR30:
+ case QImage::Format_A2BGR30_Premultiplied:
+ if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
+ pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
+ internalFormat = GL_RGB10_A2;
+ premultiplied = true;
+ } else {
+ needsConversion = true;
+ }
+ break;
+ case QImage::Format_RGB30:
+ case QImage::Format_A2RGB30_Premultiplied:
+ if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
+ pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
+ internalFormat = GL_RGB10_A2;
+ premultiplied = true;
+ swizzle = true;
+ } else {
+ needsConversion = true;
+ }
+ break;
+ default:
+ needsConversion = true;
+ break;
+ }
}
+ if (needsConversion)
+ image = image.convertToFormat(QImage::Format_RGBA8888);
- QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
+ QOpenGLFunctions *funcs = ctx->functions();
QRect rect = subRect;
if (rect.isNull() || rect == QRect(QPoint(0,0),size)) {
- funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, image.constBits());
+ funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, size.width(), size.height(), 0, GL_RGBA, pixelType, image.constBits());
} else {
#ifndef QT_OPENGL_ES_2
- if (!QOpenGLContext::currentContext()->isOpenGLES()) {
+ if (!ctx->isOpenGLES()) {
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, image.width());
- funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
image.constScanLine(rect.y()) + rect.x() * 4);
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
} else
@@ -160,22 +214,25 @@ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffe
// OpenGL instead of copying, since there's no gap between scanlines
if (rect.width() == size.width()) {
- funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
image.constScanLine(rect.y()));
} else {
- funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
image.copy(rect).constBits());
}
}
}
if (swizzleRandB)
*swizzleRandB = swizzle;
+ if (premultipliedB)
+ *premultipliedB = premultiplied;
return true;
#else
Q_UNUSED(graphicsBuffer)
Q_UNUSED(swizzleRandB)
+ Q_UNUSED(premultipliedB)
Q_UNUSED(subRect)
return false;
#endif // QT_NO_OPENGL
diff --git a/src/gui/kernel/qplatformgraphicsbufferhelper.h b/src/gui/kernel/qplatformgraphicsbufferhelper.h
index ded7810608..cc1a4918cd 100644
--- a/src/gui/kernel/qplatformgraphicsbufferhelper.h
+++ b/src/gui/kernel/qplatformgraphicsbufferhelper.h
@@ -39,8 +39,8 @@
QT_BEGIN_NAMESPACE
namespace QPlatformGraphicsBufferHelper {
- bool lockAndBindToTexture(QPlatformGraphicsBuffer *graphicsBuffer, bool *swizzleRandB, const QRect &rect = QRect());
- bool bindSWToTexture(const QPlatformGraphicsBuffer *graphicsBuffer, bool *swizzleRandB = Q_NULLPTR, const QRect &rect = QRect());
+ bool lockAndBindToTexture(QPlatformGraphicsBuffer *graphicsBuffer, bool *swizzleRandB, bool *premultipliedB, const QRect &rect = QRect());
+ bool bindSWToTexture(const QPlatformGraphicsBuffer *graphicsBuffer, bool *swizzleRandB = Q_NULLPTR, bool *premultipliedB = Q_NULLPTR, const QRect &rect = QRect());
}
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatforminputcontextfactory.cpp b/src/gui/kernel/qplatforminputcontextfactory.cpp
index a7660e76ae..fedf940dda 100644
--- a/src/gui/kernel/qplatforminputcontextfactory.cpp
+++ b/src/gui/kernel/qplatforminputcontextfactory.cpp
@@ -56,48 +56,34 @@ QStringList QPlatformInputContextFactory::keys()
#endif
}
-QPlatformInputContext *QPlatformInputContextFactory::create(const QString& key)
+QString QPlatformInputContextFactory::requested()
{
- QStringList paramList = key.split(QLatin1Char(':'));
- const QString platform = paramList.takeFirst().toLower();
-
-#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
- if (QPlatformInputContext *ret = qLoadPlugin1<QPlatformInputContext, QPlatformInputContextPlugin>(loader(), platform, paramList))
- return ret;
-#endif
- return 0;
+ QByteArray env = qgetenv("QT_IM_MODULE");
+ return env.isNull() ? QString() : QString::fromLocal8Bit(env);
}
-QPlatformInputContext *QPlatformInputContextFactory::create()
+QPlatformInputContext *QPlatformInputContextFactory::create(const QString& key)
{
- QPlatformInputContext *ic = 0;
-
- QString icString = QString::fromLatin1(qgetenv("QT_IM_MODULE"));
-
- if (icString == QLatin1String("none"))
- return 0;
-
- ic = create(icString);
- if (ic && ic->isValid())
- return ic;
-
- delete ic;
- ic = 0;
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+ if (!key.isEmpty()) {
+ QStringList paramList = key.split(QLatin1Char(':'));
+ const QString platform = paramList.takeFirst().toLower();
- QStringList k = keys();
- for (int i = 0; i < k.size(); ++i) {
- if (k.at(i) == icString)
- continue;
- ic = create(k.at(i));
+ QPlatformInputContext *ic = qLoadPlugin1<QPlatformInputContext, QPlatformInputContextPlugin>
+ (loader(), platform, paramList);
if (ic && ic->isValid())
return ic;
+
delete ic;
- ic = 0;
}
-
+#endif
return 0;
}
+QPlatformInputContext *QPlatformInputContextFactory::create()
+{
+ return create(requested());
+}
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatforminputcontextfactory_p.h b/src/gui/kernel/qplatforminputcontextfactory_p.h
index a74c4f5f80..38f4358287 100644
--- a/src/gui/kernel/qplatforminputcontextfactory_p.h
+++ b/src/gui/kernel/qplatforminputcontextfactory_p.h
@@ -56,6 +56,7 @@ class Q_GUI_EXPORT QPlatformInputContextFactory
{
public:
static QStringList keys();
+ static QString requested();
static QPlatformInputContext *create(const QString &key);
static QPlatformInputContext *create();
};
diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp
index 4d973d47a5..14633d8b30 100644
--- a/src/gui/kernel/qplatformintegration.cpp
+++ b/src/gui/kernel/qplatformintegration.cpp
@@ -39,7 +39,6 @@
#include <qpa/qplatformtheme.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/private/qpixmap_raster_p.h>
-#include <qpa/qplatformscreen_p.h>
#include <private/qdnd_p.h>
#include <private/qsimpledrag_p.h>
@@ -209,8 +208,7 @@ QPlatformServices *QPlatformIntegration::services() const
behavior for desktop platforms.
\value ForeignWindows The platform allows creating QWindows which represent
- native windows created by other processes or anyway created by using native
- libraries.
+ native windows created by other processes or by using native libraries.
\value NonFullScreenWindows The platform supports top-level windows which do not
fill the screen. The default implementation returns \c true. Returning false for
@@ -450,13 +448,31 @@ QList<int> QPlatformIntegration::possibleKeys(const QKeyEvent *) const
void QPlatformIntegration::screenAdded(QPlatformScreen *ps, bool isPrimary)
{
QScreen *screen = new QScreen(ps);
- ps->d_func()->screen = screen;
+
if (isPrimary) {
QGuiApplicationPrivate::screen_list.prepend(screen);
} else {
QGuiApplicationPrivate::screen_list.append(screen);
}
emit qGuiApp->screenAdded(screen);
+
+ if (isPrimary)
+ emit qGuiApp->primaryScreenChanged(screen);
+}
+
+/*!
+ Just removes the screen, call destroyScreen instead.
+
+ \sa destroyScreen()
+*/
+
+void QPlatformIntegration::removeScreen(QScreen *screen)
+{
+ const bool wasPrimary = (!QGuiApplicationPrivate::screen_list.isEmpty() && QGuiApplicationPrivate::screen_list[0] == screen);
+ QGuiApplicationPrivate::screen_list.removeOne(screen);
+
+ if (wasPrimary && qGuiApp && !QGuiApplicationPrivate::screen_list.isEmpty())
+ emit qGuiApp->primaryScreenChanged(QGuiApplicationPrivate::screen_list[0]);
}
/*!
@@ -469,11 +485,31 @@ void QPlatformIntegration::screenAdded(QPlatformScreen *ps, bool isPrimary)
*/
void QPlatformIntegration::destroyScreen(QPlatformScreen *screen)
{
- QGuiApplicationPrivate::screen_list.removeOne(screen->d_func()->screen);
- delete screen->d_func()->screen;
+ QScreen *qScreen = screen->screen();
+ removeScreen(qScreen);
+ delete qScreen;
delete screen;
}
+/*!
+ Should be called whenever the primary screen changes.
+
+ When the screen specified as primary changes, this method will notify
+ QGuiApplication and emit the QGuiApplication::primaryScreenChanged signal.
+ */
+
+void QPlatformIntegration::setPrimaryScreen(QPlatformScreen *newPrimary)
+{
+ QScreen* newPrimaryScreen = newPrimary->screen();
+ int idx = QGuiApplicationPrivate::screen_list.indexOf(newPrimaryScreen);
+ Q_ASSERT(idx >= 0);
+ if (idx == 0)
+ return;
+
+ QGuiApplicationPrivate::screen_list.swap(0, idx);
+ emit qGuiApp->primaryScreenChanged(newPrimaryScreen);
+}
+
QStringList QPlatformIntegration::themeNames() const
{
return QStringList();
diff --git a/src/gui/kernel/qplatformintegration.h b/src/gui/kernel/qplatformintegration.h
index 2aa502b3d2..af89a73455 100644
--- a/src/gui/kernel/qplatformintegration.h
+++ b/src/gui/kernel/qplatformintegration.h
@@ -91,7 +91,8 @@ public:
SyncState,
RasterGLSurface,
AllGLFunctionsQueryable,
- ApplicationIcon
+ ApplicationIcon,
+ SwitchableWidgetComposition
};
virtual ~QPlatformIntegration() { }
@@ -172,9 +173,13 @@ public:
virtual QOpenGLContext::OpenGLModuleType openGLModuleType();
#endif
virtual void setApplicationIcon(const QIcon &icon) const;
+
+ void removeScreen(QScreen *screen);
+
protected:
void screenAdded(QPlatformScreen *screen, bool isPrimary = false);
void destroyScreen(QPlatformScreen *screen);
+ void setPrimaryScreen(QPlatformScreen *newPrimary);
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformintegrationfactory.cpp b/src/gui/kernel/qplatformintegrationfactory.cpp
index d58ac3a33f..5a1fb3ca83 100644
--- a/src/gui/kernel/qplatformintegrationfactory.cpp
+++ b/src/gui/kernel/qplatformintegrationfactory.cpp
@@ -72,6 +72,12 @@ QPlatformIntegration *QPlatformIntegrationFactory::create(const QString &platfor
}
if (QPlatformIntegration *ret = loadIntegration(loader(), platform, paramList, argc, argv))
return ret;
+#else
+ Q_UNUSED(platform);
+ Q_UNUSED(paramList);
+ Q_UNUSED(argc);
+ Q_UNUSED(argv);
+ Q_UNUSED(platformPluginPath);
#endif
return 0;
}
@@ -102,6 +108,7 @@ QStringList QPlatformIntegrationFactory::keys(const QString &platformPluginPath)
list.append(loader()->keyMap().values());
return list;
#else
+ Q_UNUSED(platformPluginPath);
return QStringList();
#endif
}
diff --git a/src/gui/kernel/qplatformmenu.h b/src/gui/kernel/qplatformmenu.h
index 1022d0ed4a..bc0b3a4870 100644
--- a/src/gui/kernel/qplatformmenu.h
+++ b/src/gui/kernel/qplatformmenu.h
@@ -63,6 +63,7 @@ public:
// They could be added as public QAction roles if necessary.
CutRole, CopyRole, PasteRole, SelectAllRole,
RoleCount };
+ Q_ENUM(MenuRole)
virtual void setTag(quintptr tag) = 0;
virtual quintptr tag()const = 0;
@@ -91,6 +92,7 @@ class Q_GUI_EXPORT QPlatformMenu : public QObject
Q_OBJECT
public:
enum MenuType { DefaultMenu = 0, EditMenu };
+ Q_ENUM(MenuType)
virtual void insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) = 0;
virtual void removeMenuItem(QPlatformMenuItem *menuItem) = 0;
diff --git a/src/gui/kernel/qplatformscreen.cpp b/src/gui/kernel/qplatformscreen.cpp
index edf546799f..8e9767d69e 100644
--- a/src/gui/kernel/qplatformscreen.cpp
+++ b/src/gui/kernel/qplatformscreen.cpp
@@ -40,6 +40,7 @@
#include <qpa/qplatformintegration.h>
#include <QtGui/qscreen.h>
#include <QtGui/qwindow.h>
+#include <private/qhighdpiscaling_p.h>
QT_BEGIN_NAMESPACE
@@ -55,7 +56,7 @@ QPlatformScreen::~QPlatformScreen()
Q_D(QPlatformScreen);
if (d->screen) {
qWarning("Manually deleting a QPlatformScreen. Call QPlatformIntegration::destroyScreen instead.");
- QGuiApplicationPrivate::screen_list.removeOne(d->screen);
+ QGuiApplicationPrivate::platformIntegration()->removeScreen(d->screen);
delete d->screen;
}
}
@@ -89,7 +90,7 @@ QWindow *QPlatformScreen::topLevelAt(const QPoint & pos) const
QWindowList list = QGuiApplication::topLevelWindows();
for (int i = list.size()-1; i >= 0; --i) {
QWindow *w = list[i];
- if (w->isVisible() && w->geometry().contains(pos))
+ if (w->isVisible() && QHighDpi::toNativePixels(w->geometry(), w).contains(pos))
return w;
}
@@ -97,6 +98,23 @@ QWindow *QPlatformScreen::topLevelAt(const QPoint & pos) const
}
/*!
+ Find the sibling screen corresponding to \a globalPos.
+
+ Returns this screen if no suitable screen is found at the position.
+ */
+const QPlatformScreen *QPlatformScreen::screenForPosition(const QPoint &point) const
+{
+ if (!geometry().contains(point)) {
+ Q_FOREACH (const QPlatformScreen* screen, virtualSiblings()) {
+ if (screen->geometry().contains(point))
+ return screen;
+ }
+ }
+ return this;
+}
+
+
+/*!
Returns a list of all the platform screens that are part of the same
virtual desktop.
@@ -156,11 +174,13 @@ QDpi QPlatformScreen::logicalDpi() const
}
/*!
- Reimplement this function in subclass to return the device pixel
- ratio for the screen. This is the ratio between physical pixels
- and device-independent pixels.
+ Reimplement this function in subclass to return the device pixel ratio
+ for the screen. This is the ratio between physical pixels and the
+ device-independent pixels of the windowing system. The default
+ implementation returns 1.0.
- \sa QPlatformWindow::devicePixelRatio();
+ \sa QPlatformWindow::devicePixelRatio()
+ \sa QPlatformScreen::pixelDensity()
*/
qreal QPlatformScreen::devicePixelRatio() const
{
@@ -168,6 +188,24 @@ qreal QPlatformScreen::devicePixelRatio() const
}
/*!
+ Reimplement this function in subclass to return the pixel density of the
+ screen. This is the scale factor needed to make a low-dpi application
+ usable on this screen. The default implementation returns 1.0.
+
+ Returning something else than 1.0 from this function causes Qt to
+ apply the scale factor to the application's coordinate system.
+ This is different from devicePixelRatio, which reports a scale
+ factor already applied by the windowing system. A platform plugin
+ typically implements one (or none) of these two functions.
+
+ \sa QPlatformWindow::devicePixelRatio()
+*/
+qreal QPlatformScreen::pixelDensity() const
+{
+ return 1.0;
+}
+
+/*!
Reimplement this function in subclass to return the vertical refresh rate
of the screen, in Hz.
@@ -290,8 +328,8 @@ void QPlatformScreen::resizeMaximizedWindows()
// 'screen()' still has the old geometry info while 'this' has the new geometry info
const QRect oldGeometry = screen()->geometry();
const QRect oldAvailableGeometry = screen()->availableGeometry();
- const QRect newGeometry = geometry();
- const QRect newAvailableGeometry = availableGeometry();
+ const QRect newGeometry = deviceIndependentGeometry();
+ const QRect newAvailableGeometry = QHighDpi::fromNative(availableGeometry(), QHighDpiScaling::factor(this), newGeometry.topLeft());
// make sure maximized and fullscreen windows are updated
for (int i = 0; i < windows.size(); ++i) {
@@ -324,7 +362,7 @@ static int log2(uint i)
int QPlatformScreen::angleBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b)
{
if (a == Qt::PrimaryOrientation || b == Qt::PrimaryOrientation) {
- qWarning() << "Use QScreen version of" << __FUNCTION__ << "when passing Qt::PrimaryOrientation";
+ qWarning("Use QScreen version of %sBetween() when passing Qt::PrimaryOrientation", "angle");
return 0;
}
@@ -346,7 +384,7 @@ int QPlatformScreen::angleBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation
QTransform QPlatformScreen::transformBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &target)
{
if (a == Qt::PrimaryOrientation || b == Qt::PrimaryOrientation) {
- qWarning() << "Use QScreen version of" << __FUNCTION__ << "when passing Qt::PrimaryOrientation";
+ qWarning("Use QScreen version of %sBetween() when passing Qt::PrimaryOrientation", "transform");
return QTransform();
}
@@ -377,7 +415,7 @@ QTransform QPlatformScreen::transformBetween(Qt::ScreenOrientation a, Qt::Screen
QRect QPlatformScreen::mapBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &rect)
{
if (a == Qt::PrimaryOrientation || b == Qt::PrimaryOrientation) {
- qWarning() << "Use QScreen version of" << __FUNCTION__ << "when passing Qt::PrimaryOrientation";
+ qWarning("Use QScreen version of %sBetween() when passing Qt::PrimaryOrientation", "map");
return rect;
}
@@ -393,6 +431,13 @@ QRect QPlatformScreen::mapBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation
return rect;
}
+QRect QPlatformScreen::deviceIndependentGeometry() const
+{
+ qreal scaleFactor = QHighDpiScaling::factor(this);
+ QRect nativeGeometry = geometry();
+ return QRect(nativeGeometry.topLeft(), QHighDpi::fromNative(nativeGeometry.size(), scaleFactor));
+}
+
/*!
Returns a hint about this screen's subpixel layout structure.
@@ -420,4 +465,22 @@ QPlatformScreen::SubpixelAntialiasingType QPlatformScreen::subpixelAntialiasingT
return static_cast<QPlatformScreen::SubpixelAntialiasingType>(type);
}
+/*!
+ Returns the current power state.
+
+ The default implementation always returns PowerStateOn.
+*/
+QPlatformScreen::PowerState QPlatformScreen::powerState() const
+{
+ return PowerStateOn;
+}
+
+/*!
+ Sets the power state for this screen.
+*/
+void QPlatformScreen::setPowerState(PowerState state)
+{
+ Q_UNUSED(state);
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformscreen.h b/src/gui/kernel/qplatformscreen.h
index 551cb788c9..b32f9cf97c 100644
--- a/src/gui/kernel/qplatformscreen.h
+++ b/src/gui/kernel/qplatformscreen.h
@@ -82,6 +82,13 @@ public:
Subpixel_VBGR
};
+ enum PowerState {
+ PowerStateOn,
+ PowerStateStandby,
+ PowerStateSuspend,
+ PowerStateOff
+ };
+
QPlatformScreen();
virtual ~QPlatformScreen();
@@ -96,6 +103,7 @@ public:
virtual QSizeF physicalSize() const;
virtual QDpi logicalDpi() const;
virtual qreal devicePixelRatio() const;
+ virtual qreal pixelDensity() const;
virtual qreal refreshRate() const;
@@ -105,6 +113,7 @@ public:
virtual QWindow *topLevelAt(const QPoint &point) const;
virtual QList<QPlatformScreen *> virtualSiblings() const;
+ const QPlatformScreen *screenForPosition(const QPoint &point) const;
QScreen *screen() const;
@@ -117,10 +126,16 @@ public:
virtual QPlatformCursor *cursor() const;
virtual SubpixelAntialiasingType subpixelAntialiasingTypeHint() const;
+ virtual PowerState powerState() const;
+ virtual void setPowerState(PowerState state);
+
static int angleBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b);
static QTransform transformBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &target);
static QRect mapBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &rect);
+ // The platform screen's geometry in device independent coordinates
+ QRect deviceIndependentGeometry() const;
+
protected:
void resizeMaximizedWindows();
@@ -129,7 +144,7 @@ protected:
private:
Q_DISABLE_COPY(QPlatformScreen)
- friend class QPlatformIntegration;
+ friend class QScreenPrivate;
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformsystemtrayicon.h b/src/gui/kernel/qplatformsystemtrayicon.h
index 437f5e02b1..6ef2d1538f 100644
--- a/src/gui/kernel/qplatformsystemtrayicon.h
+++ b/src/gui/kernel/qplatformsystemtrayicon.h
@@ -57,8 +57,10 @@ public:
Trigger,
MiddleClick
};
+ Q_ENUM(ActivationReason)
enum MessageIcon { NoIcon, Information, Warning, Critical };
+ Q_ENUM(MessageIcon)
QPlatformSystemTrayIcon();
~QPlatformSystemTrayIcon();
diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp
index 36a71fe2da..ce8548f628 100644
--- a/src/gui/kernel/qplatformtheme.cpp
+++ b/src/gui/kernel/qplatformtheme.cpp
@@ -323,7 +323,9 @@ const QKeyBinding QPlatformThemePrivate::keyBindings[] = {
{QKeySequence::FullScreen, 1, Qt::Key_F11, KB_Win | KB_KDE},
{QKeySequence::Deselect, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_A, KB_X11},
{QKeySequence::DeleteCompleteLine, 0, Qt::CTRL | Qt::Key_U, KB_X11},
- {QKeySequence::Backspace, 0, Qt::META | Qt::Key_H, KB_Mac}
+ {QKeySequence::Backspace, 0, Qt::META | Qt::Key_H, KB_Mac},
+ {QKeySequence::Cancel, 0, Qt::Key_Escape, KB_All},
+ {QKeySequence::Cancel, 0, Qt::CTRL | Qt::Key_Period, KB_Mac}
};
const uint QPlatformThemePrivate::numberOfKeyBindings = sizeof(QPlatformThemePrivate::keyBindings)/(sizeof(QKeyBinding));
diff --git a/src/gui/kernel/qplatformtheme.h b/src/gui/kernel/qplatformtheme.h
index 69cc2f90af..36fa7a65aa 100644
--- a/src/gui/kernel/qplatformtheme.h
+++ b/src/gui/kernel/qplatformtheme.h
@@ -164,6 +164,8 @@ public:
SmallFont,
MiniFont,
FixedFont,
+ GroupBoxTitleFont,
+ TabButtonFont,
NFonts
};
diff --git a/src/gui/kernel/qplatformthemefactory.cpp b/src/gui/kernel/qplatformthemefactory.cpp
index d4902ac163..bcc37dad06 100644
--- a/src/gui/kernel/qplatformthemefactory.cpp
+++ b/src/gui/kernel/qplatformthemefactory.cpp
@@ -63,6 +63,9 @@ QPlatformTheme *QPlatformThemeFactory::create(const QString& key, const QString
}
if (QPlatformTheme *ret = qLoadPlugin1<QPlatformTheme, QPlatformThemePlugin>(loader(), platform, paramList))
return ret;
+#else
+ Q_UNUSED(key);
+ Q_UNUSED(platformPluginPath);
#endif
return 0;
}
@@ -93,6 +96,7 @@ QStringList QPlatformThemeFactory::keys(const QString &platformPluginPath)
list += loader()->keyMap().values();
return list;
#else
+ Q_UNUSED(platformPluginPath);
return QStringList();
#endif
}
diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp
index 114fcf8062..aea029b7f5 100644
--- a/src/gui/kernel/qplatformwindow.cpp
+++ b/src/gui/kernel/qplatformwindow.cpp
@@ -39,8 +39,10 @@
#include <qpa/qwindowsysteminterface.h>
#include <QtGui/qwindow.h>
#include <QtGui/qscreen.h>
+#include <private/qhighdpiscaling_p.h>
#include <private/qwindow_p.h>
+
QT_BEGIN_NAMESPACE
/*!
@@ -481,13 +483,27 @@ QString QPlatformWindow::formatWindowTitle(const QString &title, const QString &
QPlatformScreen *QPlatformWindow::screenForGeometry(const QRect &newGeometry) const
{
QPlatformScreen *currentScreen = screen();
- if (!parent() && currentScreen && !currentScreen->geometry().intersects(newGeometry)) {
+ QPlatformScreen *fallback = currentScreen;
+ //QRect::center can return a value outside the rectangle if it's empty
+ const QPoint center = newGeometry.isEmpty() ? newGeometry.topLeft() : newGeometry.center();
+
+ if (!parent() && currentScreen && !currentScreen->geometry().contains(center)) {
Q_FOREACH (QPlatformScreen* screen, currentScreen->virtualSiblings()) {
- if (screen->geometry().intersects(newGeometry))
+ if (screen->geometry().contains(center))
return screen;
+ if (screen->geometry().intersects(newGeometry))
+ fallback = screen;
}
}
- return currentScreen;
+ return fallback;
+}
+
+/*!
+ Returns a size with both dimensions bounded to [0, QWINDOWSIZE_MAX]
+*/
+QSize QPlatformWindow::constrainWindowSize(const QSize &size)
+{
+ return size.expandedTo(QSize(0, 0)).boundedTo(QSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX));
}
/*!
@@ -565,7 +581,10 @@ void QPlatformWindow::invalidateSurface()
QRect QPlatformWindow::initialGeometry(const QWindow *w,
const QRect &initialGeometry, int defaultWidth, int defaultHeight)
{
- QRect rect(initialGeometry);
+ const QScreen *screen = effectiveScreen(w);
+ if (!screen)
+ return initialGeometry;
+ QRect rect(QHighDpi::fromNativePixels(initialGeometry, w));
if (rect.width() == 0) {
const int minWidth = w->minimumWidth();
rect.setWidth(minWidth > 0 ? minWidth : defaultWidth);
@@ -575,25 +594,23 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w,
rect.setHeight(minHeight > 0 ? minHeight : defaultHeight);
}
if (w->isTopLevel() && qt_window_private(const_cast<QWindow*>(w))->positionAutomatic
- && w->type() != Qt::Popup) {
- if (const QScreen *screen = effectiveScreen(w)) {
- const QRect availableGeometry = screen->availableGeometry();
- // Center unless the geometry ( + unknown window frame) is too large for the screen).
- if (rect.height() < (availableGeometry.height() * 8) / 9
+ && w->type() != Qt::Popup) {
+ const QRect availableGeometry = screen->availableGeometry();
+ // Center unless the geometry ( + unknown window frame) is too large for the screen).
+ if (rect.height() < (availableGeometry.height() * 8) / 9
&& rect.width() < (availableGeometry.width() * 8) / 9) {
- const QWindow *tp = w->transientParent();
- if (tp) {
- // A transient window should be centered w.r.t. its transient parent.
- rect.moveCenter(tp->geometry().center());
- } else {
- // Center the window on the screen. (Only applicable on platforms
- // which do not provide a better way.)
- rect.moveCenter(availableGeometry.center());
- }
+ const QWindow *tp = w->transientParent();
+ if (tp) {
+ // A transient window should be centered w.r.t. its transient parent.
+ rect.moveCenter(tp->geometry().center());
+ } else {
+ // Center the window on the screen. (Only applicable on platforms
+ // which do not provide a better way.)
+ rect.moveCenter(availableGeometry.center());
}
}
}
- return rect;
+ return QHighDpi::toNativePixels(rect, screen);
}
/*!
@@ -627,6 +644,82 @@ void QPlatformWindow::requestUpdate()
}
/*!
+ Returns the QWindow minimum size.
+*/
+QSize QPlatformWindow::windowMinimumSize() const
+{
+ return constrainWindowSize(QHighDpi::toNativePixels(window()->minimumSize(), window()));
+}
+
+/*!
+ Returns the QWindow maximum size.
+*/
+QSize QPlatformWindow::windowMaximumSize() const
+{
+ return constrainWindowSize(QHighDpi::toNativePixels(window()->maximumSize(), window()));
+}
+
+/*!
+ Returns the QWindow base size.
+*/
+QSize QPlatformWindow::windowBaseSize() const
+{
+ return QHighDpi::toNativePixels(window()->baseSize(), window());
+}
+
+/*!
+ Returns the QWindow size increment.
+*/
+QSize QPlatformWindow::windowSizeIncrement() const
+{
+ QSize increment = window()->sizeIncrement();
+ if (!QHighDpiScaling::isActive())
+ return increment;
+
+ // Normalize the increment. If not set the increment can be
+ // (-1, -1) or (0, 0). Make that (1, 1) which is scalable.
+ if (increment.isEmpty())
+ increment = QSize(1, 1);
+
+ return QHighDpi::toNativePixels(increment, window());
+}
+
+/*!
+ Returns the QWindow geometry.
+*/
+QRect QPlatformWindow::windowGeometry() const
+{
+ return QHighDpi::toNativePixels(window()->geometry(), window());
+}
+
+/*!
+ Returns the QWindow frame geometry.
+*/
+QRect QPlatformWindow::windowFrameGeometry() const
+{
+ return QHighDpi::toNativePixels(window()->frameGeometry(), window());
+}
+
+/*!
+ Returns the closest acceptable geometry for a given geometry before
+ a resize/move event for platforms that support it, for example to
+ implement heightForWidth().
+*/
+
+QRectF QPlatformWindow::closestAcceptableGeometry(const QWindow *qWindow, const QRectF &nativeRect)
+{
+ const QRectF rectF = QHighDpi::fromNativePixels(nativeRect, qWindow);
+ const QRectF correctedGeometryF = qt_window_private(const_cast<QWindow *>(qWindow))->closestAcceptableGeometry(rectF);
+ return !correctedGeometryF.isEmpty() && rectF != correctedGeometryF
+ ? QHighDpi::toNativePixels(correctedGeometryF, qWindow) : nativeRect;
+}
+
+QRectF QPlatformWindow::windowClosestAcceptableGeometry(const QRectF &nativeRect) const
+{
+ return QPlatformWindow::closestAcceptableGeometry(window(), nativeRect);
+}
+
+/*!
\class QPlatformWindow
\since 4.8
\internal
diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h
index c7c1efdc58..850e2b4bfe 100644
--- a/src/gui/kernel/qplatformwindow.h
+++ b/src/gui/kernel/qplatformwindow.h
@@ -95,7 +95,7 @@ public:
virtual bool isExposed() const;
virtual bool isActive() const;
- virtual bool isEmbedded(const QPlatformWindow *parentWindow) const;
+ virtual bool isEmbedded(const QPlatformWindow *parentWindow = 0) const;
virtual QPoint mapToGlobal(const QPoint &pos) const;
virtual QPoint mapFromGlobal(const QPoint &pos) const;
@@ -130,9 +130,22 @@ public:
const QRect &initialGeometry, int defaultWidth, int defaultHeight);
virtual void requestUpdate();
+
+ // Window property accessors. Platform plugins should use these
+ // instead of accessing QWindow directly.
+ QSize windowMinimumSize() const;
+ QSize windowMaximumSize() const;
+ QSize windowBaseSize() const;
+ QSize windowSizeIncrement() const;
+ QRect windowGeometry() const;
+ QRect windowFrameGeometry() const;
+ QRectF windowClosestAcceptableGeometry(const QRectF &nativeRect) const;
+ static QRectF closestAcceptableGeometry(const QWindow *w, const QRectF &nativeRect);
+
protected:
static QString formatWindowTitle(const QString &title, const QString &separator);
QPlatformScreen *screenForGeometry(const QRect &newGeometry) const;
+ static QSize constrainWindowSize(const QSize &size);
QScopedPointer<QPlatformWindowPrivate> d_ptr;
private:
diff --git a/src/gui/kernel/qrasterwindow.cpp b/src/gui/kernel/qrasterwindow.cpp
index c04eb71420..fc1739ca0e 100644
--- a/src/gui/kernel/qrasterwindow.cpp
+++ b/src/gui/kernel/qrasterwindow.cpp
@@ -108,8 +108,6 @@ int QRasterWindow::metric(PaintDeviceMetric metric) const
switch (metric) {
case PdmDepth:
return d->backingstore->paintDevice()->depth();
- case PdmDevicePixelRatio:
- return d->backingstore->paintDevice()->devicePixelRatio();
default:
break;
}
diff --git a/src/gui/kernel/qrasterwindow.h b/src/gui/kernel/qrasterwindow.h
index 4912efad37..6db6baa8f5 100644
--- a/src/gui/kernel/qrasterwindow.h
+++ b/src/gui/kernel/qrasterwindow.h
@@ -46,7 +46,7 @@ class Q_GUI_EXPORT QRasterWindow : public QPaintDeviceWindow
Q_DECLARE_PRIVATE(QRasterWindow)
public:
- explicit QRasterWindow(QWindow *parent = 0);
+ explicit QRasterWindow(QWindow *parent = Q_NULLPTR);
protected:
int metric(PaintDeviceMetric metric) const Q_DECL_OVERRIDE;
diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp
index 038be09dc7..52e7686439 100644
--- a/src/gui/kernel/qscreen.cpp
+++ b/src/gui/kernel/qscreen.cpp
@@ -36,7 +36,9 @@
#include "qpixmap.h"
#include "qguiapplication_p.h"
#include <qpa/qplatformscreen.h>
+#include <qpa/qplatformscreen_p.h>
+#include <QtCore/QDebug>
#include <QtCore/private/qobject_p.h>
QT_BEGIN_NAMESPACE
@@ -62,8 +64,33 @@ QT_BEGIN_NAMESPACE
*/
QScreen::QScreen(QPlatformScreen *screen)
- : QObject(*new QScreenPrivate(screen), 0)
+ : QObject(*new QScreenPrivate(), 0)
{
+ Q_D(QScreen);
+ d->setPlatformScreen(screen);
+}
+
+void QScreenPrivate::setPlatformScreen(QPlatformScreen *screen)
+{
+ Q_Q(QScreen);
+ platformScreen = screen;
+ platformScreen->d_func()->screen = q;
+ orientation = platformScreen->orientation();
+ geometry = platformScreen->deviceIndependentGeometry();
+ availableGeometry = QHighDpi::fromNative(platformScreen->availableGeometry(), QHighDpiScaling::factor(platformScreen), geometry.topLeft());
+ logicalDpi = platformScreen->logicalDpi();
+ refreshRate = platformScreen->refreshRate();
+ // safeguard ourselves against buggy platform behavior...
+ if (refreshRate < 1.0)
+ refreshRate = 60.0;
+
+ updatePrimaryOrientation();
+
+ filteredOrientation = orientation;
+ if (filteredOrientation == Qt::PrimaryOrientation)
+ filteredOrientation = primaryOrientation;
+
+ updateHighDpi();
}
@@ -89,8 +116,8 @@ QScreen::~QScreen()
bool movingFromVirtualSibling = primaryScreen && primaryScreen->handle()->virtualSiblings().contains(handle());
// Move any leftover windows to the primary screen
- foreach (QWindow *window, QGuiApplication::topLevelWindows()) {
- if (window->screen() != this)
+ foreach (QWindow *window, QGuiApplication::allWindows()) {
+ if (!window->isTopLevel() || window->screen() != this)
continue;
const bool wasVisible = window->isVisible();
@@ -207,6 +234,8 @@ qreal QScreen::physicalDotsPerInch() const
qreal QScreen::logicalDotsPerInchX() const
{
Q_D(const QScreen);
+ if (QHighDpiScaling::isActive())
+ return QHighDpiScaling::logicalDpi().first;
return d->logicalDpi.first;
}
@@ -221,6 +250,8 @@ qreal QScreen::logicalDotsPerInchX() const
qreal QScreen::logicalDotsPerInchY() const
{
Q_D(const QScreen);
+ if (QHighDpiScaling::isActive())
+ return QHighDpiScaling::logicalDpi().second;
return d->logicalDpi.second;
}
@@ -239,7 +270,7 @@ qreal QScreen::logicalDotsPerInchY() const
qreal QScreen::logicalDotsPerInch() const
{
Q_D(const QScreen);
- QDpi dpi = d->logicalDpi;
+ QDpi dpi = QHighDpiScaling::isActive() ? QHighDpiScaling::logicalDpi() : d->logicalDpi;
return (dpi.first + dpi.second) * qreal(0.5);
}
@@ -258,7 +289,7 @@ qreal QScreen::logicalDotsPerInch() const
qreal QScreen::devicePixelRatio() const
{
Q_D(const QScreen);
- return d->platformScreen->devicePixelRatio();
+ return d->platformScreen->devicePixelRatio() * QHighDpiScaling::factor(this);
}
/*!
@@ -328,6 +359,7 @@ QList<QScreen *> QScreen::virtualSiblings() const
Q_D(const QScreen);
QList<QPlatformScreen *> platformScreens = d->platformScreen->virtualSiblings();
QList<QScreen *> screens;
+ screens.reserve(platformScreens.count());
foreach (QPlatformScreen *platformScreen, platformScreens)
screens << platformScreen->screen();
return screens;
@@ -589,7 +621,7 @@ bool QScreen::isLandscape(Qt::ScreenOrientation o) const
\fn void QScreen::orientationChanged(Qt::ScreenOrientation orientation)
This signal is emitted when the orientation of the screen
- changes.
+ changes with \a orientation as an argument.
\sa orientation()
*/
@@ -598,7 +630,7 @@ bool QScreen::isLandscape(Qt::ScreenOrientation o) const
\fn void QScreen::primaryOrientationChanged(Qt::ScreenOrientation orientation)
This signal is emitted when the primary orientation of the screen
- changes.
+ changes with \a orientation as an argument.
\sa primaryOrientation()
*/
@@ -648,10 +680,47 @@ QPixmap QScreen::grabWindow(WId window, int x, int y, int width, int height)
{
const QPlatformScreen *platformScreen = handle();
if (!platformScreen) {
- qWarning("%s invoked with handle==0", Q_FUNC_INFO);
+ qWarning("invoked with handle==0");
return QPixmap();
}
return platformScreen->grabWindow(window, x, y, width, height);
}
+#ifndef QT_NO_DEBUG_STREAM
+
+static inline void formatRect(QDebug &debug, const QRect r)
+{
+ debug << r.width() << 'x' << r.height()
+ << forcesign << r.x() << r.y() << noforcesign;
+}
+
+Q_GUI_EXPORT QDebug operator<<(QDebug debug, const QScreen *screen)
+{
+ const QDebugStateSaver saver(debug);
+ debug.nospace();
+ debug << "QScreen(" << (const void *)screen;
+ if (screen) {
+ debug << ", name=" << screen->name();
+ if (debug.verbosity() > 2) {
+ if (screen == QGuiApplication::primaryScreen())
+ debug << ", primary";
+ debug << ", geometry=";
+ formatRect(debug, screen->geometry());
+ debug << ", available=";
+ formatRect(debug, screen->availableGeometry());
+ debug << ", logical DPI=" << screen->logicalDotsPerInchX()
+ << ',' << screen->logicalDotsPerInchY()
+ << ", physical DPI=" << screen->physicalDotsPerInchX()
+ << ',' << screen->physicalDotsPerInchY()
+ << ", devicePixelRatio=" << screen->devicePixelRatio()
+ << ", orientation=" << screen->orientation()
+ << ", physical size=" << screen->physicalSize().width()
+ << 'x' << screen->physicalSize().height() << "mm";
+ }
+ }
+ debug << ')';
+ return debug;
+}
+#endif // !QT_NO_DEBUG_STREAM
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qscreen.h b/src/gui/kernel/qscreen.h
index 255e735baf..a6018128e2 100644
--- a/src/gui/kernel/qscreen.h
+++ b/src/gui/kernel/qscreen.h
@@ -52,6 +52,9 @@ class QScreenPrivate;
class QWindow;
class QRect;
class QPixmap;
+#ifndef QT_NO_DEBUG_STREAM
+class QDebug;
+#endif
class Q_GUI_EXPORT QScreen : public QObject
{
@@ -151,8 +154,13 @@ private:
friend class QGuiApplicationPrivate;
friend class QPlatformIntegration;
friend class QPlatformScreen;
+ friend class QHighDpiScaling;
};
+#ifndef QT_NO_DEBUG_STREAM
+Q_GUI_EXPORT QDebug operator<<(QDebug, const QScreen *);
+#endif
+
QT_END_NAMESPACE
#endif // QSCREEN_H
diff --git a/src/gui/kernel/qscreen_p.h b/src/gui/kernel/qscreen_p.h
index d341b71932..4492eddd45 100644
--- a/src/gui/kernel/qscreen_p.h
+++ b/src/gui/kernel/qscreen_p.h
@@ -47,6 +47,7 @@
#include <QtGui/qscreen.h>
#include <qpa/qplatformscreen.h>
+#include "qhighdpiscaling_p.h"
#include <QtCore/private/qobject_p.h>
@@ -54,25 +55,19 @@ QT_BEGIN_NAMESPACE
class QScreenPrivate : public QObjectPrivate
{
+ Q_DECLARE_PUBLIC(QScreen)
public:
- QScreenPrivate(QPlatformScreen *screen)
- : platformScreen(screen)
+ QScreenPrivate()
+ : platformScreen(0)
, orientationUpdateMask(0)
{
- orientation = platformScreen->orientation();
- geometry = platformScreen->geometry();
- availableGeometry = platformScreen->availableGeometry();
- logicalDpi = platformScreen->logicalDpi();
- refreshRate = platformScreen->refreshRate();
- // safeguard ourselves against buggy platform behavior...
- if (refreshRate < 1.0)
- refreshRate = 60.0;
-
- updatePrimaryOrientation();
+ }
- filteredOrientation = orientation;
- if (filteredOrientation == Qt::PrimaryOrientation)
- filteredOrientation = primaryOrientation;
+ void setPlatformScreen(QPlatformScreen *screen);
+ void updateHighDpi()
+ {
+ geometry = platformScreen->deviceIndependentGeometry();
+ availableGeometry = QHighDpi::fromNative(platformScreen->availableGeometry(), QHighDpiScaling::factor(platformScreen), geometry.topLeft());
}
void updatePrimaryOrientation();
diff --git a/src/gui/kernel/qshapedpixmapdndwindow.cpp b/src/gui/kernel/qshapedpixmapdndwindow.cpp
index 8f80789fb0..d77b6dc262 100644
--- a/src/gui/kernel/qshapedpixmapdndwindow.cpp
+++ b/src/gui/kernel/qshapedpixmapdndwindow.cpp
@@ -35,12 +35,16 @@
#include <QtGui/QPainter>
#include <QtGui/QCursor>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QPalette>
+#include <QtGui/QBitmap>
QT_BEGIN_NAMESPACE
-QShapedPixmapWindow::QShapedPixmapWindow()
- : QWindow(),
- m_backingStore(0)
+QShapedPixmapWindow::QShapedPixmapWindow(QScreen *screen)
+ : QWindow(screen),
+ m_backingStore(0),
+ m_useCompositing(true)
{
QSurfaceFormat format;
format.setAlphaBufferSize(8);
@@ -68,7 +72,10 @@ void QShapedPixmapWindow::render()
{
QPainter p(device);
- p.setCompositionMode(QPainter::CompositionMode_Source);
+ if (m_useCompositing)
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ else
+ p.fillRect(rect, QGuiApplication::palette().base());
p.drawPixmap(0, 0, m_pixmap);
}
@@ -79,6 +86,8 @@ void QShapedPixmapWindow::render()
void QShapedPixmapWindow::setPixmap(const QPixmap &pixmap)
{
m_pixmap = pixmap;
+ if (!m_useCompositing)
+ setMask(m_pixmap.mask());
}
void QShapedPixmapWindow::setHotspot(const QPoint &hotspot)
diff --git a/src/gui/kernel/qshapedpixmapdndwindow_p.h b/src/gui/kernel/qshapedpixmapdndwindow_p.h
index fc311cff92..3d7974fa82 100644
--- a/src/gui/kernel/qshapedpixmapdndwindow_p.h
+++ b/src/gui/kernel/qshapedpixmapdndwindow_p.h
@@ -55,11 +55,12 @@ class QShapedPixmapWindow : public QWindow
{
Q_OBJECT
public:
- QShapedPixmapWindow();
+ explicit QShapedPixmapWindow(QScreen *screen = 0);
~QShapedPixmapWindow();
void render();
+ void setUseCompositing(bool on) { m_useCompositing = on; }
void setPixmap(const QPixmap &pixmap);
void setHotspot(const QPoint &hotspot);
@@ -72,6 +73,7 @@ private:
QBackingStore *m_backingStore;
QPixmap m_pixmap;
QPoint m_hotSpot;
+ bool m_useCompositing;
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp
index 3e267f2e0b..3941f7233f 100644
--- a/src/gui/kernel/qshortcutmap.cpp
+++ b/src/gui/kernel/qshortcutmap.cpp
@@ -84,7 +84,7 @@ struct QShortcutEntry
QShortcutMap::ContextMatcher contextMatcher;
};
-#if 0 //ndef QT_NO_DEBUG_STREAM
+#ifdef Dump_QShortcutMap
/*! \internal
QDebug operator<< for easy debug output of the shortcut entries.
*/
@@ -99,7 +99,7 @@ static QDebug &operator<<(QDebug &dbg, const QShortcutEntry *se)
<< "), owner(" << se->owner << ')';
return dbg;
}
-#endif // QT_NO_DEBUGSTREAM
+#endif // Dump_QShortcutMap
/* \internal
Private data for QShortcutMap
@@ -309,59 +309,46 @@ QKeySequence::SequenceMatch QShortcutMap::state()
}
/*! \internal
- Uses ShortcutOverride event to see if any widgets want to override
- the event. If not, uses nextState(QKeyEvent) to check for a grabbed
- Shortcut, and dispatchEvent() is found and identical.
+ Uses nextState(QKeyEvent) to check for a grabbed shortcut.
- \note that this function should only be called from QWindowSystemInterface,
- otherwise it will result in duplicate events.
+ If so, it is dispatched using dispatchEvent().
+
+ Returns true if a shortcut handled the event.
\sa nextState, dispatchEvent
*/
-bool QShortcutMap::tryShortcutEvent(QObject *o, QKeyEvent *e)
+bool QShortcutMap::tryShortcut(QKeyEvent *e)
{
Q_D(QShortcutMap);
if (e->key() == Qt::Key_unknown)
return false;
- bool wasAccepted = e->isAccepted();
- bool wasSpontaneous = e->spont;
- if (d->currentState == QKeySequence::NoMatch) {
- ushort orgType = e->t;
- e->t = QEvent::ShortcutOverride;
- e->ignore();
- QCoreApplication::sendEvent(o, e);
- e->t = orgType;
- e->spont = wasSpontaneous;
- if (e->isAccepted()) {
- if (!wasAccepted)
- e->ignore();
- return false;
- }
- }
-
- QKeySequence::SequenceMatch result = nextState(e);
- bool stateWasAccepted = e->isAccepted();
- if (wasAccepted)
- e->accept();
- else
- e->ignore();
-
- int identicalMatches = d->identicals.count();
+ QKeySequence::SequenceMatch previousState = state();
- switch(result) {
+ switch (nextState(e)) {
case QKeySequence::NoMatch:
- return stateWasAccepted;
- case QKeySequence::ExactMatch:
+ // In the case of going from a partial match to no match we handled the
+ // event, since we already stated that we did for the partial match. But
+ // in the normal case of directly going to no match we say we didn't.
+ return previousState == QKeySequence::PartialMatch;
+ case QKeySequence::PartialMatch:
+ // For a partial match we don't know yet if we will handle the shortcut
+ // but we need to say we did, so that we get the follow-up key-presses.
+ return true;
+ case QKeySequence::ExactMatch: {
+ // Save number of identical matches before dispatching
+ // to keep QShortcutMap and tryShortcut reentrant.
+ const int identicalMatches = d->identicals.count();
resetState();
dispatchEvent(e);
+ // If there are no identicals we've only found disabled shortcuts, and
+ // shouldn't say that we handled the event.
+ return identicalMatches > 0;
+ }
default:
- break;
+ Q_UNREACHABLE();
}
- // If nextState is QKeySequence::ExactMatch && identicals.count == 0
- // we've only found disabled shortcuts
- return identicalMatches > 0 || result == QKeySequence::PartialMatch;
}
/*! \internal
@@ -396,10 +383,6 @@ QKeySequence::SequenceMatch QShortcutMap::nextState(QKeyEvent *e)
}
}
- // Should we eat this key press?
- if (d->currentState == QKeySequence::PartialMatch
- || (d->currentState == QKeySequence::ExactMatch && d->identicals.count()))
- e->accept();
// Does the new state require us to clean up?
if (result == QKeySequence::NoMatch)
clearSequence(d->currentSequences);
diff --git a/src/gui/kernel/qshortcutmap_p.h b/src/gui/kernel/qshortcutmap_p.h
index 2376d27c78..16542b078a 100644
--- a/src/gui/kernel/qshortcutmap_p.h
+++ b/src/gui/kernel/qshortcutmap_p.h
@@ -75,7 +75,9 @@ public:
int setShortcutEnabled(bool enable, int id, QObject *owner, const QKeySequence &key = QKeySequence());
int setShortcutAutoRepeat(bool on, int id, QObject *owner, const QKeySequence &key = QKeySequence());
- bool tryShortcutEvent(QObject *o, QKeyEvent *e);
+ QKeySequence::SequenceMatch state();
+
+ bool tryShortcut(QKeyEvent *e);
bool hasShortcutForKeySequence(const QKeySequence &seq) const;
#ifdef Dump_QShortcutMap
@@ -85,7 +87,6 @@ public:
private:
void resetState();
QKeySequence::SequenceMatch nextState(QKeyEvent *e);
- QKeySequence::SequenceMatch state();
void dispatchEvent(QKeyEvent *e);
QKeySequence::SequenceMatch find(QKeyEvent *e, int ignoredModifiers = 0);
diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp
index b850f53014..9f38c9b78a 100644
--- a/src/gui/kernel/qsimpledrag.cpp
+++ b/src/gui/kernel/qsimpledrag.cpp
@@ -55,6 +55,7 @@
#include <private/qdnd_p.h>
#include <private/qshapedpixmapdndwindow_p.h>
+#include <private/qhighdpiscaling_p.h>
QT_BEGIN_NAMESPACE
@@ -87,7 +88,7 @@ static QWindow* topLevelAt(const QPoint &pos)
QBasicDrag::QBasicDrag() :
m_restoreCursor(false), m_eventLoop(0),
m_executed_drop_action(Qt::IgnoreAction), m_can_drop(false),
- m_drag(0), m_drag_icon_window(0)
+ m_drag(0), m_drag_icon_window(0), m_useCompositing(true)
{
}
@@ -106,6 +107,12 @@ void QBasicDrag::disableEventFilter()
qApp->removeEventFilter(this);
}
+
+static inline QPoint getNativeMousePos(QEvent *e, QObject *o)
+{
+ return QHighDpi::toNativePixels(static_cast<QMouseEvent *>(e)->globalPos(), qobject_cast<QWindow*>(o));
+}
+
bool QBasicDrag::eventFilter(QObject *o, QEvent *e)
{
Q_UNUSED(o);
@@ -139,20 +146,22 @@ bool QBasicDrag::eventFilter(QObject *o, QEvent *e)
}
case QEvent::MouseMove:
- move(static_cast<QMouseEvent *>(e));
- return true; // Eat all mouse events
-
+ {
+ QPoint nativePosition = getNativeMousePos(e, o);
+ move(nativePosition);
+ return true; // Eat all mouse move events
+ }
case QEvent::MouseButtonRelease:
disableEventFilter();
if (canDrop()) {
- drop(static_cast<QMouseEvent *>(e));
+ QPoint nativePosition = getNativeMousePos(e, o);
+ drop(nativePosition);
} else {
cancel();
}
exitDndEventLoop();
- return true; // Eat all mouse events
-
- case QEvent::MouseButtonPress:
+ QCoreApplication::postEvent(o, new QMouseEvent(*static_cast<QMouseEvent *>(e)));
+ return true; // defer mouse release events until drag event loop has returned
case QEvent::MouseButtonDblClick:
case QEvent::Wheel:
return true;
@@ -194,25 +203,15 @@ void QBasicDrag::restoreCursor()
void QBasicDrag::startDrag()
{
- // ### TODO Check if its really necessary to have m_drag_icon_window
- // when QDrag is used without a pixmap - QDrag::setPixmap()
- if (!m_drag_icon_window)
- m_drag_icon_window = new QShapedPixmapWindow();
-
- m_drag_icon_window->setPixmap(m_drag->pixmap());
- m_drag_icon_window->setHotspot(m_drag->hotSpot());
-
+ QPoint pos;
#ifndef QT_NO_CURSOR
- QPoint pos = QCursor::pos();
+ pos = QCursor::pos();
if (pos.x() == int(qInf())) {
// ### fixme: no mouse pos registered. Get pos from touch...
pos = QPoint();
}
- m_drag_icon_window->updateGeometry(pos);
#endif
-
- m_drag_icon_window->setVisible(true);
-
+ recreateShapedPixmapWindow(Q_NULLPTR, pos);
enableEventFilter();
}
@@ -220,6 +219,20 @@ void QBasicDrag::endDrag()
{
}
+void QBasicDrag::recreateShapedPixmapWindow(QScreen *screen, const QPoint &pos)
+{
+ delete m_drag_icon_window;
+ // ### TODO Check if its really necessary to have m_drag_icon_window
+ // when QDrag is used without a pixmap - QDrag::setPixmap()
+ m_drag_icon_window = new QShapedPixmapWindow(screen);
+
+ m_drag_icon_window->setUseCompositing(m_useCompositing);
+ m_drag_icon_window->setPixmap(m_drag->pixmap());
+ m_drag_icon_window->setHotspot(m_drag->hotSpot());
+ m_drag_icon_window->updateGeometry(pos);
+ m_drag_icon_window->setVisible(true);
+}
+
void QBasicDrag::cancel()
{
disableEventFilter();
@@ -227,13 +240,18 @@ void QBasicDrag::cancel()
m_drag_icon_window->setVisible(false);
}
-void QBasicDrag::move(const QMouseEvent *e)
+/*!
+ Move the drag label to \a globalPos, which is
+ interpreted in device independent coordinates. Typically called from reimplementations of move().
+ */
+
+void QBasicDrag::moveShapedPixmapWindow(const QPoint &globalPos)
{
if (m_drag)
- m_drag_icon_window->updateGeometry(e->globalPos());
+ m_drag_icon_window->updateGeometry(globalPos);
}
-void QBasicDrag::drop(const QMouseEvent *)
+void QBasicDrag::drop(const QPoint &)
{
disableEventFilter();
restoreCursor();
@@ -330,14 +348,15 @@ void QSimpleDrag::cancel()
}
}
-void QSimpleDrag::move(const QMouseEvent *me)
+void QSimpleDrag::move(const QPoint &globalPos)
{
- QBasicDrag::move(me);
- QWindow *window = topLevelAt(me->globalPos());
+ //### not high-DPI aware
+ moveShapedPixmapWindow(globalPos);
+ QWindow *window = topLevelAt(globalPos);
if (!window)
return;
- const QPoint pos = me->globalPos() - window->geometry().topLeft();
+ const QPoint pos = globalPos - window->geometry().topLeft();
const QPlatformDragQtResponse qt_response =
QWindowSystemInterface::handleDrag(window, drag()->mimeData(), pos, drag()->supportedActions());
@@ -345,14 +364,16 @@ void QSimpleDrag::move(const QMouseEvent *me)
setCanDrop(qt_response.isAccepted());
}
-void QSimpleDrag::drop(const QMouseEvent *me)
+void QSimpleDrag::drop(const QPoint &globalPos)
{
- QBasicDrag::drop(me);
- QWindow *window = topLevelAt(me->globalPos());
+ //### not high-DPI aware
+
+ QBasicDrag::drop(globalPos);
+ QWindow *window = topLevelAt(globalPos);
if (!window)
return;
- const QPoint pos = me->globalPos() - window->geometry().topLeft();
+ const QPoint pos = globalPos - window->geometry().topLeft();
const QPlatformDropQtResponse response =
QWindowSystemInterface::handleDrop(window, drag()->mimeData(),pos, drag()->supportedActions());
if (response.isAccepted()) {
diff --git a/src/gui/kernel/qsimpledrag_p.h b/src/gui/kernel/qsimpledrag_p.h
index 7812f8b863..055136c436 100644
--- a/src/gui/kernel/qsimpledrag_p.h
+++ b/src/gui/kernel/qsimpledrag_p.h
@@ -58,6 +58,7 @@ class QWindow;
class QEventLoop;
class QDropData;
class QShapedPixmapWindow;
+class QScreen;
class Q_GUI_EXPORT QBasicDrag : public QPlatformDrag, public QObject
{
@@ -73,16 +74,22 @@ protected:
virtual void startDrag();
virtual void cancel();
- virtual void move(const QMouseEvent *me);
- virtual void drop(const QMouseEvent *me);
+ virtual void move(const QPoint &globalPos) = 0;
+ virtual void drop(const QPoint &globalPos) = 0;
virtual void endDrag();
+
+ void moveShapedPixmapWindow(const QPoint &deviceIndependentPosition);
QShapedPixmapWindow *shapedPixmapWindow() const { return m_drag_icon_window; }
+ void recreateShapedPixmapWindow(QScreen *screen, const QPoint &pos);
void updateCursor(Qt::DropAction action);
bool canDrop() const { return m_can_drop; }
void setCanDrop(bool c) { m_can_drop = c; }
+ bool useCompositing() const { return m_useCompositing; }
+ void setUseCompositing(bool on) { m_useCompositing = on; }
+
Qt::DropAction executedDropAction() const { return m_executed_drop_action; }
void setExecutedDropAction(Qt::DropAction da) { m_executed_drop_action = da; }
@@ -100,6 +107,7 @@ private:
bool m_can_drop;
QDrag *m_drag;
QShapedPixmapWindow *m_drag_icon_window;
+ bool m_useCompositing;
};
class Q_GUI_EXPORT QSimpleDrag : public QBasicDrag
@@ -111,8 +119,8 @@ public:
protected:
virtual void startDrag() Q_DECL_OVERRIDE;
virtual void cancel() Q_DECL_OVERRIDE;
- virtual void move(const QMouseEvent *me) Q_DECL_OVERRIDE;
- virtual void drop(const QMouseEvent *me) Q_DECL_OVERRIDE;
+ virtual void move(const QPoint &globalPos) Q_DECL_OVERRIDE;
+ virtual void drop(const QPoint &globalPos) Q_DECL_OVERRIDE;
private:
QWindow *m_current_window;
diff --git a/src/gui/kernel/qstylehints.cpp b/src/gui/kernel/qstylehints.cpp
index 7ff0f9f860..7fc89112e6 100644
--- a/src/gui/kernel/qstylehints.cpp
+++ b/src/gui/kernel/qstylehints.cpp
@@ -305,7 +305,7 @@ int QStyleHints::cursorFlashTime() const
\note The platform may still choose to show certain windows non-fullscreen,
such as popups or dialogs. This property only reports the default behavior.
- \sa QWindow::show()
+ \sa QWindow::show(), showIsMaximized()
*/
bool QStyleHints::showIsFullScreen() const
{
@@ -313,6 +313,22 @@ bool QStyleHints::showIsFullScreen() const
}
/*!
+ \property QStyleHints::showIsMaximized
+ \brief \c true if the platform defaults to windows being maximized,
+ otherwise \c false.
+
+ \note The platform may still choose to show certain windows non-maximized,
+ such as popups or dialogs. This property only reports the default behavior.
+
+ \sa QWindow::show(), showIsFullScreen()
+ \since 5.6
+*/
+bool QStyleHints::showIsMaximized() const
+{
+ return hint(QPlatformIntegration::ShowIsMaximized).toBool();
+}
+
+/*!
\property QStyleHints::passwordMaskDelay
\brief the time, in milliseconds, a typed letter is displayed unshrouded
in a text input field in password mode.
diff --git a/src/gui/kernel/qstylehints.h b/src/gui/kernel/qstylehints.h
index 82eb8a6f7d..c5b8241e07 100644
--- a/src/gui/kernel/qstylehints.h
+++ b/src/gui/kernel/qstylehints.h
@@ -56,6 +56,7 @@ class Q_GUI_EXPORT QStyleHints : public QObject
Q_PROPERTY(int passwordMaskDelay READ passwordMaskDelay STORED false CONSTANT FINAL)
Q_PROPERTY(bool setFocusOnTouchRelease READ setFocusOnTouchRelease STORED false CONSTANT FINAL)
Q_PROPERTY(bool showIsFullScreen READ showIsFullScreen STORED false CONSTANT FINAL)
+ Q_PROPERTY(bool showIsMaximized READ showIsMaximized STORED false CONSTANT FINAL)
Q_PROPERTY(int startDragDistance READ startDragDistance NOTIFY startDragDistanceChanged FINAL)
Q_PROPERTY(int startDragTime READ startDragTime NOTIFY startDragTimeChanged FINAL)
Q_PROPERTY(int startDragVelocity READ startDragVelocity STORED false CONSTANT FINAL)
@@ -78,6 +79,7 @@ public:
void setCursorFlashTime(int cursorFlashTime);
int cursorFlashTime() const;
bool showIsFullScreen() const;
+ bool showIsMaximized() const;
int passwordMaskDelay() const;
QChar passwordMaskCharacter() const;
qreal fontSmoothingGamma() const;
diff --git a/src/gui/kernel/qtouchdevice.cpp b/src/gui/kernel/qtouchdevice.cpp
index 1a6e9deba8..266b5308a2 100644
--- a/src/gui/kernel/qtouchdevice.cpp
+++ b/src/gui/kernel/qtouchdevice.cpp
@@ -195,7 +195,7 @@ void QTouchDevice::setName(const QString &name)
d->name = name;
}
-typedef QList<QTouchDevice *> TouchDevices;
+typedef QList<const QTouchDevice *> TouchDevices;
Q_GLOBAL_STATIC(TouchDevices, deviceList)
static QBasicMutex devicesMutex;
@@ -214,26 +214,22 @@ static void cleanupDevicesList()
QList<const QTouchDevice *> QTouchDevice::devices()
{
QMutexLocker lock(&devicesMutex);
- QList<QTouchDevice *> *devList = deviceList();
- QList<const QTouchDevice *> constDevList;
- for (int i = 0, count = devList->count(); i != count; ++i)
- constDevList.append(devList->at(i));
- return constDevList;
+ return *deviceList();
}
/*!
\internal
*/
-bool QTouchDevicePrivate::isRegistered(QTouchDevice *dev)
+bool QTouchDevicePrivate::isRegistered(const QTouchDevice *dev)
{
- QMutexLocker lock(&devicesMutex);
+ QMutexLocker locker(&devicesMutex);
return deviceList()->contains(dev);
}
/*!
\internal
*/
-void QTouchDevicePrivate::registerDevice(QTouchDevice *dev)
+void QTouchDevicePrivate::registerDevice(const QTouchDevice *dev)
{
QMutexLocker lock(&devicesMutex);
if (deviceList()->isEmpty())
@@ -241,6 +237,17 @@ void QTouchDevicePrivate::registerDevice(QTouchDevice *dev)
deviceList()->append(dev);
}
+/*!
+ \internal
+ */
+void QTouchDevicePrivate::unregisterDevice(const QTouchDevice *dev)
+{
+ QMutexLocker lock(&devicesMutex);
+ bool wasRemoved = deviceList()->removeOne(dev);
+ if (wasRemoved && deviceList()->isEmpty())
+ qRemovePostRoutine(cleanupDevicesList);
+}
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, const QTouchDevice *device)
{
diff --git a/src/gui/kernel/qtouchdevice_p.h b/src/gui/kernel/qtouchdevice_p.h
index 9c0bcf3414..63b83d33ec 100644
--- a/src/gui/kernel/qtouchdevice_p.h
+++ b/src/gui/kernel/qtouchdevice_p.h
@@ -45,7 +45,6 @@
// We mean it.
//
-#include <QtCore/qobject.h>
#include <QtGui/qtouchdevice.h>
QT_BEGIN_NAMESPACE
@@ -65,8 +64,9 @@ public:
QString name;
int maxTouchPoints;
- static void registerDevice(QTouchDevice *dev);
- static bool isRegistered(QTouchDevice *dev);
+ static void registerDevice(const QTouchDevice *dev);
+ static void unregisterDevice(const QTouchDevice *dev);
+ static bool isRegistered(const QTouchDevice *dev);
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 871437efb1..21734f1619 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -47,6 +47,7 @@
#ifndef QT_NO_ACCESSIBILITY
# include "qaccessible.h"
#endif
+#include "qhighdpiscaling_p.h"
#include <private/qevent_p.h>
@@ -368,7 +369,7 @@ void QWindowPrivate::setTopLevelScreen(QScreen *newScreen, bool recreate)
{
Q_Q(QWindow);
if (parentWindow) {
- qWarning() << this << Q_FUNC_INFO << '(' << newScreen << "): Attempt to set a screen on a child window.";
+ qWarning() << this << '(' << newScreen << "): Attempt to set a screen on a child window.";
return;
}
if (newScreen != topLevelScreen) {
@@ -388,25 +389,31 @@ void QWindowPrivate::setTopLevelScreen(QScreen *newScreen, bool recreate)
void QWindowPrivate::create(bool recursive)
{
Q_Q(QWindow);
+ if (platformWindow)
+ return;
+
+ platformWindow = QGuiApplicationPrivate::platformIntegration()->createPlatformWindow(q);
+ Q_ASSERT(platformWindow);
+
if (!platformWindow) {
- platformWindow = QGuiApplicationPrivate::platformIntegration()->createPlatformWindow(q);
- QObjectList childObjects = q->children();
- for (int i = 0; i < childObjects.size(); i ++) {
- QObject *object = childObjects.at(i);
- if (object->isWindowType()) {
- QWindow *window = static_cast<QWindow *>(object);
- if (recursive)
- window->d_func()->create(true);
- if (window->d_func()->platformWindow)
- window->d_func()->platformWindow->setParent(platformWindow);
- }
- }
+ qWarning() << "Failed to create platform window for" << q << "with flags" << q->flags();
+ return;
+ }
- if (platformWindow) {
- QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceCreated);
- QGuiApplication::sendEvent(q, &e);
+ QObjectList childObjects = q->children();
+ for (int i = 0; i < childObjects.size(); i ++) {
+ QObject *object = childObjects.at(i);
+ if (object->isWindowType()) {
+ QWindow *window = static_cast<QWindow *>(object);
+ if (recursive)
+ window->d_func()->create(true);
+ if (window->d_func()->platformWindow)
+ window->d_func()->platformWindow->setParent(platformWindow);
}
}
+
+ QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceCreated);
+ QGuiApplication::sendEvent(q, &e);
}
void QWindowPrivate::clearFocusObject()
@@ -587,8 +594,7 @@ QWindow *QWindow::parent() const
Setting \a parent to be 0 will make the window become a top level window.
If \a parent is a window created by fromWinId(), then the current window
- will be embedded inside \a parent, if the platform supports it. Window
- embedding is currently supported only by the X11 platform plugin.
+ will be embedded inside \a parent, if the platform supports it.
*/
void QWindow::setParent(QWindow *parent)
{
@@ -598,11 +604,13 @@ void QWindow::setParent(QWindow *parent)
QScreen *newScreen = parent ? parent->screen() : screen();
if (d->windowRecreationRequired(newScreen)) {
- qWarning() << this << Q_FUNC_INFO << '(' << parent << "): Cannot change screens (" << screen() << newScreen << ')';
+ qWarning() << this << '(' << parent << "): Cannot change screens (" << screen() << newScreen << ')';
return;
}
QObject::setParent(parent);
+ d->parentWindow = parent;
+
if (parent)
d->disconnectFromScreen();
else
@@ -616,8 +624,6 @@ void QWindow::setParent(QWindow *parent)
}
}
- d->parentWindow = parent;
-
QGuiApplicationPrivate::updateBlockedStatus(this);
}
@@ -1085,13 +1091,13 @@ qreal QWindow::devicePixelRatio() const
{
Q_D(const QWindow);
- // If there is no platform window, do the second best thing and
- // return the app global devicePixelRatio. This is the highest
- // devicePixelRatio found on the system screens, and will be
- // correct for single-display systems (a very common case).
+ // If there is no platform window use the app global devicePixelRatio,
+ // which is the the highest devicePixelRatio found on the system
+ // screens, and will be correct for single-display systems (a very common case).
if (!d->platformWindow)
return qApp->devicePixelRatio();
- return d->platformWindow->devicePixelRatio();
+
+ return d->platformWindow->devicePixelRatio() * QHighDpiScaling::factor(this);
}
/*!
@@ -1154,7 +1160,7 @@ void QWindow::setTransientParent(QWindow *parent)
{
Q_D(QWindow);
if (parent && !parent->isTopLevel()) {
- qWarning() << Q_FUNC_INFO << parent << "must be a top level window.";
+ qWarning() << parent << "must be a top level window.";
return;
}
@@ -1437,7 +1443,13 @@ void QWindow::setGeometry(const QRect &rect)
d->positionPolicy = QWindowPrivate::WindowFrameExclusive;
if (d->platformWindow) {
- d->platformWindow->setGeometry(rect);
+ QRect nativeRect;
+ QScreen *newScreen = d->screenForGeometry(rect);
+ if (newScreen && isTopLevel())
+ nativeRect = QHighDpi::toNativePixels(rect, newScreen);
+ else
+ nativeRect = QHighDpi::toNativePixels(rect, this);
+ d->platformWindow->setGeometry(nativeRect);
} else {
d->geometry = rect;
@@ -1452,6 +1464,30 @@ void QWindow::setGeometry(const QRect &rect)
}
}
+/*
+ This is equivalent to QPlatformWindow::screenForGeometry, but in platform
+ independent coordinates. The duplication is unfortunate, but there is a
+ chicken and egg problem here: we cannot convert to native coordinates
+ before we know which screen we are on.
+*/
+QScreen *QWindowPrivate::screenForGeometry(const QRect &newGeometry)
+{
+ Q_Q(QWindow);
+ QScreen *currentScreen = q->screen();
+ QScreen *fallback = currentScreen;
+ QPoint center = newGeometry.center();
+ if (!q->parent() && currentScreen && !currentScreen->geometry().contains(center)) {
+ Q_FOREACH (QScreen* screen, currentScreen->virtualSiblings()) {
+ if (screen->geometry().contains(center))
+ return screen;
+ if (screen->geometry().intersects(newGeometry))
+ fallback = screen;
+ }
+ }
+ return fallback;
+}
+
+
/*!
Returns the geometry of the window, excluding its window frame.
@@ -1461,7 +1497,7 @@ QRect QWindow::geometry() const
{
Q_D(const QWindow);
if (d->platformWindow)
- return d->platformWindow->geometry();
+ return QHighDpi::fromNativePixels(d->platformWindow->geometry(), this);
return d->geometry;
}
@@ -1474,7 +1510,7 @@ QMargins QWindow::frameMargins() const
{
Q_D(const QWindow);
if (d->platformWindow)
- return d->platformWindow->frameMargins();
+ return QHighDpi::fromNativePixels(d->platformWindow->frameMargins(), this);
return QMargins();
}
@@ -1488,7 +1524,7 @@ QRect QWindow::frameGeometry() const
Q_D(const QWindow);
if (d->platformWindow) {
QMargins m = frameMargins();
- return d->platformWindow->geometry().adjusted(-m.left(), -m.top(), m.right(), m.bottom());
+ return QHighDpi::fromNativePixels(d->platformWindow->geometry(), this).adjusted(-m.left(), -m.top(), m.right(), m.bottom());
}
return d->geometry;
}
@@ -1505,7 +1541,7 @@ QPoint QWindow::framePosition() const
Q_D(const QWindow);
if (d->platformWindow) {
QMargins margins = frameMargins();
- return d->platformWindow->geometry().topLeft() - QPoint(margins.left(), margins.top());
+ return QHighDpi::fromNativePixels(d->platformWindow->geometry().topLeft(), this) - QPoint(margins.left(), margins.top());
}
return d->geometry.topLeft();
}
@@ -1521,7 +1557,7 @@ void QWindow::setFramePosition(const QPoint &point)
d->positionPolicy = QWindowPrivate::WindowFrameInclusive;
d->positionAutomatic = false;
if (d->platformWindow) {
- d->platformWindow->setGeometry(QRect(point, size()));
+ d->platformWindow->setGeometry(QHighDpi::toNativePixels(QRect(point, size()), this));
} else {
d->geometry.moveTopLeft(point);
}
@@ -1581,7 +1617,7 @@ void QWindow::resize(const QSize &newSize)
{
Q_D(QWindow);
if (d->platformWindow) {
- d->platformWindow->setGeometry(QRect(position(), newSize));
+ d->platformWindow->setGeometry(QHighDpi::toNativePixels(QRect(position(), newSize), this));
} else {
const QSize oldSize = d->geometry.size();
d->geometry.setSize(newSize);
@@ -2261,10 +2297,10 @@ QPoint QWindow::mapToGlobal(const QPoint &pos) const
Q_D(const QWindow);
// QTBUG-43252, prefer platform implementation for foreign windows.
if (d->platformWindow
- && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded(0))) {
+ && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded())) {
return d->platformWindow->mapToGlobal(pos);
}
- return pos + d_func()->globalPosition();
+ return pos + d->globalPosition();
}
@@ -2281,10 +2317,10 @@ QPoint QWindow::mapFromGlobal(const QPoint &pos) const
Q_D(const QWindow);
// QTBUG-43252, prefer platform implementation for foreign windows.
if (d->platformWindow
- && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded(0))) {
+ && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded())) {
return d->platformWindow->mapFromGlobal(pos);
}
- return pos - d_func()->globalPosition();
+ return pos - d->globalPosition();
}
@@ -2346,9 +2382,16 @@ QWindow *QWindowPrivate::topLevelWindow() const
Given the handle \a id to a native window, this method creates a QWindow
object which can be used to represent the window when invoking methods like
setParent() and setTransientParent().
- This can be used, on platforms which support it, to embed a window inside a
- container or to make a window stick on top of a window created by another
- process.
+
+ This can be used, on platforms which support it, to embed a QWindow inside a
+ native window, or to embed a native window inside a QWindow.
+
+ If foreign windows are not supported, this function returns 0.
+
+ \note The resulting QWindow should not be used to manipulate the underlying
+ native window (besides re-parenting), or to observe state changes of the
+ native window. Any support for these kind of operations is incidental, highly
+ platform dependent and untested.
\sa setParent()
\sa setTransientParent()
@@ -2477,6 +2520,45 @@ void QWindowPrivate::applyCursor()
}
#endif // QT_NO_CURSOR
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug debug, const QWindow *window)
+{
+ QDebugStateSaver saver(debug);
+ debug.nospace();
+ if (window) {
+ debug << window->metaObject()->className() << '(' << (const void *)window;
+ if (!window->objectName().isEmpty())
+ debug << ", name=" << window->objectName();
+ if (debug.verbosity() > 2) {
+ const QRect geometry = window->geometry();
+ if (window->isVisible())
+ debug << ", visible";
+ if (window->isExposed())
+ debug << ", exposed";
+ debug << ", state=" << window->windowState()
+ << ", type=" << window->type() << ", flags=" << window->flags()
+ << ", surface type=" << window->surfaceType();
+ if (window->isTopLevel())
+ debug << ", toplevel";
+ debug << ", " << geometry.width() << 'x' << geometry.height()
+ << forcesign << geometry.x() << geometry.y() << noforcesign;
+ const QMargins margins = window->frameMargins();
+ if (!margins.isNull())
+ debug << ", margins=" << margins;
+ debug << ", devicePixelRatio=" << window->devicePixelRatio();
+ if (const QPlatformWindow *platformWindow = window->handle())
+ debug << ", winId=0x" << hex << platformWindow->winId() << dec;
+ if (const QScreen *screen = window->screen())
+ debug << ", on " << screen->name();
+ }
+ debug << ')';
+ } else {
+ debug << "QWindow(0x0)";
+ }
+ return debug;
+}
+#endif // !QT_NO_DEBUG_STREAM
+
QT_END_NAMESPACE
#include "moc_qwindow.cpp"
diff --git a/src/gui/kernel/qwindow.h b/src/gui/kernel/qwindow.h
index f9fe37718c..b29e7aaae7 100644
--- a/src/gui/kernel/qwindow.h
+++ b/src/gui/kernel/qwindow.h
@@ -78,6 +78,9 @@ class QBackingStore;
class QScreen;
class QAccessibleInterface;
class QWindowContainer;
+#ifndef QT_NO_DEBUG_STREAM
+class QDebug;
+#endif
class Q_GUI_EXPORT QWindow : public QObject, public QSurface
{
@@ -122,7 +125,7 @@ public:
};
Q_ENUM(Visibility)
- explicit QWindow(QScreen *screen = 0);
+ explicit QWindow(QScreen *screen = Q_NULLPTR);
explicit QWindow(QWindow *parent);
virtual ~QWindow();
@@ -357,16 +360,20 @@ private:
#ifndef Q_QDOC
template <> inline QWindow *qobject_cast<QWindow*>(QObject *o)
{
- if (!o || !o->isWindowType()) return 0;
+ if (!o || !o->isWindowType()) return Q_NULLPTR;
return static_cast<QWindow*>(o);
}
template <> inline const QWindow *qobject_cast<const QWindow*>(const QObject *o)
{
- if (!o || !o->isWindowType()) return 0;
+ if (!o || !o->isWindowType()) return Q_NULLPTR;
return static_cast<const QWindow*>(o);
}
#endif // !Q_QDOC
+#ifndef QT_NO_DEBUG_STREAM
+Q_GUI_EXPORT QDebug operator<<(QDebug, const QWindow *);
+#endif
+
QT_END_NAMESPACE
#endif // QWINDOW_H
diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h
index 4fc63acf28..6880edaada 100644
--- a/src/gui/kernel/qwindow_p.h
+++ b/src/gui/kernel/qwindow_p.h
@@ -50,6 +50,7 @@
#include <qpa/qplatformwindow.h>
#include <QtCore/private/qobject_p.h>
+#include <QtCore/qelapsedtimer.h>
#include <QtGui/QIcon>
QT_BEGIN_NAMESPACE
@@ -136,6 +137,7 @@ public:
void connectToScreen(QScreen *topLevelScreen);
void disconnectFromScreen();
void emitScreenChangedRecursion(QScreen *newScreen);
+ QScreen *screenForGeometry(const QRect &rect);
virtual void clearFocusObject();
virtual QRectF closestAcceptableGeometry(const QRectF &rect) const;
@@ -186,6 +188,7 @@ public:
#endif
bool compositing;
+ QElapsedTimer lastComposeTime;
};
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 850b69d729..d17a1f1d5b 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -40,14 +40,18 @@
#include <qpa/qplatformdrag.h>
#include <qpa/qplatformintegration.h>
#include <qdebug.h>
+#include "qhighdpiscaling_p.h"
+#include <QtCore/qscopedvaluerollback.h>
QT_BEGIN_NAMESPACE
QElapsedTimer QWindowSystemInterfacePrivate::eventTime;
-bool QWindowSystemInterfacePrivate::synchronousWindowsSystemEvents = false;
+bool QWindowSystemInterfacePrivate::synchronousWindowSystemEvents = false;
QWaitCondition QWindowSystemInterfacePrivate::eventsFlushed;
QMutex QWindowSystemInterfacePrivate::flushEventMutex;
+QAtomicInt QWindowSystemInterfacePrivate::eventAccepted;
+QWindowSystemEventHandler *QWindowSystemInterfacePrivate::eventHandler;
//------------------------------------------------------------
//
@@ -93,14 +97,14 @@ void QWindowSystemInterface::handleLeaveEvent(QWindow *tlw)
*/
void QWindowSystemInterface::handleEnterLeaveEvent(QWindow *enter, QWindow *leave, const QPointF &local, const QPointF& global)
{
- bool wasSynchronous = QWindowSystemInterfacePrivate::synchronousWindowsSystemEvents;
+ bool wasSynchronous = QWindowSystemInterfacePrivate::synchronousWindowSystemEvents;
if (wasSynchronous)
- setSynchronousWindowsSystemEvents(false);
+ setSynchronousWindowSystemEvents(false);
handleLeaveEvent(leave);
handleEnterEvent(enter, local, global);
if (wasSynchronous) {
flushWindowSystemEvents();
- setSynchronousWindowsSystemEvents(true);
+ setSynchronousWindowSystemEvents(true);
}
}
@@ -138,7 +142,7 @@ void QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState
*/
void QWindowSystemInterface::handleGeometryChange(QWindow *tlw, const QRect &newRect, const QRect &oldRect)
{
- QWindowSystemInterfacePrivate::GeometryChangeEvent *e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(tlw,newRect, oldRect);
+ QWindowSystemInterfacePrivate::GeometryChangeEvent *e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(tlw, QHighDpi::fromNativePixels(newRect, tlw), QHighDpi::fromNativePixels(oldRect, tlw));
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -167,7 +171,7 @@ void QWindowSystemInterface::handleMouseEvent(QWindow *w, ulong timestamp, const
Qt::KeyboardModifiers mods, Qt::MouseEventSource source)
{
QWindowSystemInterfacePrivate::MouseEvent * e =
- new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, local, global, b, mods, source);
+ new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, QHighDpi::fromNativeLocalPosition(local, w), QHighDpi::fromNativePixels(global, w), b, mods, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -184,167 +188,102 @@ void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *w, ulong timest
QWindowSystemInterfacePrivate::MouseEvent * e =
new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp,
QWindowSystemInterfacePrivate::FrameStrutMouse,
- local, global, b, mods, source);
+ QHighDpi::fromNativeLocalPosition(local, w), QHighDpi::fromNativePixels(global, w), b, mods, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
-bool QWindowSystemInterface::tryHandleShortcutEvent(QWindow *w, int k, Qt::KeyboardModifiers mods,
- const QString & text, bool autorep, ushort count)
-{
- unsigned long timestamp = QWindowSystemInterfacePrivate::eventTime.elapsed();
- return tryHandleShortcutEvent(w, timestamp, k, mods, text, autorep, count);
-}
-
-bool QWindowSystemInterface::tryHandleShortcutEvent(QWindow *w, ulong timestamp, int k, Qt::KeyboardModifiers mods,
- const QString & text, bool autorep, ushort count)
-{
-#ifndef QT_NO_SHORTCUT
- QGuiApplicationPrivate::modifier_buttons = mods;
-
- if (!w)
- w = QGuiApplication::focusWindow();
- if (!w)
- return false;
-
- QObject *focus = w->focusObject();
- if (!focus)
- focus = w;
-
- QKeyEvent qevent(QEvent::ShortcutOverride, k, mods, text, autorep, count);
- qevent.setTimestamp(timestamp);
- return QGuiApplicationPrivate::instance()->shortcutMap.tryShortcutEvent(focus, &qevent);
-#else
- Q_UNUSED(w)
- Q_UNUSED(timestamp)
- Q_UNUSED(k)
- Q_UNUSED(mods)
- Q_UNUSED(text)
- Q_UNUSED(autorep)
- Q_UNUSED(count)
- return false;
-#endif
-}
-
-bool QWindowSystemInterface::tryHandleShortcutOverrideEvent(QWindow *w, QKeyEvent *ev)
-{
-#ifndef QT_NO_SHORTCUT
- Q_ASSERT(ev->type() == QKeyEvent::ShortcutOverride);
- QGuiApplicationPrivate::modifier_buttons = ev->modifiers();
-
- QObject *focus = w->focusObject();
- if (!focus)
- focus = w;
- return QGuiApplicationPrivate::instance()->shortcutMap.tryShortcutEvent(focus, ev);
-#else
- Q_UNUSED(w)
- Q_UNUSED(ev)
- return false;
-#endif
-}
-
-// used by QTestLib to directly send shortcuts to objects
-bool QWindowSystemInterface::tryHandleShortcutEventToObject(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods,
- const QString &text, bool autorep, ushort count)
+bool QWindowSystemInterface::handleShortcutEvent(QWindow *window, ulong timestamp, int keyCode, Qt::KeyboardModifiers modifiers, quint32 nativeScanCode,
+ quint32 nativeVirtualKey, quint32 nativeModifiers, const QString &text, bool autorepeat, ushort count)
{
#ifndef QT_NO_SHORTCUT
- QGuiApplicationPrivate::modifier_buttons = mods;
-
- QKeyEvent qevent(QEvent::ShortcutOverride, k, mods, text, autorep, count);
- qevent.setTimestamp(timestamp);
- return QGuiApplicationPrivate::instance()->shortcutMap.tryShortcutEvent(o, &qevent);
-#else
- Q_UNUSED(w)
- Q_UNUSED(timestamp)
- Q_UNUSED(k)
- Q_UNUSED(mods)
- Q_UNUSED(text)
- Q_UNUSED(autorep)
- Q_UNUSED(count)
- return false;
-#endif
-}
-
-bool QWindowSystemInterface::tryHandleExtendedShortcutEvent(QWindow *w, int k, Qt::KeyboardModifiers mods,
- quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers,
- const QString &text, bool autorep, ushort count)
-{
- unsigned long timestamp = QWindowSystemInterfacePrivate::eventTime.elapsed();
- return tryHandleExtendedShortcutEvent(w, timestamp, k, mods, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count);
-}
-
-bool QWindowSystemInterface::tryHandleExtendedShortcutEvent(QWindow *w, ulong timestamp, int k, Qt::KeyboardModifiers mods,
- quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers,
- const QString &text, bool autorep, ushort count)
-{
-#ifndef QT_NO_SHORTCUT
- QGuiApplicationPrivate::modifier_buttons = mods;
+ if (!window)
+ window = QGuiApplication::focusWindow();
+
+ QShortcutMap &shortcutMap = QGuiApplicationPrivate::instance()->shortcutMap;
+ if (shortcutMap.state() == QKeySequence::NoMatch) {
+ // Check if the shortcut is overridden by some object in the event delivery path (typically the focus object).
+ // If so, we should not look up the shortcut in the shortcut map, but instead deliver the event as a regular
+ // key event, so that the target that accepted the shortcut override event can handle it. Note that we only
+ // do this if the shortcut map hasn't found a partial shortcut match yet. If it has, the shortcut can not be
+ // overridden.
+ QWindowSystemInterfacePrivate::KeyEvent *shortcutOverrideEvent = new QWindowSystemInterfacePrivate::KeyEvent(window, timestamp,
+ QEvent::ShortcutOverride, keyCode, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorepeat, count);
+
+ {
+ // FIXME: Template handleWindowSystemEvent to support both sync and async delivery
+ QScopedValueRollback<bool> syncRollback(QWindowSystemInterfacePrivate::synchronousWindowSystemEvents);
+ QWindowSystemInterfacePrivate::synchronousWindowSystemEvents = true;
+
+ if (QWindowSystemInterfacePrivate::handleWindowSystemEvent(shortcutOverrideEvent))
+ return false;
+ }
+ }
- QObject *focus = w->focusObject();
- if (!focus)
- focus = w;
+ // The shortcut event is dispatched as a QShortcutEvent, not a QKeyEvent, but we use
+ // the QKeyEvent as a container for the various properties that the shortcut map needs
+ // to inspect to determine if a shortcut matched the keys that were pressed.
+ QKeyEvent keyEvent(QEvent::ShortcutOverride, keyCode, modifiers, nativeScanCode,
+ nativeVirtualKey, nativeModifiers, text, autorepeat, count);
- QKeyEvent qevent(QEvent::ShortcutOverride, k, mods, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count);
- qevent.setTimestamp(timestamp);
- return QGuiApplicationPrivate::instance()->shortcutMap.tryShortcutEvent(focus, &qevent);
+ return shortcutMap.tryShortcut(&keyEvent);
#else
- Q_UNUSED(w)
+ Q_UNUSED(window)
Q_UNUSED(timestamp)
- Q_UNUSED(k)
- Q_UNUSED(mods)
+ Q_UNUSED(key)
+ Q_UNUSED(modifiers)
Q_UNUSED(nativeScanCode)
Q_UNUSED(nativeVirtualKey)
Q_UNUSED(nativeModifiers)
Q_UNUSED(text)
- Q_UNUSED(autorep)
+ Q_UNUSED(autorepeat)
Q_UNUSED(count)
return false;
#endif
}
-void QWindowSystemInterface::handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count) {
+bool QWindowSystemInterface::handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count) {
unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
- handleKeyEvent(w, time, t, k, mods, text, autorep, count);
+ return handleKeyEvent(w, time, t, k, mods, text, autorep, count);
}
-void QWindowSystemInterface::handleKeyEvent(QWindow *tlw, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count)
+bool QWindowSystemInterface::handleKeyEvent(QWindow *tlw, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count)
{
- // This is special handling needed for OS X which eventually will call sendEvent(), on other platforms
- // this might not be safe, e.g., on Android. See: QGuiApplicationPrivate::processKeyEvent() for
- // shortcut overriding on other platforms.
-#if defined(Q_OS_OSX)
- if (t == QEvent::KeyPress && QWindowSystemInterface::tryHandleShortcutEvent(tlw, timestamp, k, mods, text))
- return;
-#endif // Q_OS_OSX
+ if (t == QEvent::KeyPress && QWindowSystemInterface::handleShortcutEvent(tlw, timestamp, k, mods, 0, 0, 0, text, autorep, count))
+ return true;
QWindowSystemInterfacePrivate::KeyEvent * e =
new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, t, k, mods, text, autorep, count);
- QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
+ return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
-void QWindowSystemInterface::handleExtendedKeyEvent(QWindow *w, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
+bool QWindowSystemInterface::handleExtendedKeyEvent(QWindow *w, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
quint32 nativeScanCode, quint32 nativeVirtualKey,
quint32 nativeModifiers,
const QString& text, bool autorep,
- ushort count)
+ ushort count, bool tryShortcutOverride)
{
unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
- handleExtendedKeyEvent(w, time, type, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers,
- text, autorep, count);
+ return handleExtendedKeyEvent(w, time, type, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers,
+ text, autorep, count, tryShortcutOverride);
}
-void QWindowSystemInterface::handleExtendedKeyEvent(QWindow *tlw, ulong timestamp, QEvent::Type type, int key,
+bool QWindowSystemInterface::handleExtendedKeyEvent(QWindow *tlw, ulong timestamp, QEvent::Type type, int key,
Qt::KeyboardModifiers modifiers,
quint32 nativeScanCode, quint32 nativeVirtualKey,
quint32 nativeModifiers,
const QString& text, bool autorep,
ushort count, bool tryShortcutOverride)
{
- Q_UNUSED(tryShortcutOverride)
+ if (tryShortcutOverride && type == QEvent::KeyPress && QWindowSystemInterface::handleShortcutEvent(tlw,
+ timestamp, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count)) {
+ return true;
+ }
+
QWindowSystemInterfacePrivate::KeyEvent * e =
new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, type, key, modifiers,
nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count);
- QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
+ return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
void QWindowSystemInterface::handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, int d, Qt::Orientation o, Qt::KeyboardModifiers mods) {
@@ -382,14 +321,14 @@ void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, con
// Simple case: vertical deltas only:
if (angleDelta.y() != 0 && angleDelta.x() == 0) {
- e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
return;
}
// Simple case: horizontal deltas only:
if (angleDelta.y() == 0 && angleDelta.x() != 0) {
- e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.x(), Qt::Horizontal, mods, phase, source);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), pixelDelta, angleDelta, angleDelta.x(), Qt::Horizontal, mods, phase, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
return;
}
@@ -397,12 +336,12 @@ void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, con
// Both horizontal and vertical deltas: Send two wheel events.
// The first event contains the Qt 5 pixel and angle delta as points,
// and in addition the Qt 4 compatibility vertical angle delta.
- e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
// The second event contains null pixel and angle points and the
// Qt 4 compatibility horizontal angle delta.
- e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, QPoint(), QPoint(), angleDelta.x(), Qt::Horizontal, mods, phase, source);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), QPoint(), QPoint(), angleDelta.x(), Qt::Horizontal, mods, phase, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -440,23 +379,60 @@ void QWindowSystemInterfacePrivate::removeWindowSystemEvent(WindowSystemEvent *e
windowSystemEventQueue.remove(event);
}
-void QWindowSystemInterfacePrivate::handleWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *ev)
+void QWindowSystemInterfacePrivate::postWindowSystemEvent(WindowSystemEvent *ev)
{
- if (synchronousWindowsSystemEvents) {
- QGuiApplicationPrivate::processWindowSystemEvent(ev);
+ windowSystemEventQueue.append(ev);
+ QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::qt_qpa_core_dispatcher();
+ if (dispatcher)
+ dispatcher->wakeUp();
+}
+
+/*!
+ Handles a window system event.
+
+ By default this function posts the event on the window system event queue and
+ wakes the Gui event dispatcher. Qt Gui will then handle the event asynchonously
+ at a later point. The return value is not used in asynchronous mode and will
+ always be true.
+
+ In synchronous mode Qt Gui will process the event immediately. The return value
+ indicates if Qt accepted the event.
+
+ \sa flushWindowSystemEvents(), setSynchronousWindowSystemEvents()
+*/
+bool QWindowSystemInterfacePrivate::handleWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *ev)
+{
+ bool accepted = true;
+ if (synchronousWindowSystemEvents) {
+ if (QThread::currentThread() == QGuiApplication::instance()->thread()) {
+ // Process the event immediately on the current thread and return the accepted state.
+ QGuiApplicationPrivate::processWindowSystemEvent(ev);
+ accepted = ev->eventAccepted;
+ delete ev;
+ } else {
+ // Post the event on the Qt main thread queue and flush the queue.
+ // This will wake up the Gui thread which will process the event.
+ // Return the accepted state for the last event on the queue,
+ // which is the event posted by this function.
+ postWindowSystemEvent(ev);
+ accepted = QWindowSystemInterface::flushWindowSystemEvents();
+ }
} else {
- windowSystemEventQueue.append(ev);
- QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::qt_qpa_core_dispatcher();
- if (dispatcher)
- dispatcher->wakeUp();
+ postWindowSystemEvent(ev);
}
+ return accepted;
}
-void QWindowSystemInterface::registerTouchDevice(QTouchDevice *device)
+void QWindowSystemInterface::registerTouchDevice(const QTouchDevice *device)
{
QTouchDevicePrivate::registerDevice(device);
}
+void QWindowSystemInterface::unregisterTouchDevice(const QTouchDevice *device)
+{
+ QTouchDevicePrivate::unregisterDevice(device);
+}
+
void QWindowSystemInterface::handleTouchEvent(QWindow *w, QTouchDevice *device,
const QList<TouchPoint> &points, Qt::KeyboardModifiers mods)
{
@@ -464,12 +440,16 @@ void QWindowSystemInterface::handleTouchEvent(QWindow *w, QTouchDevice *device,
handleTouchEvent(w, time, device, points, mods);
}
-QList<QTouchEvent::TouchPoint> QWindowSystemInterfacePrivate::convertTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points, QEvent::Type *type)
+QList<QTouchEvent::TouchPoint>
+ QWindowSystemInterfacePrivate::fromNativeTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points,
+ const QWindow *window,
+ QEvent::Type *type)
{
QList<QTouchEvent::TouchPoint> touchPoints;
Qt::TouchPointStates states;
QTouchEvent::TouchPoint p;
+ touchPoints.reserve(points.count());
QList<QWindowSystemInterface::TouchPoint>::const_iterator point = points.constBegin();
QList<QWindowSystemInterface::TouchPoint>::const_iterator end = points.constEnd();
while (point != end) {
@@ -479,16 +459,16 @@ QList<QTouchEvent::TouchPoint> QWindowSystemInterfacePrivate::convertTouchPoints
p.setState(point->state);
const QPointF screenPos = point->area.center();
- p.setScreenPos(screenPos);
- p.setScreenRect(point->area);
+ p.setScreenPos(QHighDpi::fromNativePixels(screenPos, window));
+ p.setScreenRect(QHighDpi::fromNativePixels(point->area, window));
// The local pos and rect are not set, they will be calculated
// when the event gets processed by QGuiApplication.
- p.setNormalizedPos(point->normalPosition);
- p.setVelocity(point->velocity);
+ p.setNormalizedPos(QHighDpi::fromNativePixels(point->normalPosition, window));
+ p.setVelocity(QHighDpi::fromNativePixels(point->velocity, window));
p.setFlags(point->flags);
- p.setRawScreenPositions(point->rawPositions);
+ p.setRawScreenPositions(QHighDpi::fromNativePixels(point->rawPositions, window));
touchPoints.append(p);
++point;
@@ -506,6 +486,27 @@ QList<QTouchEvent::TouchPoint> QWindowSystemInterfacePrivate::convertTouchPoints
return touchPoints;
}
+QList<QWindowSystemInterface::TouchPoint>
+ QWindowSystemInterfacePrivate::toNativeTouchPoints(const QList<QTouchEvent::TouchPoint>& pointList,
+ const QWindow *window)
+{
+ QList<QWindowSystemInterface::TouchPoint> newList;
+ newList.reserve(pointList.size());
+ foreach (const QTouchEvent::TouchPoint &pt, pointList) {
+ QWindowSystemInterface::TouchPoint p;
+ p.id = pt.id();
+ p.flags = pt.flags();
+ p.normalPosition = QHighDpi::toNativeLocalPosition(pt.normalizedPos(), window);
+ p.area = QHighDpi::toNativePixels(pt.screenRect(), window);
+ p.pressure = pt.pressure();
+ p.state = pt.state();
+ p.velocity = pt.velocity();
+ p.rawPositions = pt.rawScreenPositions();
+ newList.append(p);
+ }
+ return newList;
+}
+
void QWindowSystemInterface::handleTouchEvent(QWindow *tlw, ulong timestamp, QTouchDevice *device,
const QList<TouchPoint> &points, Qt::KeyboardModifiers mods)
{
@@ -516,7 +517,7 @@ void QWindowSystemInterface::handleTouchEvent(QWindow *tlw, ulong timestamp, QTo
return;
QEvent::Type type;
- QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::convertTouchPoints(points, &type);
+ QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::fromNativeTouchPoints(points, tlw, &type);
QWindowSystemInterfacePrivate::TouchEvent *e =
new QWindowSystemInterfacePrivate::TouchEvent(tlw, timestamp, type, device, touchPoints, mods);
@@ -549,14 +550,14 @@ void QWindowSystemInterface::handleScreenOrientationChange(QScreen *screen, Qt::
void QWindowSystemInterface::handleScreenGeometryChange(QScreen *screen, const QRect &geometry, const QRect &availableGeometry)
{
QWindowSystemInterfacePrivate::ScreenGeometryEvent *e =
- new QWindowSystemInterfacePrivate::ScreenGeometryEvent(screen, geometry, availableGeometry);
+ new QWindowSystemInterfacePrivate::ScreenGeometryEvent(screen, QHighDpi::fromNativeScreenGeometry(geometry, screen), QHighDpi::fromNative(availableGeometry, screen, geometry.topLeft()));
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
void QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(QScreen *screen, qreal dpiX, qreal dpiY)
{
QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *e =
- new QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent(screen, dpiX, dpiY);
+ new QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent(screen, dpiX, dpiY); // ### tja
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -575,7 +576,7 @@ void QWindowSystemInterface::handleThemeChange(QWindow *tlw)
void QWindowSystemInterface::handleExposeEvent(QWindow *tlw, const QRegion &region)
{
- QWindowSystemInterfacePrivate::ExposeEvent *e = new QWindowSystemInterfacePrivate::ExposeEvent(tlw, region);
+ QWindowSystemInterfacePrivate::ExposeEvent *e = new QWindowSystemInterfacePrivate::ExposeEvent(tlw, QHighDpi::fromNativeLocalRegion(region, tlw));
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -584,30 +585,37 @@ void QWindowSystemInterface::deferredFlushWindowSystemEvents(QEventLoop::Process
Q_ASSERT(QThread::currentThread() == QGuiApplication::instance()->thread());
QMutexLocker locker(&QWindowSystemInterfacePrivate::flushEventMutex);
- flushWindowSystemEvents(flags);
+ sendWindowSystemEvents(flags);
QWindowSystemInterfacePrivate::eventsFlushed.wakeOne();
}
-void QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags)
+/*!
+ Make Qt Gui process all events on the event queue immediately. Return the
+ accepted state for the last event on the queue.
+*/
+bool QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags)
{
const int count = QWindowSystemInterfacePrivate::windowSystemEventQueue.count();
if (!count)
- return;
+ return false;
if (!QGuiApplication::instance()) {
qWarning().nospace()
<< "QWindowSystemInterface::flushWindowSystemEvents() invoked after "
"QGuiApplication destruction, discarding " << count << " events.";
QWindowSystemInterfacePrivate::windowSystemEventQueue.clear();
- return;
+ return false;
}
if (QThread::currentThread() != QGuiApplication::instance()->thread()) {
+ // Post a FlushEvents event which will trigger a call back to
+ // deferredFlushWindowSystemEvents from the Gui thread.
QMutexLocker locker(&QWindowSystemInterfacePrivate::flushEventMutex);
QWindowSystemInterfacePrivate::FlushEventsEvent *e = new QWindowSystemInterfacePrivate::FlushEventsEvent(flags);
- QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
+ QWindowSystemInterfacePrivate::postWindowSystemEvent(e);
QWindowSystemInterfacePrivate::eventsFlushed.wait(&QWindowSystemInterfacePrivate::flushEventMutex);
} else {
sendWindowSystemEvents(flags);
}
+ return QWindowSystemInterfacePrivate::eventAccepted.load() > 0;
}
bool QWindowSystemInterface::sendWindowSystemEvents(QEventLoop::ProcessEventsFlags flags)
@@ -621,17 +629,42 @@ bool QWindowSystemInterface::sendWindowSystemEvents(QEventLoop::ProcessEventsFla
QWindowSystemInterfacePrivate::getWindowSystemEvent();
if (!event)
break;
- nevents++;
- QGuiApplicationPrivate::processWindowSystemEvent(event);
+
+ if (QWindowSystemInterfacePrivate::eventHandler) {
+ if (QWindowSystemInterfacePrivate::eventHandler->sendEvent(event))
+ nevents++;
+ } else {
+ nevents++;
+ QGuiApplicationPrivate::processWindowSystemEvent(event);
+ }
+
+ // Record the accepted state for the processed event
+ // (excluding flush events). This state can then be
+ // returned by flushWindowSystemEvents().
+ if (event->type != QWindowSystemInterfacePrivate::FlushEvents)
+ QWindowSystemInterfacePrivate::eventAccepted.store(event->eventAccepted);
+
delete event;
}
return (nevents > 0);
}
-void QWindowSystemInterface::setSynchronousWindowsSystemEvents(bool enable)
+void QWindowSystemInterfacePrivate::installWindowSystemEventHandler(QWindowSystemEventHandler *handler)
+{
+ if (!eventHandler)
+ eventHandler = handler;
+}
+
+void QWindowSystemInterfacePrivate::removeWindowSystemEventhandler(QWindowSystemEventHandler *handler)
+{
+ if (eventHandler == handler)
+ eventHandler = 0;
+}
+
+void QWindowSystemInterface::setSynchronousWindowSystemEvents(bool enable)
{
- QWindowSystemInterfacePrivate::synchronousWindowsSystemEvents = enable;
+ QWindowSystemInterfacePrivate::synchronousWindowSystemEvents = enable;
}
int QWindowSystemInterface::windowSystemEventsQueued()
@@ -642,12 +675,12 @@ int QWindowSystemInterface::windowSystemEventsQueued()
#ifndef QT_NO_DRAGANDDROP
QPlatformDragQtResponse QWindowSystemInterface::handleDrag(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions)
{
- return QGuiApplicationPrivate::processDrag(w, dropData, p,supportedActions);
+ return QGuiApplicationPrivate::processDrag(w, dropData, QHighDpi::fromNativeLocalPosition(p, w) ,supportedActions);
}
QPlatformDropQtResponse QWindowSystemInterface::handleDrop(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions)
{
- return QGuiApplicationPrivate::processDrop(w, dropData, p,supportedActions);
+ return QGuiApplicationPrivate::processDrop(w, dropData, QHighDpi::fromNativeLocalPosition(p, w),supportedActions);
}
#endif // QT_NO_DRAGANDDROP
@@ -681,8 +714,11 @@ void QWindowSystemInterface::handleTabletEvent(QWindow *w, ulong timestamp, cons
Qt::KeyboardModifiers modifiers)
{
QWindowSystemInterfacePrivate::TabletEvent *e =
- new QWindowSystemInterfacePrivate::TabletEvent(w, timestamp, local, global, device, pointerType, buttons, pressure,
- xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
+ new QWindowSystemInterfacePrivate::TabletEvent(w,timestamp,
+ QHighDpi::fromNativeLocalPosition(local, w),
+ QHighDpi::fromNativePixels(global, w),
+ device, pointerType, buttons, pressure,
+ xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -807,18 +843,60 @@ Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QWindowSystemInterface::TouchPo
}
#endif
-Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier) {
- QWindowSystemInterface::handleMouseEvent(w, local, global, b, mods);
+// The following functions are used by testlib, and need to be synchronous to avoid
+// race conditions with plugins delivering native events from secondary threads.
+
+Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *w, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods, int timestamp)
+{
+ bool wasSynchronous = QWindowSystemInterfacePrivate::synchronousWindowSystemEvents;
+ QWindowSystemInterface::setSynchronousWindowSystemEvents(true);
+ QWindowSystemInterface::handleMouseEvent(w, timestamp, local, global, b, mods);
+ QWindowSystemInterface::setSynchronousWindowSystemEvents(wasSynchronous);
}
Q_GUI_EXPORT void qt_handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1)
{
+ bool wasSynchronous = QWindowSystemInterfacePrivate::synchronousWindowSystemEvents;
+ QWindowSystemInterface::setSynchronousWindowSystemEvents(true);
QWindowSystemInterface::handleKeyEvent(w, t, k, mods, text, autorep, count);
+ QWindowSystemInterface::setSynchronousWindowSystemEvents(wasSynchronous);
}
-Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1)
+Q_GUI_EXPORT bool qt_handleShortcutEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1)
{
- return QWindowSystemInterface::tryHandleShortcutEventToObject(o, timestamp, k, mods, text, autorep, count);
+#ifndef QT_NO_SHORTCUT
+
+ // FIXME: This method should not allow targeting a specific object, but should
+ // instead forward the event to a window, which then takes care of normal event
+ // propagation. We need to fix a lot of tests before we can refactor this (the
+ // window needs to be exposed and active and have a focus object), so we leave
+ // it as is for now. See QTBUG-48577.
+
+ QGuiApplicationPrivate::modifier_buttons = mods;
+
+ QKeyEvent qevent(QEvent::ShortcutOverride, k, mods, text, autorep, count);
+ qevent.setTimestamp(timestamp);
+
+ QShortcutMap &shortcutMap = QGuiApplicationPrivate::instance()->shortcutMap;
+ if (shortcutMap.state() == QKeySequence::NoMatch) {
+ // Try sending as QKeyEvent::ShortcutOverride first
+ QCoreApplication::sendEvent(o, &qevent);
+ if (qevent.isAccepted())
+ return false;
+ }
+
+ // Then as QShortcutEvent
+ return shortcutMap.tryShortcut(&qevent);
+#else
+ Q_UNUSED(o)
+ Q_UNUSED(timestamp)
+ Q_UNUSED(k)
+ Q_UNUSED(mods)
+ Q_UNUSED(text)
+ Q_UNUSED(autorep)
+ Q_UNUSED(count)
+ return false;
+#endif
}
static QWindowSystemInterface::TouchPoint touchPoint(const QTouchEvent::TouchPoint& pt)
@@ -839,17 +917,31 @@ static QList<struct QWindowSystemInterface::TouchPoint> touchPointList(const QLi
QList<struct QWindowSystemInterface::TouchPoint> newList;
Q_FOREACH (QTouchEvent::TouchPoint p, pointList)
- {
newList.append(touchPoint(p));
- }
+
return newList;
}
-Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *w, QTouchDevice *device,
+Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *w, QTouchDevice *device,
const QList<QTouchEvent::TouchPoint> &points,
Qt::KeyboardModifiers mods = Qt::NoModifier)
{
+ bool wasSynchronous = QWindowSystemInterfacePrivate::synchronousWindowSystemEvents;
+ QWindowSystemInterface::setSynchronousWindowSystemEvents(true);
QWindowSystemInterface::handleTouchEvent(w, device, touchPointList(points), mods);
+ QWindowSystemInterface::setSynchronousWindowSystemEvents(wasSynchronous);
}
+QWindowSystemEventHandler::~QWindowSystemEventHandler()
+{
+ QWindowSystemInterfacePrivate::removeWindowSystemEventhandler(this);
+}
+
+bool QWindowSystemEventHandler::sendEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e)
+{
+ QGuiApplicationPrivate::processWindowSystemEvent(e);
+ return true;
+}
+
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
index 448c5d0893..a27c68649e 100644
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ b/src/gui/kernel/qwindowsysteminterface.h
@@ -78,32 +78,18 @@ public:
Qt::KeyboardModifiers mods = Qt::NoModifier,
Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
- static bool tryHandleShortcutOverrideEvent(QWindow *w, QKeyEvent *ev);
+ static bool handleShortcutEvent(QWindow *w, ulong timestamp, int k, Qt::KeyboardModifiers mods, quint32 nativeScanCode,
+ quint32 nativeVirtualKey, quint32 nativeModifiers, const QString & text = QString(), bool autorep = false, ushort count = 1);
- static bool tryHandleShortcutEvent(QWindow *w, int k, Qt::KeyboardModifiers mods,
- const QString & text = QString(), bool autorep = false, ushort count = 1);
- static bool tryHandleShortcutEvent(QWindow *w, ulong timestamp, int k, Qt::KeyboardModifiers mods,
- const QString & text = QString(), bool autorep = false, ushort count = 1);
+ static bool handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
+ static bool handleKeyEvent(QWindow *w, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
- static bool tryHandleShortcutEventToObject(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods,
- const QString & text = QString(), bool autorep = false, ushort count = 1);
-
- static bool tryHandleExtendedShortcutEvent(QWindow *w, int k, Qt::KeyboardModifiers mods,
- quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers,
- const QString & text = QString(), bool autorep = false, ushort count = 1);
- static bool tryHandleExtendedShortcutEvent(QWindow *w, ulong timestamp, int k, Qt::KeyboardModifiers mods,
- quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers,
- const QString & text = QString(), bool autorep = false, ushort count = 1);
-
- static void handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
- static void handleKeyEvent(QWindow *w, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
-
- static void handleExtendedKeyEvent(QWindow *w, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
+ static bool handleExtendedKeyEvent(QWindow *w, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
quint32 nativeScanCode, quint32 nativeVirtualKey,
quint32 nativeModifiers,
const QString& text = QString(), bool autorep = false,
- ushort count = 1);
- static void handleExtendedKeyEvent(QWindow *w, ulong timestamp, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
+ ushort count = 1, bool tryShortcutOverride = true);
+ static bool handleExtendedKeyEvent(QWindow *w, ulong timestamp, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
quint32 nativeScanCode, quint32 nativeVirtualKey,
quint32 nativeModifiers,
const QString& text = QString(), bool autorep = false,
@@ -127,7 +113,8 @@ public:
QVector<QPointF> rawPositions; // in screen coordinates
};
- static void registerTouchDevice(QTouchDevice *device);
+ static void registerTouchDevice(const QTouchDevice *device);
+ static void unregisterTouchDevice(const QTouchDevice *device);
static void handleTouchEvent(QWindow *w, QTouchDevice *device,
const QList<struct TouchPoint> &points, Qt::KeyboardModifiers mods = Qt::NoModifier);
static void handleTouchEvent(QWindow *w, ulong timestamp, QTouchDevice *device,
@@ -212,8 +199,8 @@ public:
// For event dispatcher implementations
static bool sendWindowSystemEvents(QEventLoop::ProcessEventsFlags flags);
- static void setSynchronousWindowsSystemEvents(bool enable);
- static void flushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents);
+ static void setSynchronousWindowSystemEvents(bool enable);
+ static bool flushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents);
static void deferredFlushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags);
static int windowSystemEventsQueued();
};
diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h
index 2ec402a1e9..e48d1e965b 100644
--- a/src/gui/kernel/qwindowsysteminterface_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_p.h
@@ -51,9 +51,12 @@
#include <QMutex>
#include <QList>
#include <QWaitCondition>
+#include <QAtomicInt>
QT_BEGIN_NAMESPACE
+class QWindowSystemEventHandler;
+
class Q_GUI_EXPORT QWindowSystemInterfacePrivate {
public:
enum EventType {
@@ -99,7 +102,7 @@ public:
};
explicit WindowSystemEvent(EventType t)
- : type(t), flags(0) { }
+ : type(t), flags(0), eventAccepted(true) { }
virtual ~WindowSystemEvent() { }
bool synthetic() const { return flags & Synthetic; }
@@ -107,6 +110,7 @@ public:
EventType type;
int flags;
+ bool eventAccepted;
};
class CloseEvent : public WindowSystemEvent {
@@ -478,15 +482,33 @@ public:
static WindowSystemEvent *getNonUserInputWindowSystemEvent();
static WindowSystemEvent *peekWindowSystemEvent(EventType t);
static void removeWindowSystemEvent(WindowSystemEvent *event);
- static void handleWindowSystemEvent(WindowSystemEvent *ev);
+ static void postWindowSystemEvent(WindowSystemEvent *ev);
+ static bool handleWindowSystemEvent(WindowSystemEvent *ev);
static QElapsedTimer eventTime;
- static bool synchronousWindowsSystemEvents;
+ static bool synchronousWindowSystemEvents;
static QWaitCondition eventsFlushed;
static QMutex flushEventMutex;
+ static QAtomicInt eventAccepted;
+
+ static QList<QTouchEvent::TouchPoint>
+ fromNativeTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points,
+ const QWindow *window, QEvent::Type *type = Q_NULLPTR);
+ static QList<QWindowSystemInterface::TouchPoint>
+ toNativeTouchPoints(const QList<QTouchEvent::TouchPoint>& pointList,
+ const QWindow *window);
+
+ static void installWindowSystemEventHandler(QWindowSystemEventHandler *handler);
+ static void removeWindowSystemEventhandler(QWindowSystemEventHandler *handler);
+ static QWindowSystemEventHandler *eventHandler;
+};
- static QList<QTouchEvent::TouchPoint> convertTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points, QEvent::Type *type);
+class Q_GUI_EXPORT QWindowSystemEventHandler
+{
+public:
+ virtual ~QWindowSystemEventHandler();
+ virtual bool sendEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *event);
};
QT_END_NAMESPACE
diff --git a/src/gui/math3d/qmatrix4x4.h b/src/gui/math3d/qmatrix4x4.h
index 6f6ff235cf..cd5686be94 100644
--- a/src/gui/math3d/qmatrix4x4.h
+++ b/src/gui/math3d/qmatrix4x4.h
@@ -86,7 +86,7 @@ public:
inline void fill(float value);
double determinant() const;
- QMatrix4x4 inverted(bool *invertible = 0) const;
+ QMatrix4x4 inverted(bool *invertible = Q_NULLPTR) const;
QMatrix4x4 transposed() const;
QMatrix3x3 normalMatrix() const;
diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h
index 5b0006ac56..3716220a60 100644
--- a/src/gui/math3d/qquaternion.h
+++ b/src/gui/math3d/qquaternion.h
@@ -164,12 +164,12 @@ inline QQuaternion::QQuaternion(float aScalar, float xpos, float ypos, float zpo
inline bool QQuaternion::isNull() const
{
- return xp == 0.0f && yp == 0.0f && zp == 0.0f && wp == 0.0f;
+ return wp == 0.0f && xp == 0.0f && yp == 0.0f && zp == 0.0f;
}
inline bool QQuaternion::isIdentity() const
{
- return xp == 0.0f && yp == 0.0f && zp == 0.0f && wp == 1.0f;
+ return wp == 1.0f && xp == 0.0f && yp == 0.0f && zp == 0.0f;
}
inline float QQuaternion::x() const { return xp; }
@@ -184,16 +184,16 @@ inline void QQuaternion::setScalar(float aScalar) { wp = aScalar; }
Q_DECL_CONSTEXPR inline float QQuaternion::dotProduct(const QQuaternion &q1, const QQuaternion &q2)
{
- return q1.xp * q2.xp + q1.yp * q2.yp + q1.zp * q2.zp + q1.wp * q2.wp;
+ return q1.wp * q2.wp + q1.xp * q2.xp + q1.yp * q2.yp + q1.zp * q2.zp;
}
inline QQuaternion QQuaternion::inverted() const
{
// Need some extra precision if the length is very small.
- double len = double(xp) * double(xp) +
+ double len = double(wp) * double(wp) +
+ double(xp) * double(xp) +
double(yp) * double(yp) +
- double(zp) * double(zp) +
- double(wp) * double(wp);
+ double(zp) * double(zp);
if (!qFuzzyIsNull(len))
return QQuaternion(wp / len, -xp / len, -yp / len, -zp / len);
return QQuaternion(0.0f, 0.0f, 0.0f, 0.0f);
@@ -213,28 +213,28 @@ inline QQuaternion QQuaternion::conjugate() const
inline QQuaternion &QQuaternion::operator+=(const QQuaternion &quaternion)
{
+ wp += quaternion.wp;
xp += quaternion.xp;
yp += quaternion.yp;
zp += quaternion.zp;
- wp += quaternion.wp;
return *this;
}
inline QQuaternion &QQuaternion::operator-=(const QQuaternion &quaternion)
{
+ wp -= quaternion.wp;
xp -= quaternion.xp;
yp -= quaternion.yp;
zp -= quaternion.zp;
- wp -= quaternion.wp;
return *this;
}
inline QQuaternion &QQuaternion::operator*=(float factor)
{
+ wp *= factor;
xp *= factor;
yp *= factor;
zp *= factor;
- wp *= factor;
return *this;
}
@@ -262,16 +262,16 @@ inline QQuaternion &QQuaternion::operator*=(const QQuaternion &quaternion)
inline QQuaternion &QQuaternion::operator/=(float divisor)
{
+ wp /= divisor;
xp /= divisor;
yp /= divisor;
zp /= divisor;
- wp /= divisor;
return *this;
}
inline bool operator==(const QQuaternion &q1, const QQuaternion &q2)
{
- return q1.xp == q2.xp && q1.yp == q2.yp && q1.zp == q2.zp && q1.wp == q2.wp;
+ return q1.wp == q2.wp && q1.xp == q2.xp && q1.yp == q2.yp && q1.zp == q2.zp;
}
inline bool operator!=(const QQuaternion &q1, const QQuaternion &q2)
@@ -311,10 +311,10 @@ inline const QQuaternion operator/(const QQuaternion &quaternion, float divisor)
inline bool qFuzzyCompare(const QQuaternion& q1, const QQuaternion& q2)
{
- return qFuzzyCompare(q1.xp, q2.xp) &&
+ return qFuzzyCompare(q1.wp, q2.wp) &&
+ qFuzzyCompare(q1.xp, q2.xp) &&
qFuzzyCompare(q1.yp, q2.yp) &&
- qFuzzyCompare(q1.zp, q2.zp) &&
- qFuzzyCompare(q1.wp, q2.wp);
+ qFuzzyCompare(q1.zp, q2.zp);
}
#ifndef QT_NO_VECTOR3D
diff --git a/src/gui/math3d/qvector2d.h b/src/gui/math3d/qvector2d.h
index 137142f381..c4e62710d9 100644
--- a/src/gui/math3d/qvector2d.h
+++ b/src/gui/math3d/qvector2d.h
@@ -122,7 +122,7 @@ private:
friend class QVector4D;
};
-Q_DECLARE_TYPEINFO(QVector2D, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(QVector2D, Q_PRIMITIVE_TYPE);
Q_DECL_CONSTEXPR inline QVector2D::QVector2D() : xp(0.0f), yp(0.0f) {}
diff --git a/src/gui/math3d/qvector3d.h b/src/gui/math3d/qvector3d.h
index 5be637e0c5..b62d33da71 100644
--- a/src/gui/math3d/qvector3d.h
+++ b/src/gui/math3d/qvector3d.h
@@ -141,7 +141,7 @@ private:
#endif
};
-Q_DECLARE_TYPEINFO(QVector3D, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(QVector3D, Q_PRIMITIVE_TYPE);
Q_DECL_CONSTEXPR inline QVector3D::QVector3D() : xp(0.0f), yp(0.0f), zp(0.0f) {}
diff --git a/src/gui/math3d/qvector4d.h b/src/gui/math3d/qvector4d.h
index 72db8ac754..0543f0fbe3 100644
--- a/src/gui/math3d/qvector4d.h
+++ b/src/gui/math3d/qvector4d.h
@@ -131,7 +131,7 @@ private:
#endif
};
-Q_DECLARE_TYPEINFO(QVector4D, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(QVector4D, Q_PRIMITIVE_TYPE);
Q_DECL_CONSTEXPR inline QVector4D::QVector4D() : xp(0.0f), yp(0.0f), zp(0.0f), wp(0.0f) {}
diff --git a/src/gui/opengl/opengl.pri b/src/gui/opengl/opengl.pri
index 8659bd6dea..b13f258fda 100644
--- a/src/gui/opengl/opengl.pri
+++ b/src/gui/opengl/opengl.pri
@@ -36,7 +36,8 @@ contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) {
opengl/qopengltexture.h \
opengl/qopengltexture_p.h \
opengl/qopengltexturehelper_p.h \
- opengl/qopenglpixeltransferoptions.h
+ opengl/qopenglpixeltransferoptions.h \
+ opengl/qopenglextrafunctions.h
SOURCES += opengl/qopengl.cpp \
opengl/qopenglfunctions.cpp \
diff --git a/src/gui/opengl/qopengl.cpp b/src/gui/opengl/qopengl.cpp
index 1c008ccb42..a77d6743ad 100644
--- a/src/gui/opengl/qopengl.cpp
+++ b/src/gui/opengl/qopengl.cpp
@@ -135,20 +135,42 @@ static const char operators[][3] = {"!=", "<", "<=", "=", ">", ">="};
static inline QString valueKey() { return QStringLiteral("value"); }
static inline QString opKey() { return QStringLiteral("op"); }
static inline QString versionKey() { return QStringLiteral("version"); }
+static inline QString releaseKey() { return QStringLiteral("release"); }
static inline QString typeKey() { return QStringLiteral("type"); }
static inline QString osKey() { return QStringLiteral("os"); }
static inline QString vendorIdKey() { return QStringLiteral("vendor_id"); }
static inline QString glVendorKey() { return QStringLiteral("gl_vendor"); }
static inline QString deviceIdKey() { return QStringLiteral("device_id"); }
static inline QString driverVersionKey() { return QStringLiteral("driver_version"); }
+static inline QString driverDescriptionKey() { return QStringLiteral("driver_description"); }
static inline QString featuresKey() { return QStringLiteral("features"); }
static inline QString idKey() { return QStringLiteral("id"); }
static inline QString descriptionKey() { return QStringLiteral("description"); }
static inline QString exceptionsKey() { return QStringLiteral("exceptions"); }
+typedef QJsonArray::ConstIterator JsonArrayConstIt;
+
+static inline bool contains(const QJsonArray &haystack, unsigned needle)
+{
+ for (JsonArrayConstIt it = haystack.constBegin(), cend = haystack.constEnd(); it != cend; ++it) {
+ if (needle == it->toString().toUInt(Q_NULLPTR, /* base */ 0))
+ return true;
+ }
+ return false;
+}
+
+static inline bool contains(const QJsonArray &haystack, const QString &needle)
+{
+ for (JsonArrayConstIt it = haystack.constBegin(), cend = haystack.constEnd(); it != cend; ++it) {
+ if (needle == it->toString())
+ return true;
+ }
+ return false;
+}
+
namespace {
// VersionTerm describing a version term consisting of number and operator
-// found in "os", "driver_version", "gl_version".
+// found in os.version and driver_version.
struct VersionTerm {
VersionTerm() : op(NotEqual) {}
static VersionTerm fromJson(const QJsonValue &v);
@@ -162,7 +184,7 @@ struct VersionTerm {
bool VersionTerm::matches(const QVersionNumber &other) const
{
if (isNull() || other.isNull()) {
- qWarning() << Q_FUNC_INFO << "called with invalid parameters";
+ qWarning("called with invalid parameters");
return false;
}
switch (op) {
@@ -206,21 +228,56 @@ struct OsTypeTerm
static OsTypeTerm fromJson(const QJsonValue &v);
static QString hostOs();
static QVersionNumber hostKernelVersion() { return QVersionNumber::fromString(QSysInfo::kernelVersion()); }
+ static QString hostOsRelease() {
+ QString ver;
+#ifdef Q_OS_WIN
+ switch (QSysInfo::windowsVersion()) {
+ case QSysInfo::WV_XP:
+ case QSysInfo::WV_2003:
+ ver = QStringLiteral("xp");
+ break;
+ case QSysInfo::WV_VISTA:
+ ver = QStringLiteral("vista");
+ break;
+ case QSysInfo::WV_WINDOWS7:
+ ver = QStringLiteral("7");
+ break;
+ case QSysInfo::WV_WINDOWS8:
+ ver = QStringLiteral("8");
+ break;
+ case QSysInfo::WV_WINDOWS8_1:
+ ver = QStringLiteral("8.1");
+ break;
+ case QSysInfo::WV_WINDOWS10:
+ ver = QStringLiteral("10");
+ break;
+ default:
+ break;
+ }
+#endif
+ return ver;
+ }
bool isNull() const { return type.isEmpty(); }
- bool matches(const QString &osName, const QVersionNumber &kernelVersion) const
+ bool matches(const QString &osName, const QVersionNumber &kernelVersion, const QString &osRelease) const
{
if (isNull() || osName.isEmpty() || kernelVersion.isNull()) {
- qWarning() << Q_FUNC_INFO << "called with invalid parameters";
+ qWarning("called with invalid parameters");
return false;
}
if (type != osName)
return false;
- return versionTerm.isNull() || versionTerm.matches(kernelVersion);
+ if (!versionTerm.isNull() && !versionTerm.matches(kernelVersion))
+ return false;
+ // release is a list of Windows versions where the rule should match
+ if (!release.isEmpty() && !contains(release, osRelease))
+ return false;
+ return true;
}
QString type;
VersionTerm versionTerm;
+ QJsonArray release;
};
OsTypeTerm OsTypeTerm::fromJson(const QJsonValue &v)
@@ -231,6 +288,7 @@ OsTypeTerm OsTypeTerm::fromJson(const QJsonValue &v)
const QJsonObject o = v.toObject();
result.type = o.value(typeKey()).toString();
result.versionTerm = VersionTerm::fromJson(o.value(versionKey()));
+ result.release = o.value(releaseKey()).toArray();
return result;
}
@@ -251,17 +309,6 @@ QString OsTypeTerm::hostOs()
}
} // anonymous namespace
-typedef QJsonArray::ConstIterator JsonArrayConstIt;
-
-static inline bool contains(const QJsonArray &a, unsigned needle)
-{
- for (JsonArrayConstIt it = a.constBegin(), cend = a.constEnd(); it != cend; ++it) {
- if (needle == it->toString().toUInt(Q_NULLPTR, /* base */ 0))
- return true;
- }
- return false;
-}
-
static QString msgSyntaxWarning(const QJsonObject &object, const QString &what)
{
QString result;
@@ -277,17 +324,18 @@ static QString msgSyntaxWarning(const QJsonObject &object, const QString &what)
static bool matches(const QJsonObject &object,
const QString &osName,
const QVersionNumber &kernelVersion,
+ const QString &osRelease,
const QOpenGLConfig::Gpu &gpu)
{
const OsTypeTerm os = OsTypeTerm::fromJson(object.value(osKey()));
- if (!os.isNull() && !os.matches(osName, kernelVersion))
+ if (!os.isNull() && !os.matches(osName, kernelVersion, osRelease))
return false;
const QJsonValue exceptionsV = object.value(exceptionsKey());
if (exceptionsV.isArray()) {
const QJsonArray exceptionsA = exceptionsV.toArray();
for (JsonArrayConstIt it = exceptionsA.constBegin(), cend = exceptionsA.constEnd(); it != cend; ++it) {
- if (matches(it->toObject(), osName, kernelVersion, gpu))
+ if (matches(it->toObject(), osName, kernelVersion, osRelease, gpu))
return false;
}
}
@@ -336,12 +384,22 @@ static bool matches(const QJsonObject &object,
QLatin1String("Driver version must be of type object."));
}
}
+
+ if (!gpu.driverDescription.isEmpty()) {
+ const QJsonValue driverDescriptionV = object.value(driverDescriptionKey());
+ if (driverDescriptionV.isString()) {
+ if (!gpu.driverDescription.contains(driverDescriptionV.toString().toUtf8()))
+ return false;
+ }
+ }
+
return true;
}
static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu,
const QString &osName,
const QVersionNumber &kernelVersion,
+ const QString &osRelease,
const QJsonDocument &doc,
QSet<QString> *result,
QString *errorMessage)
@@ -358,7 +416,7 @@ static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu,
for (JsonArrayConstIt eit = entriesA.constBegin(), ecend = entriesA.constEnd(); eit != ecend; ++eit) {
if (eit->isObject()) {
const QJsonObject object = eit->toObject();
- if (matches(object, osName, kernelVersion, gpu)) {
+ if (matches(object, osName, kernelVersion, osRelease, gpu)) {
const QJsonValue featuresListV = object.value(featuresKey());
if (featuresListV.isArray()) {
const QJsonArray featuresListA = featuresListV.toArray();
@@ -374,6 +432,7 @@ static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu,
static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu,
const QString &osName,
const QVersionNumber &kernelVersion,
+ const QString &osRelease,
const QByteArray &jsonAsciiData,
QSet<QString> *result, QString *errorMessage)
{
@@ -389,12 +448,13 @@ static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu,
<< error.offset << ").";
return false;
}
- return readGpuFeatures(gpu, osName, kernelVersion, document, result, errorMessage);
+ return readGpuFeatures(gpu, osName, kernelVersion, osRelease, document, result, errorMessage);
}
static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu,
const QString &osName,
const QVersionNumber &kernelVersion,
+ const QString &osRelease,
const QString &fileName,
QSet<QString> *result, QString *errorMessage)
{
@@ -407,7 +467,7 @@ static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu,
<< file.errorString();
return false;
}
- const bool success = readGpuFeatures(gpu, osName, kernelVersion, file.readAll(), result, errorMessage);
+ const bool success = readGpuFeatures(gpu, osName, kernelVersion, osRelease, file.readAll(), result, errorMessage);
if (!success) {
errorMessage->prepend(QLatin1String("Error reading \"")
+ QDir::toNativeSeparators(fileName)
@@ -417,37 +477,39 @@ static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu,
}
QSet<QString> QOpenGLConfig::gpuFeatures(const QOpenGLConfig::Gpu &gpu,
- const QString &osName,
- const QVersionNumber &kernelVersion,
- const QJsonDocument &doc)
+ const QString &osName,
+ const QVersionNumber &kernelVersion,
+ const QString &osRelease,
+ const QJsonDocument &doc)
{
QSet<QString> result;
QString errorMessage;
- if (!readGpuFeatures(gpu, osName, kernelVersion, doc, &result, &errorMessage))
+ if (!readGpuFeatures(gpu, osName, kernelVersion, osRelease, doc, &result, &errorMessage))
qWarning().noquote() << errorMessage;
return result;
}
QSet<QString> QOpenGLConfig::gpuFeatures(const QOpenGLConfig::Gpu &gpu,
- const QString &osName,
- const QVersionNumber &kernelVersion,
- const QString &fileName)
+ const QString &osName,
+ const QVersionNumber &kernelVersion,
+ const QString &osRelease,
+ const QString &fileName)
{
QSet<QString> result;
QString errorMessage;
- if (!readGpuFeatures(gpu, osName, kernelVersion, fileName, &result, &errorMessage))
+ if (!readGpuFeatures(gpu, osName, kernelVersion, osRelease, fileName, &result, &errorMessage))
qWarning().noquote() << errorMessage;
return result;
}
QSet<QString> QOpenGLConfig::gpuFeatures(const Gpu &gpu, const QJsonDocument &doc)
{
- return gpuFeatures(gpu, OsTypeTerm::hostOs(), OsTypeTerm::hostKernelVersion(), doc);
+ return gpuFeatures(gpu, OsTypeTerm::hostOs(), OsTypeTerm::hostKernelVersion(), OsTypeTerm::hostOsRelease(), doc);
}
QSet<QString> QOpenGLConfig::gpuFeatures(const Gpu &gpu, const QString &fileName)
{
- return gpuFeatures(gpu, OsTypeTerm::hostOs(), OsTypeTerm::hostKernelVersion(), fileName);
+ return gpuFeatures(gpu, OsTypeTerm::hostOs(), OsTypeTerm::hostKernelVersion(), OsTypeTerm::hostOsRelease(), fileName);
}
QOpenGLConfig::Gpu QOpenGLConfig::Gpu::fromContext()
diff --git a/src/gui/opengl/qopengl.h b/src/gui/opengl/qopengl.h
index 72abce760d..87dc2a830e 100644
--- a/src/gui/opengl/qopengl.h
+++ b/src/gui/opengl/qopengl.h
@@ -83,13 +83,11 @@ typedef void* GLeglImageOES;
// include headers on top of each other, meaning that applications can
// include gl2.h even if gl31.h gets included here.
-// This compile time differentation is important inside Qt because,
-// unlike desktop GL, GLES is different when it comes to versioning
-// and extensions: Standard functions that are new in a given version
-// are always available in a version-specific header and are not
-// guaranteed to be dynamically resolvable via eglGetProcAddress (and
-// are typically not available as extensions even if they were part of
-// an extension for a previous version).
+// NB! This file contains the only usages of the ES_3 and ES_3_1
+// macros. They are useless for pretty much anything else. The fact
+// that Qt was built against an SDK with f.ex. ES 2 only does not mean
+// applications cannot target ES 3. Therefore QOpenGLFunctions and
+// friends do everything dynamically and never rely on these macros.
# if defined(QT_OPENGL_ES_3_1)
# include <GLES3/gl31.h>
diff --git a/src/gui/opengl/qopengl_p.h b/src/gui/opengl/qopengl_p.h
index 980e02aea6..6b66a3ba57 100644
--- a/src/gui/opengl/qopengl_p.h
+++ b/src/gui/opengl/qopengl_p.h
@@ -49,7 +49,7 @@
#include <private/qopenglcontext_p.h>
#include <QtCore/qset.h>
#include <QtCore/qstring.h>
-#include <private/qversionnumber_p.h>
+#include <QtCore/qversionnumber.h>
QT_BEGIN_NAMESPACE
@@ -79,19 +79,21 @@ public:
bool isValid() const { return deviceId || !glVendor.isEmpty(); }
bool equals(const Gpu &other) const {
return vendorId == other.vendorId && deviceId == other.deviceId && driverVersion == other.driverVersion
- && glVendor == other.glVendor;
+ && driverDescription == other.driverDescription && glVendor == other.glVendor;
}
uint vendorId;
uint deviceId;
QVersionNumber driverVersion;
+ QByteArray driverDescription;
QByteArray glVendor;
- static Gpu fromDevice(uint vendorId, uint deviceId, QVersionNumber driverVersion) {
+ static Gpu fromDevice(uint vendorId, uint deviceId, QVersionNumber driverVersion, const QByteArray &driverDescription) {
Gpu gpu;
gpu.vendorId = vendorId;
gpu.deviceId = deviceId;
gpu.driverVersion = driverVersion;
+ gpu.driverDescription = driverDescription;
return gpu;
}
@@ -105,10 +107,10 @@ public:
};
static QSet<QString> gpuFeatures(const Gpu &gpu,
- const QString &osName, const QVersionNumber &kernelVersion,
+ const QString &osName, const QVersionNumber &kernelVersion, const QString &osVersion,
const QJsonDocument &doc);
static QSet<QString> gpuFeatures(const Gpu &gpu,
- const QString &osName, const QVersionNumber &kernelVersion,
+ const QString &osName, const QVersionNumber &kernelVersion, const QString &osVersion,
const QString &fileName);
static QSet<QString> gpuFeatures(const Gpu &gpu, const QJsonDocument &doc);
static QSet<QString> gpuFeatures(const Gpu &gpu, const QString &fileName);
diff --git a/src/gui/opengl/qopenglbuffer.h b/src/gui/opengl/qopenglbuffer.h
index 847c1efaa0..ca3d85d8e0 100644
--- a/src/gui/opengl/qopenglbuffer.h
+++ b/src/gui/opengl/qopenglbuffer.h
@@ -118,7 +118,7 @@ public:
void write(int offset, const void *data, int count);
void allocate(const void *data, int count);
- inline void allocate(int count) { allocate(0, count); }
+ inline void allocate(int count) { allocate(Q_NULLPTR, count); }
void *map(QOpenGLBuffer::Access access);
void *mapRange(int offset, int count, QOpenGLBuffer::RangeAccessFlags access);
diff --git a/src/gui/opengl/qopengldebug.h b/src/gui/opengl/qopengldebug.h
index 425ab78d7a..3e93ad4120 100644
--- a/src/gui/opengl/qopengldebug.h
+++ b/src/gui/opengl/qopengldebug.h
@@ -97,14 +97,14 @@ public:
QOpenGLDebugMessage();
QOpenGLDebugMessage(const QOpenGLDebugMessage &debugMessage);
- ~QOpenGLDebugMessage();
QOpenGLDebugMessage &operator=(const QOpenGLDebugMessage &debugMessage);
#ifdef Q_COMPILER_RVALUE_REFS
- inline QOpenGLDebugMessage &operator=(QOpenGLDebugMessage &&debugMessage)
- { d.swap(debugMessage.d); return *this; }
+ QOpenGLDebugMessage &operator=(QOpenGLDebugMessage &&other) Q_DECL_NOTHROW { swap(other); return *this; }
#endif
- inline void swap(QOpenGLDebugMessage &debugMessage) { d.swap(debugMessage.d); }
+ ~QOpenGLDebugMessage();
+
+ void swap(QOpenGLDebugMessage &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
Source source() const;
Type type() const;
@@ -156,7 +156,7 @@ public:
};
Q_ENUM(LoggingMode)
- explicit QOpenGLDebugLogger(QObject *parent = 0);
+ explicit QOpenGLDebugLogger(QObject *parent = Q_NULLPTR);
~QOpenGLDebugLogger();
bool initialize();
diff --git a/src/gui/opengl/qopenglengineshadermanager.cpp b/src/gui/opengl/qopenglengineshadermanager.cpp
index 7e53c01cba..40f4ce94c2 100644
--- a/src/gui/opengl/qopenglengineshadermanager.cpp
+++ b/src/gui/opengl/qopenglengineshadermanager.cpp
@@ -427,11 +427,10 @@ QOpenGLEngineShaderProg *QOpenGLEngineSharedShaders::findProgramInCache(const QO
if (!inCache)
shaderCache.store(newProg->program, QOpenGLContext::currentContext());
} else {
- QLatin1String none("none");
- QLatin1String br("\n");
QString error;
error = QLatin1String("Shader program failed to link,");
#if defined(QT_DEBUG)
+ QLatin1String br("\n");
error += QLatin1String("\n Shaders Used:\n");
for (int i = 0; i < newProg->program->shaders().count(); ++i) {
QOpenGLShader *shader = newProg->program->shaders().at(i);
diff --git a/src/gui/opengl/qopenglextensions_p.h b/src/gui/opengl/qopenglextensions_p.h
index 7def687f49..aa2a08242d 100644
--- a/src/gui/opengl/qopenglextensions_p.h
+++ b/src/gui/opengl/qopenglextensions_p.h
@@ -45,7 +45,7 @@
// We mean it.
//
-#include "qopenglfunctions.h"
+#include "qopenglextrafunctions.h"
#include <QtCore/qlibrary.h>
QT_BEGIN_NAMESPACE
@@ -57,32 +57,194 @@ class QOpenGLES3Helper
public:
QOpenGLES3Helper();
- GLvoid* (QOPENGLF_APIENTRYP MapBufferRange)(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr length, GLbitfield access);
+ // GLES3
+ void (QOPENGLF_APIENTRYP ReadBuffer)(GLenum mode);
+ void (QOPENGLF_APIENTRYP DrawRangeElements)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices);
+ void (QOPENGLF_APIENTRYP TexImage3D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels);
+ void (QOPENGLF_APIENTRYP TexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);
+ void (QOPENGLF_APIENTRYP CopyTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+ void (QOPENGLF_APIENTRYP CompressedTexImage3D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);
+ void (QOPENGLF_APIENTRYP CompressedTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);
+ void (QOPENGLF_APIENTRYP GenQueries)(GLsizei n, GLuint *ids);
+ void (QOPENGLF_APIENTRYP DeleteQueries)(GLsizei n, const GLuint *ids);
+ GLboolean (QOPENGLF_APIENTRYP IsQuery)(GLuint id);
+ void (QOPENGLF_APIENTRYP BeginQuery)(GLenum target, GLuint id);
+ void (QOPENGLF_APIENTRYP EndQuery)(GLenum target);
+ void (QOPENGLF_APIENTRYP GetQueryiv)(GLenum target, GLenum pname, GLint *params);
+ void (QOPENGLF_APIENTRYP GetQueryObjectuiv)(GLuint id, GLenum pname, GLuint *params);
GLboolean (QOPENGLF_APIENTRYP UnmapBuffer)(GLenum target);
+ void (QOPENGLF_APIENTRYP GetBufferPointerv)(GLenum target, GLenum pname, void **params);
+ void (QOPENGLF_APIENTRYP DrawBuffers)(GLsizei n, const GLenum *bufs);
+ void (QOPENGLF_APIENTRYP UniformMatrix2x3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP UniformMatrix3x2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP UniformMatrix2x4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP UniformMatrix4x2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP UniformMatrix3x4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP UniformMatrix4x3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
void (QOPENGLF_APIENTRYP BlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
- void (QOPENGLF_APIENTRYP RenderbufferStorageMultisample)(GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height);
-
- void (QOPENGLF_APIENTRYP GenVertexArrays)(GLsizei n, GLuint *arrays);
- void (QOPENGLF_APIENTRYP DeleteVertexArrays)(GLsizei n, const GLuint *arrays);
+ void (QOPENGLF_APIENTRYP RenderbufferStorageMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+ void (QOPENGLF_APIENTRYP FramebufferTextureLayer)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+ void *(QOPENGLF_APIENTRYP MapBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+ void (QOPENGLF_APIENTRYP FlushMappedBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length);
void (QOPENGLF_APIENTRYP BindVertexArray)(GLuint array);
+ void (QOPENGLF_APIENTRYP DeleteVertexArrays)(GLsizei n, const GLuint *arrays);
+ void (QOPENGLF_APIENTRYP GenVertexArrays)(GLsizei n, GLuint *arrays);
GLboolean (QOPENGLF_APIENTRYP IsVertexArray)(GLuint array);
-
- void (QOPENGLF_APIENTRYP TexImage3D)(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
- void (QOPENGLF_APIENTRYP TexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
- void (QOPENGLF_APIENTRYP CompressedTexImage3D)(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
- void (QOPENGLF_APIENTRYP CompressedTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
-
- void (QOPENGLF_APIENTRYP TexStorage3D)(GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth);
- void (QOPENGLF_APIENTRYP TexStorage2D)(GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height);
+ void (QOPENGLF_APIENTRYP GetIntegeri_v)(GLenum target, GLuint index, GLint *data);
+ void (QOPENGLF_APIENTRYP BeginTransformFeedback)(GLenum primitiveMode);
+ void (QOPENGLF_APIENTRYP EndTransformFeedback)(void);
+ void (QOPENGLF_APIENTRYP BindBufferRange)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+ void (QOPENGLF_APIENTRYP BindBufferBase)(GLenum target, GLuint index, GLuint buffer);
+ void (QOPENGLF_APIENTRYP TransformFeedbackVaryings)(GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode);
+ void (QOPENGLF_APIENTRYP GetTransformFeedbackVarying)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+ void (QOPENGLF_APIENTRYP VertexAttribIPointer)(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);
+ void (QOPENGLF_APIENTRYP GetVertexAttribIiv)(GLuint index, GLenum pname, GLint *params);
+ void (QOPENGLF_APIENTRYP GetVertexAttribIuiv)(GLuint index, GLenum pname, GLuint *params);
+ void (QOPENGLF_APIENTRYP VertexAttribI4i)(GLuint index, GLint x, GLint y, GLint z, GLint w);
+ void (QOPENGLF_APIENTRYP VertexAttribI4ui)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+ void (QOPENGLF_APIENTRYP VertexAttribI4iv)(GLuint index, const GLint *v);
+ void (QOPENGLF_APIENTRYP VertexAttribI4uiv)(GLuint index, const GLuint *v);
+ void (QOPENGLF_APIENTRYP GetUniformuiv)(GLuint program, GLint location, GLuint *params);
+ GLint (QOPENGLF_APIENTRYP GetFragDataLocation)(GLuint program, const GLchar *name);
+ void (QOPENGLF_APIENTRYP Uniform1ui)(GLint location, GLuint v0);
+ void (QOPENGLF_APIENTRYP Uniform2ui)(GLint location, GLuint v0, GLuint v1);
+ void (QOPENGLF_APIENTRYP Uniform3ui)(GLint location, GLuint v0, GLuint v1, GLuint v2);
+ void (QOPENGLF_APIENTRYP Uniform4ui)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+ void (QOPENGLF_APIENTRYP Uniform1uiv)(GLint location, GLsizei count, const GLuint *value);
+ void (QOPENGLF_APIENTRYP Uniform2uiv)(GLint location, GLsizei count, const GLuint *value);
+ void (QOPENGLF_APIENTRYP Uniform3uiv)(GLint location, GLsizei count, const GLuint *value);
+ void (QOPENGLF_APIENTRYP Uniform4uiv)(GLint location, GLsizei count, const GLuint *value);
+ void (QOPENGLF_APIENTRYP ClearBufferiv)(GLenum buffer, GLint drawbuffer, const GLint *value);
+ void (QOPENGLF_APIENTRYP ClearBufferuiv)(GLenum buffer, GLint drawbuffer, const GLuint *value);
+ void (QOPENGLF_APIENTRYP ClearBufferfv)(GLenum buffer, GLint drawbuffer, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ClearBufferfi)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+ const GLubyte *(QOPENGLF_APIENTRYP GetStringi)(GLenum name, GLuint index);
+ void (QOPENGLF_APIENTRYP CopyBufferSubData)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+ void (QOPENGLF_APIENTRYP GetUniformIndices)(GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices);
+ void (QOPENGLF_APIENTRYP GetActiveUniformsiv)(GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params);
+ GLuint (QOPENGLF_APIENTRYP GetUniformBlockIndex)(GLuint program, const GLchar *uniformBlockName);
+ void (QOPENGLF_APIENTRYP GetActiveUniformBlockiv)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params);
+ void (QOPENGLF_APIENTRYP GetActiveUniformBlockName)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName);
+ void (QOPENGLF_APIENTRYP UniformBlockBinding)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+ void (QOPENGLF_APIENTRYP DrawArraysInstanced)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
+ void (QOPENGLF_APIENTRYP DrawElementsInstanced)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount);
+ GLsync (QOPENGLF_APIENTRYP FenceSync)(GLenum condition, GLbitfield flags);
+ GLboolean (QOPENGLF_APIENTRYP IsSync)(GLsync sync);
+ void (QOPENGLF_APIENTRYP DeleteSync)(GLsync sync);
+ GLenum (QOPENGLF_APIENTRYP ClientWaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout);
+ void (QOPENGLF_APIENTRYP WaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout);
+ void (QOPENGLF_APIENTRYP GetInteger64v)(GLenum pname, GLint64 *data);
+ void (QOPENGLF_APIENTRYP GetSynciv)(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+ void (QOPENGLF_APIENTRYP GetInteger64i_v)(GLenum target, GLuint index, GLint64 *data);
+ void (QOPENGLF_APIENTRYP GetBufferParameteri64v)(GLenum target, GLenum pname, GLint64 *params);
+ void (QOPENGLF_APIENTRYP GenSamplers)(GLsizei count, GLuint *samplers);
+ void (QOPENGLF_APIENTRYP DeleteSamplers)(GLsizei count, const GLuint *samplers);
+ GLboolean (QOPENGLF_APIENTRYP IsSampler)(GLuint sampler);
+ void (QOPENGLF_APIENTRYP BindSampler)(GLuint unit, GLuint sampler);
+ void (QOPENGLF_APIENTRYP SamplerParameteri)(GLuint sampler, GLenum pname, GLint param);
+ void (QOPENGLF_APIENTRYP SamplerParameteriv)(GLuint sampler, GLenum pname, const GLint *param);
+ void (QOPENGLF_APIENTRYP SamplerParameterf)(GLuint sampler, GLenum pname, GLfloat param);
+ void (QOPENGLF_APIENTRYP SamplerParameterfv)(GLuint sampler, GLenum pname, const GLfloat *param);
+ void (QOPENGLF_APIENTRYP GetSamplerParameteriv)(GLuint sampler, GLenum pname, GLint *params);
+ void (QOPENGLF_APIENTRYP GetSamplerParameterfv)(GLuint sampler, GLenum pname, GLfloat *params);
+ void (QOPENGLF_APIENTRYP VertexAttribDivisor)(GLuint index, GLuint divisor);
+ void (QOPENGLF_APIENTRYP BindTransformFeedback)(GLenum target, GLuint id);
+ void (QOPENGLF_APIENTRYP DeleteTransformFeedbacks)(GLsizei n, const GLuint *ids);
+ void (QOPENGLF_APIENTRYP GenTransformFeedbacks)(GLsizei n, GLuint *ids);
+ GLboolean (QOPENGLF_APIENTRYP IsTransformFeedback)(GLuint id);
+ void (QOPENGLF_APIENTRYP PauseTransformFeedback)(void);
+ void (QOPENGLF_APIENTRYP ResumeTransformFeedback)(void);
+ void (QOPENGLF_APIENTRYP GetProgramBinary)(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary);
+ void (QOPENGLF_APIENTRYP ProgramBinary)(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length);
+ void (QOPENGLF_APIENTRYP ProgramParameteri)(GLuint program, GLenum pname, GLint value);
+ void (QOPENGLF_APIENTRYP InvalidateFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum *attachments);
+ void (QOPENGLF_APIENTRYP InvalidateSubFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+ void (QOPENGLF_APIENTRYP TexStorage2D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+ void (QOPENGLF_APIENTRYP TexStorage3D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+ void (QOPENGLF_APIENTRYP GetInternalformativ)(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params);
+
+ // GLES 3.1
+ void (QOPENGLF_APIENTRYP DispatchCompute)(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);
+ void (QOPENGLF_APIENTRYP DispatchComputeIndirect)(GLintptr indirect);
+ void (QOPENGLF_APIENTRYP DrawArraysIndirect)(GLenum mode, const void *indirect);
+ void (QOPENGLF_APIENTRYP DrawElementsIndirect)(GLenum mode, GLenum type, const void *indirect);
+ void (QOPENGLF_APIENTRYP FramebufferParameteri)(GLenum target, GLenum pname, GLint param);
+ void (QOPENGLF_APIENTRYP GetFramebufferParameteriv)(GLenum target, GLenum pname, GLint *params);
+ void (QOPENGLF_APIENTRYP GetProgramInterfaceiv)(GLuint program, GLenum programInterface, GLenum pname, GLint *params);
+ GLuint (QOPENGLF_APIENTRYP GetProgramResourceIndex)(GLuint program, GLenum programInterface, const GLchar *name);
+ void (QOPENGLF_APIENTRYP GetProgramResourceName)(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name);
+ void (QOPENGLF_APIENTRYP GetProgramResourceiv)(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params);
+ GLint (QOPENGLF_APIENTRYP GetProgramResourceLocation)(GLuint program, GLenum programInterface, const GLchar *name);
+ void (QOPENGLF_APIENTRYP UseProgramStages)(GLuint pipeline, GLbitfield stages, GLuint program);
+ void (QOPENGLF_APIENTRYP ActiveShaderProgram)(GLuint pipeline, GLuint program);
+ GLuint (QOPENGLF_APIENTRYP CreateShaderProgramv)(GLenum type, GLsizei count, const GLchar *const*strings);
+ void (QOPENGLF_APIENTRYP BindProgramPipeline)(GLuint pipeline);
+ void (QOPENGLF_APIENTRYP DeleteProgramPipelines)(GLsizei n, const GLuint *pipelines);
+ void (QOPENGLF_APIENTRYP GenProgramPipelines)(GLsizei n, GLuint *pipelines);
+ GLboolean (QOPENGLF_APIENTRYP IsProgramPipeline)(GLuint pipeline);
+ void (QOPENGLF_APIENTRYP GetProgramPipelineiv)(GLuint pipeline, GLenum pname, GLint *params);
+ void (QOPENGLF_APIENTRYP ProgramUniform1i)(GLuint program, GLint location, GLint v0);
+ void (QOPENGLF_APIENTRYP ProgramUniform2i)(GLuint program, GLint location, GLint v0, GLint v1);
+ void (QOPENGLF_APIENTRYP ProgramUniform3i)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+ void (QOPENGLF_APIENTRYP ProgramUniform4i)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+ void (QOPENGLF_APIENTRYP ProgramUniform1ui)(GLuint program, GLint location, GLuint v0);
+ void (QOPENGLF_APIENTRYP ProgramUniform2ui)(GLuint program, GLint location, GLuint v0, GLuint v1);
+ void (QOPENGLF_APIENTRYP ProgramUniform3ui)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+ void (QOPENGLF_APIENTRYP ProgramUniform4ui)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+ void (QOPENGLF_APIENTRYP ProgramUniform1f)(GLuint program, GLint location, GLfloat v0);
+ void (QOPENGLF_APIENTRYP ProgramUniform2f)(GLuint program, GLint location, GLfloat v0, GLfloat v1);
+ void (QOPENGLF_APIENTRYP ProgramUniform3f)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+ void (QOPENGLF_APIENTRYP ProgramUniform4f)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+ void (QOPENGLF_APIENTRYP ProgramUniform1iv)(GLuint program, GLint location, GLsizei count, const GLint *value);
+ void (QOPENGLF_APIENTRYP ProgramUniform2iv)(GLuint program, GLint location, GLsizei count, const GLint *value);
+ void (QOPENGLF_APIENTRYP ProgramUniform3iv)(GLuint program, GLint location, GLsizei count, const GLint *value);
+ void (QOPENGLF_APIENTRYP ProgramUniform4iv)(GLuint program, GLint location, GLsizei count, const GLint *value);
+ void (QOPENGLF_APIENTRYP ProgramUniform1uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value);
+ void (QOPENGLF_APIENTRYP ProgramUniform2uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value);
+ void (QOPENGLF_APIENTRYP ProgramUniform3uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value);
+ void (QOPENGLF_APIENTRYP ProgramUniform4uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value);
+ void (QOPENGLF_APIENTRYP ProgramUniform1fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ProgramUniform2fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ProgramUniform3fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ProgramUniform4fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ProgramUniformMatrix2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ProgramUniformMatrix3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ProgramUniformMatrix4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ProgramUniformMatrix2x3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ProgramUniformMatrix3x2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ProgramUniformMatrix2x4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ProgramUniformMatrix4x2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ProgramUniformMatrix3x4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ProgramUniformMatrix4x3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ValidateProgramPipeline)(GLuint pipeline);
+ void (QOPENGLF_APIENTRYP GetProgramPipelineInfoLog)(GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+ void (QOPENGLF_APIENTRYP BindImageTexture)(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);
+ void (QOPENGLF_APIENTRYP GetBooleani_v)(GLenum target, GLuint index, GLboolean *data);
+ void (QOPENGLF_APIENTRYP MemoryBarrierFunc)(GLbitfield barriers);
+ void (QOPENGLF_APIENTRYP MemoryBarrierByRegion)(GLbitfield barriers);
+ void (QOPENGLF_APIENTRYP TexStorage2DMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+ void (QOPENGLF_APIENTRYP GetMultisamplefv)(GLenum pname, GLuint index, GLfloat *val);
+ void (QOPENGLF_APIENTRYP SampleMaski)(GLuint maskNumber, GLbitfield mask);
+ void (QOPENGLF_APIENTRYP GetTexLevelParameteriv)(GLenum target, GLint level, GLenum pname, GLint *params);
+ void (QOPENGLF_APIENTRYP GetTexLevelParameterfv)(GLenum target, GLint level, GLenum pname, GLfloat *params);
+ void (QOPENGLF_APIENTRYP BindVertexBuffer)(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);
+ void (QOPENGLF_APIENTRYP VertexAttribFormat)(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);
+ void (QOPENGLF_APIENTRYP VertexAttribIFormat)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+ void (QOPENGLF_APIENTRYP VertexAttribBinding)(GLuint attribindex, GLuint bindingindex);
+ void (QOPENGLF_APIENTRYP VertexBindingDivisor)(GLuint bindingindex, GLuint divisor);
+
+ QPair<int, int> supportedVersion() const { return m_supportedVersion; }
private:
bool init();
QFunctionPointer resolve(const char *name);
-
+#ifndef QT_NO_LIBRARY
QLibrary m_gl;
+#endif
+ QPair<int, int> m_supportedVersion;
};
-class Q_GUI_EXPORT QOpenGLExtensions : public QOpenGLFunctions
+class Q_GUI_EXPORT QOpenGLExtensions : public QOpenGLExtraFunctions
{
Q_DECLARE_PRIVATE(QOpenGLExtensions)
public:
@@ -113,7 +275,8 @@ public:
GeometryShaders = 0x00080000,
MapBufferRange = 0x00100000,
Sized8Formats = 0x00200000,
- DiscardFramebuffer = 0x00400000
+ DiscardFramebuffer = 0x00400000,
+ Sized16Formats = 0x00800000
};
Q_DECLARE_FLAGS(OpenGLExtensions, OpenGLExtension)
@@ -121,19 +284,7 @@ public:
bool hasOpenGLExtension(QOpenGLExtensions::OpenGLExtension extension) const;
GLvoid *glMapBuffer(GLenum target, GLenum access);
- GLvoid *glMapBufferRange(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr length, GLbitfield access);
- GLboolean glUnmapBuffer(GLenum target);
-
- void glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
- GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter);
-
- void glRenderbufferStorageMultisample(GLenum target, GLsizei samples,
- GLenum internalFormat,
- GLsizei width, GLsizei height);
-
void glGetBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, GLvoid *data);
-
void glDiscardFramebufferEXT (GLenum target, GLsizei numAttachments, const GLenum *attachments);
QOpenGLES3Helper *gles3Helper();
@@ -146,21 +297,12 @@ private:
Q_DECLARE_OPERATORS_FOR_FLAGS(QOpenGLExtensions::OpenGLExtensions)
-class QOpenGLExtensionsPrivate : public QOpenGLFunctionsPrivate
+class QOpenGLExtensionsPrivate : public QOpenGLExtraFunctionsPrivate
{
public:
explicit QOpenGLExtensionsPrivate(QOpenGLContext *ctx);
GLvoid* (QOPENGLF_APIENTRYP MapBuffer)(GLenum target, GLenum access);
- GLvoid* (QOPENGLF_APIENTRYP MapBufferRange)(GLenum target, qopengl_GLintptr offset,
- qopengl_GLsizeiptr length, GLbitfield access);
- GLboolean (QOPENGLF_APIENTRYP UnmapBuffer)(GLenum target);
- void (QOPENGLF_APIENTRYP BlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
- GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter);
- void (QOPENGLF_APIENTRYP RenderbufferStorageMultisample)(GLenum target, GLsizei samples,
- GLenum internalFormat,
- GLsizei width, GLsizei height);
void (QOPENGLF_APIENTRYP GetBufferSubData)(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, GLvoid *data);
void (QOPENGLF_APIENTRYP DiscardFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum *attachments);
@@ -177,45 +319,6 @@ inline GLvoid *QOpenGLExtensions::glMapBuffer(GLenum target, GLenum access)
return result;
}
-inline GLvoid *QOpenGLExtensions::glMapBufferRange(GLenum target, qopengl_GLintptr offset,
- qopengl_GLsizeiptr length, GLbitfield access)
-{
- Q_D(QOpenGLExtensions);
- Q_ASSERT(QOpenGLExtensions::isInitialized(d));
- GLvoid *result = d->MapBufferRange(target, offset, length, access);
- Q_OPENGL_FUNCTIONS_DEBUG
- return result;
-}
-
-inline GLboolean QOpenGLExtensions::glUnmapBuffer(GLenum target)
-{
- Q_D(QOpenGLExtensions);
- Q_ASSERT(QOpenGLExtensions::isInitialized(d));
- GLboolean result = d->UnmapBuffer(target);
- Q_OPENGL_FUNCTIONS_DEBUG
- return result;
-}
-
-inline void QOpenGLExtensions::glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
- GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter)
-{
- Q_D(QOpenGLExtensions);
- Q_ASSERT(QOpenGLExtensions::isInitialized(d));
- d->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
- Q_OPENGL_FUNCTIONS_DEBUG
-}
-
-inline void QOpenGLExtensions::glRenderbufferStorageMultisample(GLenum target, GLsizei samples,
- GLenum internalFormat,
- GLsizei width, GLsizei height)
-{
- Q_D(QOpenGLExtensions);
- Q_ASSERT(QOpenGLExtensions::isInitialized(d));
- d->RenderbufferStorageMultisample(target, samples, internalFormat, width, height);
- Q_OPENGL_FUNCTIONS_DEBUG
-}
-
inline void QOpenGLExtensions::glGetBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, GLvoid *data)
{
Q_D(QOpenGLExtensions);
diff --git a/src/gui/opengl/qopenglextrafunctions.h b/src/gui/opengl/qopenglextrafunctions.h
new file mode 100644
index 0000000000..6558284bd0
--- /dev/null
+++ b/src/gui/opengl/qopenglextrafunctions.h
@@ -0,0 +1,1990 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENGLEXTRAFUNCTIONS_H
+#define QOPENGLEXTRAFUNCTIONS_H
+
+#include <QtCore/qglobal.h>
+
+#ifndef QT_NO_OPENGL
+
+#include <QtGui/qopenglfunctions.h>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLExtraFunctionsPrivate;
+
+#undef glReadBuffer
+#undef glDrawRangeElements
+#undef glTexImage3D
+#undef glTexSubImage3D
+#undef glCopyTexSubImage3D
+#undef glCompressedTexImage3D
+#undef glCompressedTexSubImage3D
+#undef glGenQueries
+#undef glDeleteQueries
+#undef glIsQuery
+#undef glBeginQuery
+#undef glEndQuery
+#undef glGetQueryiv
+#undef glGetQueryObjectuiv
+#undef glUnmapBuffer
+#undef glGetBufferPointerv
+#undef glDrawBuffers
+#undef glUniformMatrix2x3fv
+#undef glUniformMatrix3x2fv
+#undef glUniformMatrix2x4fv
+#undef glUniformMatrix4x2fv
+#undef glUniformMatrix3x4fv
+#undef glUniformMatrix4x3fv
+#undef glBlitFramebuffer
+#undef glRenderbufferStorageMultisample
+#undef glFramebufferTextureLayer
+#undef glMapBufferRange
+#undef glFlushMappedBufferRange
+#undef glBindVertexArray
+#undef glDeleteVertexArrays
+#undef glGenVertexArrays
+#undef glIsVertexArray
+#undef glGetIntegeri_v
+#undef glBeginTransformFeedback
+#undef glEndTransformFeedback
+#undef glBindBufferRange
+#undef glBindBufferBase
+#undef glTransformFeedbackVaryings
+#undef glGetTransformFeedbackVarying
+#undef glVertexAttribIPointer
+#undef glGetVertexAttribIiv
+#undef glGetVertexAttribIuiv
+#undef glVertexAttribI4i
+#undef glVertexAttribI4ui
+#undef glVertexAttribI4iv
+#undef glVertexAttribI4uiv
+#undef glGetUniformuiv
+#undef glGetFragDataLocation
+#undef glUniform1ui
+#undef glUniform2ui
+#undef glUniform3ui
+#undef glUniform4ui
+#undef glUniform1uiv
+#undef glUniform2uiv
+#undef glUniform3uiv
+#undef glUniform4uiv
+#undef glClearBufferiv
+#undef glClearBufferuiv
+#undef glClearBufferfv
+#undef glClearBufferfi
+#undef glGetStringi
+#undef glCopyBufferSubData
+#undef glGetUniformIndices
+#undef glGetActiveUniformsiv
+#undef glGetUniformBlockIndex
+#undef glGetActiveUniformBlockiv
+#undef glGetActiveUniformBlockName
+#undef glUniformBlockBinding
+#undef glDrawArraysInstanced
+#undef glDrawElementsInstanced
+#undef glFenceSync
+#undef glIsSync
+#undef glDeleteSync
+#undef glClientWaitSync
+#undef glWaitSync
+#undef glGetInteger64v
+#undef glGetSynciv
+#undef glGetInteger64i_v
+#undef glGetBufferParameteri64v
+#undef glGenSamplers
+#undef glDeleteSamplers
+#undef glIsSampler
+#undef glBindSampler
+#undef glSamplerParameteri
+#undef glSamplerParameteriv
+#undef glSamplerParameterf
+#undef glSamplerParameterfv
+#undef glGetSamplerParameteriv
+#undef glGetSamplerParameterfv
+#undef glVertexAttribDivisor
+#undef glBindTransformFeedback
+#undef glDeleteTransformFeedbacks
+#undef glGenTransformFeedbacks
+#undef glIsTransformFeedback
+#undef glPauseTransformFeedback
+#undef glResumeTransformFeedback
+#undef glGetProgramBinary
+#undef glProgramBinary
+#undef glProgramParameteri
+#undef glInvalidateFramebuffer
+#undef glInvalidateSubFramebuffer
+#undef glTexStorage2D
+#undef glTexStorage3D
+#undef glGetInternalformativ
+
+#undef glDispatchCompute
+#undef glDispatchComputeIndirect
+#undef glDrawArraysIndirect
+#undef glDrawElementsIndirect
+#undef glFramebufferParameteri
+#undef glGetFramebufferParameteriv
+#undef glGetProgramInterfaceiv
+#undef glGetProgramResourceIndex
+#undef glGetProgramResourceName
+#undef glGetProgramResourceiv
+#undef glGetProgramResourceLocation
+#undef glUseProgramStages
+#undef glActiveShaderProgram
+#undef glCreateShaderProgramv
+#undef glBindProgramPipeline
+#undef glDeleteProgramPipelines
+#undef glGenProgramPipelines
+#undef glIsProgramPipeline
+#undef glGetProgramPipelineiv
+#undef glProgramUniform1i
+#undef glProgramUniform2i
+#undef glProgramUniform3i
+#undef glProgramUniform4i
+#undef glProgramUniform1ui
+#undef glProgramUniform2ui
+#undef glProgramUniform3ui
+#undef glProgramUniform4ui
+#undef glProgramUniform1f
+#undef glProgramUniform2f
+#undef glProgramUniform3f
+#undef glProgramUniform4f
+#undef glProgramUniform1iv
+#undef glProgramUniform2iv
+#undef glProgramUniform3iv
+#undef glProgramUniform4iv
+#undef glProgramUniform1uiv
+#undef glProgramUniform2uiv
+#undef glProgramUniform3uiv
+#undef glProgramUniform4uiv
+#undef glProgramUniform1fv
+#undef glProgramUniform2fv
+#undef glProgramUniform3fv
+#undef glProgramUniform4fv
+#undef glProgramUniformMatrix2fv
+#undef glProgramUniformMatrix3fv
+#undef glProgramUniformMatrix4fv
+#undef glProgramUniformMatrix2x3fv
+#undef glProgramUniformMatrix3x2fv
+#undef glProgramUniformMatrix2x4fv
+#undef glProgramUniformMatrix4x2fv
+#undef glProgramUniformMatrix3x4fv
+#undef glProgramUniformMatrix4x3fv
+#undef glValidateProgramPipeline
+#undef glGetProgramPipelineInfoLog
+#undef glBindImageTexture
+#undef glGetBooleani_v
+#undef glMemoryBarrier
+#undef glMemoryBarrierByRegion
+#undef glTexStorage2DMultisample
+#undef glGetMultisamplefv
+#undef glSampleMaski
+#undef glGetTexLevelParameteriv
+#undef glGetTexLevelParameterfv
+#undef glBindVertexBuffer
+#undef glVertexAttribFormat
+#undef glVertexAttribIFormat
+#undef glVertexAttribBinding
+#undef glVertexBindingDivisor
+
+class Q_GUI_EXPORT QOpenGLExtraFunctions : public QOpenGLFunctions
+{
+ Q_DECLARE_PRIVATE(QOpenGLExtraFunctions)
+
+public:
+ QOpenGLExtraFunctions();
+ QOpenGLExtraFunctions(QOpenGLContext *context);
+ ~QOpenGLExtraFunctions() {}
+
+ // GLES3
+ void glReadBuffer(GLenum mode);
+ void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices);
+ void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels);
+ void glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);
+ void glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+ void glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);
+ void glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);
+ void glGenQueries(GLsizei n, GLuint *ids);
+ void glDeleteQueries(GLsizei n, const GLuint *ids);
+ GLboolean glIsQuery(GLuint id);
+ void glBeginQuery(GLenum target, GLuint id);
+ void glEndQuery(GLenum target);
+ void glGetQueryiv(GLenum target, GLenum pname, GLint *params);
+ void glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params);
+ GLboolean glUnmapBuffer(GLenum target);
+ void glGetBufferPointerv(GLenum target, GLenum pname, void **params);
+ void glDrawBuffers(GLsizei n, const GLenum *bufs);
+ void glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+ void glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+ void glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+ void *glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+ void glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length);
+ void glBindVertexArray(GLuint array);
+ void glDeleteVertexArrays(GLsizei n, const GLuint *arrays);
+ void glGenVertexArrays(GLsizei n, GLuint *arrays);
+ GLboolean glIsVertexArray(GLuint array);
+ void glGetIntegeri_v(GLenum target, GLuint index, GLint *data);
+ void glBeginTransformFeedback(GLenum primitiveMode);
+ void glEndTransformFeedback(void);
+ void glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+ void glBindBufferBase(GLenum target, GLuint index, GLuint buffer);
+ void glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode);
+ void glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+ void glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);
+ void glGetVertexAttribIiv(GLuint index, GLenum pname, GLint *params);
+ void glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params);
+ void glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w);
+ void glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+ void glVertexAttribI4iv(GLuint index, const GLint *v);
+ void glVertexAttribI4uiv(GLuint index, const GLuint *v);
+ void glGetUniformuiv(GLuint program, GLint location, GLuint *params);
+ GLint glGetFragDataLocation(GLuint program, const GLchar *name);
+ void glUniform1ui(GLint location, GLuint v0);
+ void glUniform2ui(GLint location, GLuint v0, GLuint v1);
+ void glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2);
+ void glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+ void glUniform1uiv(GLint location, GLsizei count, const GLuint *value);
+ void glUniform2uiv(GLint location, GLsizei count, const GLuint *value);
+ void glUniform3uiv(GLint location, GLsizei count, const GLuint *value);
+ void glUniform4uiv(GLint location, GLsizei count, const GLuint *value);
+ void glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value);
+ void glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value);
+ void glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value);
+ void glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+ const GLubyte *glGetStringi(GLenum name, GLuint index);
+ void glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+ void glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices);
+ void glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params);
+ GLuint glGetUniformBlockIndex(GLuint program, const GLchar *uniformBlockName);
+ void glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params);
+ void glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName);
+ void glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+ void glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
+ void glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount);
+ GLsync glFenceSync(GLenum condition, GLbitfield flags);
+ GLboolean glIsSync(GLsync sync);
+ void glDeleteSync(GLsync sync);
+ GLenum glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout);
+ void glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout);
+ void glGetInteger64v(GLenum pname, GLint64 *data);
+ void glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+ void glGetInteger64i_v(GLenum target, GLuint index, GLint64 *data);
+ void glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params);
+ void glGenSamplers(GLsizei count, GLuint *samplers);
+ void glDeleteSamplers(GLsizei count, const GLuint *samplers);
+ GLboolean glIsSampler(GLuint sampler);
+ void glBindSampler(GLuint unit, GLuint sampler);
+ void glSamplerParameteri(GLuint sampler, GLenum pname, GLint param);
+ void glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint *param);
+ void glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param);
+ void glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param);
+ void glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params);
+ void glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params);
+ void glVertexAttribDivisor(GLuint index, GLuint divisor);
+ void glBindTransformFeedback(GLenum target, GLuint id);
+ void glDeleteTransformFeedbacks(GLsizei n, const GLuint *ids);
+ void glGenTransformFeedbacks(GLsizei n, GLuint *ids);
+ GLboolean glIsTransformFeedback(GLuint id);
+ void glPauseTransformFeedback(void);
+ void glResumeTransformFeedback(void);
+ void glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary);
+ void glProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length);
+ void glProgramParameteri(GLuint program, GLenum pname, GLint value);
+ void glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments);
+ void glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+ void glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+ void glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+ void glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params);
+
+ // GLES 3.1
+ void glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);
+ void glDispatchComputeIndirect(GLintptr indirect);
+ void glDrawArraysIndirect(GLenum mode, const void *indirect);
+ void glDrawElementsIndirect(GLenum mode, GLenum type, const void *indirect);
+ void glFramebufferParameteri(GLenum target, GLenum pname, GLint param);
+ void glGetFramebufferParameteriv(GLenum target, GLenum pname, GLint *params);
+ void glGetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, GLint *params);
+ GLuint glGetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name);
+ void glGetProgramResourceName(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name);
+ void glGetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params);
+ GLint glGetProgramResourceLocation(GLuint program, GLenum programInterface, const GLchar *name);
+ void glUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program);
+ void glActiveShaderProgram(GLuint pipeline, GLuint program);
+ GLuint glCreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const*strings);
+ void glBindProgramPipeline(GLuint pipeline);
+ void glDeleteProgramPipelines(GLsizei n, const GLuint *pipelines);
+ void glGenProgramPipelines(GLsizei n, GLuint *pipelines);
+ GLboolean glIsProgramPipeline(GLuint pipeline);
+ void glGetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params);
+ void glProgramUniform1i(GLuint program, GLint location, GLint v0);
+ void glProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1);
+ void glProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+ void glProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+ void glProgramUniform1ui(GLuint program, GLint location, GLuint v0);
+ void glProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1);
+ void glProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+ void glProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+ void glProgramUniform1f(GLuint program, GLint location, GLfloat v0);
+ void glProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1);
+ void glProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+ void glProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+ void glProgramUniform1iv(GLuint program, GLint location, GLsizei count, const GLint *value);
+ void glProgramUniform2iv(GLuint program, GLint location, GLsizei count, const GLint *value);
+ void glProgramUniform3iv(GLuint program, GLint location, GLsizei count, const GLint *value);
+ void glProgramUniform4iv(GLuint program, GLint location, GLsizei count, const GLint *value);
+ void glProgramUniform1uiv(GLuint program, GLint location, GLsizei count, const GLuint *value);
+ void glProgramUniform2uiv(GLuint program, GLint location, GLsizei count, const GLuint *value);
+ void glProgramUniform3uiv(GLuint program, GLint location, GLsizei count, const GLuint *value);
+ void glProgramUniform4uiv(GLuint program, GLint location, GLsizei count, const GLuint *value);
+ void glProgramUniform1fv(GLuint program, GLint location, GLsizei count, const GLfloat *value);
+ void glProgramUniform2fv(GLuint program, GLint location, GLsizei count, const GLfloat *value);
+ void glProgramUniform3fv(GLuint program, GLint location, GLsizei count, const GLfloat *value);
+ void glProgramUniform4fv(GLuint program, GLint location, GLsizei count, const GLfloat *value);
+ void glProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void glProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void glProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void glProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void glProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void glProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void glProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void glProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void glProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void glValidateProgramPipeline(GLuint pipeline);
+ void glGetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+ void glBindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);
+ void glGetBooleani_v(GLenum target, GLuint index, GLboolean *data);
+ void glMemoryBarrier(GLbitfield barriers);
+ void glMemoryBarrierByRegion(GLbitfield barriers);
+ void glTexStorage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+ void glGetMultisamplefv(GLenum pname, GLuint index, GLfloat *val);
+ void glSampleMaski(GLuint maskNumber, GLbitfield mask);
+ void glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params);
+ void glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params);
+ void glBindVertexBuffer(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);
+ void glVertexAttribFormat(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);
+ void glVertexAttribIFormat(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+ void glVertexAttribBinding(GLuint attribindex, GLuint bindingindex);
+ void glVertexBindingDivisor(GLuint bindingindex, GLuint divisor);
+
+private:
+ static bool isInitialized(const QOpenGLExtraFunctionsPrivate *d) { return d != 0; }
+};
+
+class QOpenGLExtraFunctionsPrivate : public QOpenGLFunctionsPrivate
+{
+public:
+ QOpenGLExtraFunctionsPrivate(QOpenGLContext *ctx);
+
+ // GLES3
+ void (QOPENGLF_APIENTRYP ReadBuffer)(GLenum mode);
+ void (QOPENGLF_APIENTRYP DrawRangeElements)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices);
+ void (QOPENGLF_APIENTRYP TexImage3D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels);
+ void (QOPENGLF_APIENTRYP TexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);
+ void (QOPENGLF_APIENTRYP CopyTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+ void (QOPENGLF_APIENTRYP CompressedTexImage3D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);
+ void (QOPENGLF_APIENTRYP CompressedTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);
+ void (QOPENGLF_APIENTRYP GenQueries)(GLsizei n, GLuint *ids);
+ void (QOPENGLF_APIENTRYP DeleteQueries)(GLsizei n, const GLuint *ids);
+ GLboolean (QOPENGLF_APIENTRYP IsQuery)(GLuint id);
+ void (QOPENGLF_APIENTRYP BeginQuery)(GLenum target, GLuint id);
+ void (QOPENGLF_APIENTRYP EndQuery)(GLenum target);
+ void (QOPENGLF_APIENTRYP GetQueryiv)(GLenum target, GLenum pname, GLint *params);
+ void (QOPENGLF_APIENTRYP GetQueryObjectuiv)(GLuint id, GLenum pname, GLuint *params);
+ GLboolean (QOPENGLF_APIENTRYP UnmapBuffer)(GLenum target);
+ void (QOPENGLF_APIENTRYP GetBufferPointerv)(GLenum target, GLenum pname, void **params);
+ void (QOPENGLF_APIENTRYP DrawBuffers)(GLsizei n, const GLenum *bufs);
+ void (QOPENGLF_APIENTRYP UniformMatrix2x3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP UniformMatrix3x2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP UniformMatrix2x4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP UniformMatrix4x2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP UniformMatrix3x4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP UniformMatrix4x3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP BlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+ void (QOPENGLF_APIENTRYP RenderbufferStorageMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+ void (QOPENGLF_APIENTRYP FramebufferTextureLayer)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+ void *(QOPENGLF_APIENTRYP MapBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+ void (QOPENGLF_APIENTRYP FlushMappedBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length);
+ void (QOPENGLF_APIENTRYP BindVertexArray)(GLuint array);
+ void (QOPENGLF_APIENTRYP DeleteVertexArrays)(GLsizei n, const GLuint *arrays);
+ void (QOPENGLF_APIENTRYP GenVertexArrays)(GLsizei n, GLuint *arrays);
+ GLboolean (QOPENGLF_APIENTRYP IsVertexArray)(GLuint array);
+ void (QOPENGLF_APIENTRYP GetIntegeri_v)(GLenum target, GLuint index, GLint *data);
+ void (QOPENGLF_APIENTRYP BeginTransformFeedback)(GLenum primitiveMode);
+ void (QOPENGLF_APIENTRYP EndTransformFeedback)(void);
+ void (QOPENGLF_APIENTRYP BindBufferRange)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+ void (QOPENGLF_APIENTRYP BindBufferBase)(GLenum target, GLuint index, GLuint buffer);
+ void (QOPENGLF_APIENTRYP TransformFeedbackVaryings)(GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode);
+ void (QOPENGLF_APIENTRYP GetTransformFeedbackVarying)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+ void (QOPENGLF_APIENTRYP VertexAttribIPointer)(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);
+ void (QOPENGLF_APIENTRYP GetVertexAttribIiv)(GLuint index, GLenum pname, GLint *params);
+ void (QOPENGLF_APIENTRYP GetVertexAttribIuiv)(GLuint index, GLenum pname, GLuint *params);
+ void (QOPENGLF_APIENTRYP VertexAttribI4i)(GLuint index, GLint x, GLint y, GLint z, GLint w);
+ void (QOPENGLF_APIENTRYP VertexAttribI4ui)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+ void (QOPENGLF_APIENTRYP VertexAttribI4iv)(GLuint index, const GLint *v);
+ void (QOPENGLF_APIENTRYP VertexAttribI4uiv)(GLuint index, const GLuint *v);
+ void (QOPENGLF_APIENTRYP GetUniformuiv)(GLuint program, GLint location, GLuint *params);
+ GLint (QOPENGLF_APIENTRYP GetFragDataLocation)(GLuint program, const GLchar *name);
+ void (QOPENGLF_APIENTRYP Uniform1ui)(GLint location, GLuint v0);
+ void (QOPENGLF_APIENTRYP Uniform2ui)(GLint location, GLuint v0, GLuint v1);
+ void (QOPENGLF_APIENTRYP Uniform3ui)(GLint location, GLuint v0, GLuint v1, GLuint v2);
+ void (QOPENGLF_APIENTRYP Uniform4ui)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+ void (QOPENGLF_APIENTRYP Uniform1uiv)(GLint location, GLsizei count, const GLuint *value);
+ void (QOPENGLF_APIENTRYP Uniform2uiv)(GLint location, GLsizei count, const GLuint *value);
+ void (QOPENGLF_APIENTRYP Uniform3uiv)(GLint location, GLsizei count, const GLuint *value);
+ void (QOPENGLF_APIENTRYP Uniform4uiv)(GLint location, GLsizei count, const GLuint *value);
+ void (QOPENGLF_APIENTRYP ClearBufferiv)(GLenum buffer, GLint drawbuffer, const GLint *value);
+ void (QOPENGLF_APIENTRYP ClearBufferuiv)(GLenum buffer, GLint drawbuffer, const GLuint *value);
+ void (QOPENGLF_APIENTRYP ClearBufferfv)(GLenum buffer, GLint drawbuffer, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ClearBufferfi)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+ const GLubyte *(QOPENGLF_APIENTRYP GetStringi)(GLenum name, GLuint index);
+ void (QOPENGLF_APIENTRYP CopyBufferSubData)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+ void (QOPENGLF_APIENTRYP GetUniformIndices)(GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices);
+ void (QOPENGLF_APIENTRYP GetActiveUniformsiv)(GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params);
+ GLuint (QOPENGLF_APIENTRYP GetUniformBlockIndex)(GLuint program, const GLchar *uniformBlockName);
+ void (QOPENGLF_APIENTRYP GetActiveUniformBlockiv)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params);
+ void (QOPENGLF_APIENTRYP GetActiveUniformBlockName)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName);
+ void (QOPENGLF_APIENTRYP UniformBlockBinding)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+ void (QOPENGLF_APIENTRYP DrawArraysInstanced)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
+ void (QOPENGLF_APIENTRYP DrawElementsInstanced)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount);
+ GLsync (QOPENGLF_APIENTRYP FenceSync)(GLenum condition, GLbitfield flags);
+ GLboolean (QOPENGLF_APIENTRYP IsSync)(GLsync sync);
+ void (QOPENGLF_APIENTRYP DeleteSync)(GLsync sync);
+ GLenum (QOPENGLF_APIENTRYP ClientWaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout);
+ void (QOPENGLF_APIENTRYP WaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout);
+ void (QOPENGLF_APIENTRYP GetInteger64v)(GLenum pname, GLint64 *data);
+ void (QOPENGLF_APIENTRYP GetSynciv)(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+ void (QOPENGLF_APIENTRYP GetInteger64i_v)(GLenum target, GLuint index, GLint64 *data);
+ void (QOPENGLF_APIENTRYP GetBufferParameteri64v)(GLenum target, GLenum pname, GLint64 *params);
+ void (QOPENGLF_APIENTRYP GenSamplers)(GLsizei count, GLuint *samplers);
+ void (QOPENGLF_APIENTRYP DeleteSamplers)(GLsizei count, const GLuint *samplers);
+ GLboolean (QOPENGLF_APIENTRYP IsSampler)(GLuint sampler);
+ void (QOPENGLF_APIENTRYP BindSampler)(GLuint unit, GLuint sampler);
+ void (QOPENGLF_APIENTRYP SamplerParameteri)(GLuint sampler, GLenum pname, GLint param);
+ void (QOPENGLF_APIENTRYP SamplerParameteriv)(GLuint sampler, GLenum pname, const GLint *param);
+ void (QOPENGLF_APIENTRYP SamplerParameterf)(GLuint sampler, GLenum pname, GLfloat param);
+ void (QOPENGLF_APIENTRYP SamplerParameterfv)(GLuint sampler, GLenum pname, const GLfloat *param);
+ void (QOPENGLF_APIENTRYP GetSamplerParameteriv)(GLuint sampler, GLenum pname, GLint *params);
+ void (QOPENGLF_APIENTRYP GetSamplerParameterfv)(GLuint sampler, GLenum pname, GLfloat *params);
+ void (QOPENGLF_APIENTRYP VertexAttribDivisor)(GLuint index, GLuint divisor);
+ void (QOPENGLF_APIENTRYP BindTransformFeedback)(GLenum target, GLuint id);
+ void (QOPENGLF_APIENTRYP DeleteTransformFeedbacks)(GLsizei n, const GLuint *ids);
+ void (QOPENGLF_APIENTRYP GenTransformFeedbacks)(GLsizei n, GLuint *ids);
+ GLboolean (QOPENGLF_APIENTRYP IsTransformFeedback)(GLuint id);
+ void (QOPENGLF_APIENTRYP PauseTransformFeedback)(void);
+ void (QOPENGLF_APIENTRYP ResumeTransformFeedback)(void);
+ void (QOPENGLF_APIENTRYP GetProgramBinary)(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary);
+ void (QOPENGLF_APIENTRYP ProgramBinary)(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length);
+ void (QOPENGLF_APIENTRYP ProgramParameteri)(GLuint program, GLenum pname, GLint value);
+ void (QOPENGLF_APIENTRYP InvalidateFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum *attachments);
+ void (QOPENGLF_APIENTRYP InvalidateSubFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+ void (QOPENGLF_APIENTRYP TexStorage2D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+ void (QOPENGLF_APIENTRYP TexStorage3D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+ void (QOPENGLF_APIENTRYP GetInternalformativ)(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params);
+
+ // GLES 3.1
+ void (QOPENGLF_APIENTRYP DispatchCompute)(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);
+ void (QOPENGLF_APIENTRYP DispatchComputeIndirect)(GLintptr indirect);
+ void (QOPENGLF_APIENTRYP DrawArraysIndirect)(GLenum mode, const void *indirect);
+ void (QOPENGLF_APIENTRYP DrawElementsIndirect)(GLenum mode, GLenum type, const void *indirect);
+ void (QOPENGLF_APIENTRYP FramebufferParameteri)(GLenum target, GLenum pname, GLint param);
+ void (QOPENGLF_APIENTRYP GetFramebufferParameteriv)(GLenum target, GLenum pname, GLint *params);
+ void (QOPENGLF_APIENTRYP GetProgramInterfaceiv)(GLuint program, GLenum programInterface, GLenum pname, GLint *params);
+ GLuint (QOPENGLF_APIENTRYP GetProgramResourceIndex)(GLuint program, GLenum programInterface, const GLchar *name);
+ void (QOPENGLF_APIENTRYP GetProgramResourceName)(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name);
+ void (QOPENGLF_APIENTRYP GetProgramResourceiv)(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params);
+ GLint (QOPENGLF_APIENTRYP GetProgramResourceLocation)(GLuint program, GLenum programInterface, const GLchar *name);
+ void (QOPENGLF_APIENTRYP UseProgramStages)(GLuint pipeline, GLbitfield stages, GLuint program);
+ void (QOPENGLF_APIENTRYP ActiveShaderProgram)(GLuint pipeline, GLuint program);
+ GLuint (QOPENGLF_APIENTRYP CreateShaderProgramv)(GLenum type, GLsizei count, const GLchar *const*strings);
+ void (QOPENGLF_APIENTRYP BindProgramPipeline)(GLuint pipeline);
+ void (QOPENGLF_APIENTRYP DeleteProgramPipelines)(GLsizei n, const GLuint *pipelines);
+ void (QOPENGLF_APIENTRYP GenProgramPipelines)(GLsizei n, GLuint *pipelines);
+ GLboolean (QOPENGLF_APIENTRYP IsProgramPipeline)(GLuint pipeline);
+ void (QOPENGLF_APIENTRYP GetProgramPipelineiv)(GLuint pipeline, GLenum pname, GLint *params);
+ void (QOPENGLF_APIENTRYP ProgramUniform1i)(GLuint program, GLint location, GLint v0);
+ void (QOPENGLF_APIENTRYP ProgramUniform2i)(GLuint program, GLint location, GLint v0, GLint v1);
+ void (QOPENGLF_APIENTRYP ProgramUniform3i)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+ void (QOPENGLF_APIENTRYP ProgramUniform4i)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+ void (QOPENGLF_APIENTRYP ProgramUniform1ui)(GLuint program, GLint location, GLuint v0);
+ void (QOPENGLF_APIENTRYP ProgramUniform2ui)(GLuint program, GLint location, GLuint v0, GLuint v1);
+ void (QOPENGLF_APIENTRYP ProgramUniform3ui)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+ void (QOPENGLF_APIENTRYP ProgramUniform4ui)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+ void (QOPENGLF_APIENTRYP ProgramUniform1f)(GLuint program, GLint location, GLfloat v0);
+ void (QOPENGLF_APIENTRYP ProgramUniform2f)(GLuint program, GLint location, GLfloat v0, GLfloat v1);
+ void (QOPENGLF_APIENTRYP ProgramUniform3f)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+ void (QOPENGLF_APIENTRYP ProgramUniform4f)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+ void (QOPENGLF_APIENTRYP ProgramUniform1iv)(GLuint program, GLint location, GLsizei count, const GLint *value);
+ void (QOPENGLF_APIENTRYP ProgramUniform2iv)(GLuint program, GLint location, GLsizei count, const GLint *value);
+ void (QOPENGLF_APIENTRYP ProgramUniform3iv)(GLuint program, GLint location, GLsizei count, const GLint *value);
+ void (QOPENGLF_APIENTRYP ProgramUniform4iv)(GLuint program, GLint location, GLsizei count, const GLint *value);
+ void (QOPENGLF_APIENTRYP ProgramUniform1uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value);
+ void (QOPENGLF_APIENTRYP ProgramUniform2uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value);
+ void (QOPENGLF_APIENTRYP ProgramUniform3uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value);
+ void (QOPENGLF_APIENTRYP ProgramUniform4uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value);
+ void (QOPENGLF_APIENTRYP ProgramUniform1fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ProgramUniform2fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ProgramUniform3fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ProgramUniform4fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ProgramUniformMatrix2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ProgramUniformMatrix3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ProgramUniformMatrix4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ProgramUniformMatrix2x3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ProgramUniformMatrix3x2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ProgramUniformMatrix2x4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ProgramUniformMatrix4x2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ProgramUniformMatrix3x4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ProgramUniformMatrix4x3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void (QOPENGLF_APIENTRYP ValidateProgramPipeline)(GLuint pipeline);
+ void (QOPENGLF_APIENTRYP GetProgramPipelineInfoLog)(GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+ void (QOPENGLF_APIENTRYP BindImageTexture)(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);
+ void (QOPENGLF_APIENTRYP GetBooleani_v)(GLenum target, GLuint index, GLboolean *data);
+ void (QOPENGLF_APIENTRYP MemoryBarrierFunc)(GLbitfield barriers);
+ void (QOPENGLF_APIENTRYP MemoryBarrierByRegion)(GLbitfield barriers);
+ void (QOPENGLF_APIENTRYP TexStorage2DMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+ void (QOPENGLF_APIENTRYP GetMultisamplefv)(GLenum pname, GLuint index, GLfloat *val);
+ void (QOPENGLF_APIENTRYP SampleMaski)(GLuint maskNumber, GLbitfield mask);
+ void (QOPENGLF_APIENTRYP GetTexLevelParameteriv)(GLenum target, GLint level, GLenum pname, GLint *params);
+ void (QOPENGLF_APIENTRYP GetTexLevelParameterfv)(GLenum target, GLint level, GLenum pname, GLfloat *params);
+ void (QOPENGLF_APIENTRYP BindVertexBuffer)(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);
+ void (QOPENGLF_APIENTRYP VertexAttribFormat)(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);
+ void (QOPENGLF_APIENTRYP VertexAttribIFormat)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+ void (QOPENGLF_APIENTRYP VertexAttribBinding)(GLuint attribindex, GLuint bindingindex);
+ void (QOPENGLF_APIENTRYP VertexBindingDivisor)(GLuint bindingindex, GLuint divisor);
+};
+
+// GLES 3.0 and 3.1
+
+inline void QOpenGLExtraFunctions::glBeginQuery(GLenum target, GLuint id)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->BeginQuery(target, id);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glBeginTransformFeedback(GLenum primitiveMode)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->BeginTransformFeedback(primitiveMode);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glBindBufferBase(GLenum target, GLuint index, GLuint buffer)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->BindBufferBase(target, index, buffer);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->BindBufferRange(target, index, buffer, offset, size);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glBindSampler(GLuint unit, GLuint sampler)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->BindSampler(unit, sampler);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glBindTransformFeedback(GLenum target, GLuint id)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->BindTransformFeedback(target, id);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glBindVertexArray(GLuint array)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->BindVertexArray(array);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ClearBufferfi(buffer, drawbuffer, depth, stencil);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ClearBufferfv(buffer, drawbuffer, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ClearBufferiv(buffer, drawbuffer, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ClearBufferuiv(buffer, drawbuffer, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline GLenum QOpenGLExtraFunctions::glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ GLenum result = d->ClientWaitSync(sync, flags, timeout);
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline void QOpenGLExtraFunctions::glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * data)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->CompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->CompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->CopyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->CopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glDeleteQueries(GLsizei n, const GLuint * ids)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->DeleteQueries(n, ids);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glDeleteSamplers(GLsizei count, const GLuint * samplers)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->DeleteSamplers(count, samplers);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glDeleteSync(GLsync sync)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->DeleteSync(sync);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glDeleteTransformFeedbacks(GLsizei n, const GLuint * ids)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->DeleteTransformFeedbacks(n, ids);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glDeleteVertexArrays(GLsizei n, const GLuint * arrays)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->DeleteVertexArrays(n, arrays);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->DrawArraysInstanced(mode, first, count, instancecount);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glDrawBuffers(GLsizei n, const GLenum * bufs)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->DrawBuffers(n, bufs);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->DrawElementsInstanced(mode, count, type, indices, instancecount);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->DrawRangeElements(mode, start, end, count, type, indices);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glEndQuery(GLenum target)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->EndQuery(target);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glEndTransformFeedback()
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->EndTransformFeedback();
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline GLsync QOpenGLExtraFunctions::glFenceSync(GLenum condition, GLbitfield flags)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ GLsync result = d->FenceSync(condition, flags);
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline void QOpenGLExtraFunctions::glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->FlushMappedBufferRange(target, offset, length);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->FramebufferTextureLayer(target, attachment, texture, level, layer);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGenQueries(GLsizei n, GLuint* ids)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GenQueries(n, ids);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGenSamplers(GLsizei count, GLuint* samplers)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GenSamplers(count, samplers);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGenTransformFeedbacks(GLsizei n, GLuint* ids)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GenTransformFeedbacks(n, ids);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGenVertexArrays(GLsizei n, GLuint* arrays)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GenVertexArrays(n, arrays);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetActiveUniformBlockName(program, uniformBlockIndex, bufSize, length, uniformBlockName);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetActiveUniformBlockiv(program, uniformBlockIndex, pname, params);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint * uniformIndices, GLenum pname, GLint* params)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetActiveUniformsiv(program, uniformCount, uniformIndices, pname, params);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetBufferParameteri64v(target, pname, params);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetBufferPointerv(GLenum target, GLenum pname, void ** params)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetBufferPointerv(target, pname, params);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline GLint QOpenGLExtraFunctions::glGetFragDataLocation(GLuint program, const GLchar * name)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ GLint result = d->GetFragDataLocation(program, name);
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline void QOpenGLExtraFunctions::glGetInteger64i_v(GLenum target, GLuint index, GLint64* data)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetInteger64i_v(target, index, data);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetInteger64v(GLenum pname, GLint64* data)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetInteger64v(pname, data);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetIntegeri_v(GLenum target, GLuint index, GLint* data)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetIntegeri_v(target, index, data);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetInternalformativ(target, internalformat, pname, bufSize, params);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, void * binary)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetProgramBinary(program, bufSize, length, binaryFormat, binary);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetQueryObjectuiv(id, pname, params);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetQueryiv(GLenum target, GLenum pname, GLint* params)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetQueryiv(target, pname, params);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetSamplerParameterfv(sampler, pname, params);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetSamplerParameteriv(sampler, pname, params);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline const GLubyte * QOpenGLExtraFunctions::glGetStringi(GLenum name, GLuint index)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ const GLubyte * result = d->GetStringi(name, index);
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline void QOpenGLExtraFunctions::glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetSynciv(sync, pname, bufSize, length, values);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetTransformFeedbackVarying(program, index, bufSize, length, size, type, name);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline GLuint QOpenGLExtraFunctions::glGetUniformBlockIndex(GLuint program, const GLchar * uniformBlockName)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ GLuint result = d->GetUniformBlockIndex(program, uniformBlockName);
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline void QOpenGLExtraFunctions::glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar *const* uniformNames, GLuint* uniformIndices)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetUniformIndices(program, uniformCount, uniformNames, uniformIndices);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetUniformuiv(GLuint program, GLint location, GLuint* params)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetUniformuiv(program, location, params);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetVertexAttribIiv(index, pname, params);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetVertexAttribIuiv(index, pname, params);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum * attachments)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->InvalidateFramebuffer(target, numAttachments, attachments);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->InvalidateSubFramebuffer(target, numAttachments, attachments, x, y, width, height);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline GLboolean QOpenGLExtraFunctions::glIsQuery(GLuint id)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ GLboolean result = d->IsQuery(id);
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline GLboolean QOpenGLExtraFunctions::glIsSampler(GLuint sampler)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ GLboolean result = d->IsSampler(sampler);
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline GLboolean QOpenGLExtraFunctions::glIsSync(GLsync sync)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ GLboolean result = d->IsSync(sync);
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline GLboolean QOpenGLExtraFunctions::glIsTransformFeedback(GLuint id)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ GLboolean result = d->IsTransformFeedback(id);
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline GLboolean QOpenGLExtraFunctions::glIsVertexArray(GLuint array)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ GLboolean result = d->IsVertexArray(array);
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline void * QOpenGLExtraFunctions::glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ void *result = d->MapBufferRange(target, offset, length, access);
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline void QOpenGLExtraFunctions::glPauseTransformFeedback()
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->PauseTransformFeedback();
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramBinary(GLuint program, GLenum binaryFormat, const void * binary, GLsizei length)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramBinary(program, binaryFormat, binary, length);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramParameteri(GLuint program, GLenum pname, GLint value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramParameteri(program, pname, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glReadBuffer(GLenum src)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ReadBuffer(src);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->RenderbufferStorageMultisample(target, samples, internalformat, width, height);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glResumeTransformFeedback()
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ResumeTransformFeedback();
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->SamplerParameterf(sampler, pname, param);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat * param)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->SamplerParameterfv(sampler, pname, param);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glSamplerParameteri(GLuint sampler, GLenum pname, GLint param)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->SamplerParameteri(sampler, pname, param);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint * param)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->SamplerParameteriv(sampler, pname, param);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->TexStorage2D(target, levels, internalformat, width, height);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->TexStorage3D(target, levels, internalformat, width, height, depth);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->TransformFeedbackVaryings(program, count, varyings, bufferMode);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glUniform1ui(GLint location, GLuint v0)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->Uniform1ui(location, v0);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glUniform1uiv(GLint location, GLsizei count, const GLuint * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->Uniform1uiv(location, count, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glUniform2ui(GLint location, GLuint v0, GLuint v1)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->Uniform2ui(location, v0, v1);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glUniform2uiv(GLint location, GLsizei count, const GLuint * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->Uniform2uiv(location, count, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->Uniform3ui(location, v0, v1, v2);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glUniform3uiv(GLint location, GLsizei count, const GLuint * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->Uniform3uiv(location, count, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->Uniform4ui(location, v0, v1, v2, v3);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glUniform4uiv(GLint location, GLsizei count, const GLuint * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->Uniform4uiv(location, count, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->UniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->UniformMatrix2x3fv(location, count, transpose, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->UniformMatrix2x4fv(location, count, transpose, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->UniformMatrix3x2fv(location, count, transpose, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->UniformMatrix3x4fv(location, count, transpose, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->UniformMatrix4x2fv(location, count, transpose, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->UniformMatrix4x3fv(location, count, transpose, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline GLboolean QOpenGLExtraFunctions::glUnmapBuffer(GLenum target)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ GLboolean result = d->UnmapBuffer(target);
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline void QOpenGLExtraFunctions::glVertexAttribDivisor(GLuint index, GLuint divisor)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->VertexAttribDivisor(index, divisor);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->VertexAttribI4i(index, x, y, z, w);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glVertexAttribI4iv(GLuint index, const GLint * v)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->VertexAttribI4iv(index, v);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->VertexAttribI4ui(index, x, y, z, w);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glVertexAttribI4uiv(GLuint index, const GLuint * v)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->VertexAttribI4uiv(index, v);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->VertexAttribIPointer(index, size, type, stride, pointer);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->WaitSync(sync, flags, timeout);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glActiveShaderProgram(GLuint pipeline, GLuint program)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ActiveShaderProgram(pipeline, program);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glBindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->BindImageTexture(unit, texture, level, layered, layer, access, format);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glBindProgramPipeline(GLuint pipeline)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->BindProgramPipeline(pipeline);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glBindVertexBuffer(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->BindVertexBuffer(bindingindex, buffer, offset, stride);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline GLuint QOpenGLExtraFunctions::glCreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const* strings)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ GLuint result = d->CreateShaderProgramv(type, count, strings);
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline void QOpenGLExtraFunctions::glDeleteProgramPipelines(GLsizei n, const GLuint * pipelines)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->DeleteProgramPipelines(n, pipelines);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->DispatchCompute(num_groups_x, num_groups_y, num_groups_z);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glDispatchComputeIndirect(GLintptr indirect)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->DispatchComputeIndirect(indirect);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glDrawArraysIndirect(GLenum mode, const void * indirect)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->DrawArraysIndirect(mode, indirect);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glDrawElementsIndirect(GLenum mode, GLenum type, const void * indirect)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->DrawElementsIndirect(mode, type, indirect);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glFramebufferParameteri(GLenum target, GLenum pname, GLint param)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->FramebufferParameteri(target, pname, param);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGenProgramPipelines(GLsizei n, GLuint* pipelines)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GenProgramPipelines(n, pipelines);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetBooleani_v(GLenum target, GLuint index, GLboolean* data)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetBooleani_v(target, index, data);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetFramebufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetFramebufferParameteriv(target, pname, params);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetMultisamplefv(GLenum pname, GLuint index, GLfloat* val)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetMultisamplefv(pname, index, val);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, GLint* params)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetProgramInterfaceiv(program, programInterface, pname, params);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar* infoLog)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetProgramPipelineInfoLog(pipeline, bufSize, length, infoLog);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint* params)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetProgramPipelineiv(pipeline, pname, params);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline GLuint QOpenGLExtraFunctions::glGetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar * name)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ GLuint result = d->GetProgramResourceIndex(program, programInterface, name);
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline GLint QOpenGLExtraFunctions::glGetProgramResourceLocation(GLuint program, GLenum programInterface, const GLchar * name)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ GLint result = d->GetProgramResourceLocation(program, programInterface, name);
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline void QOpenGLExtraFunctions::glGetProgramResourceName(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, GLchar* name)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetProgramResourceName(program, programInterface, index, bufSize, length, name);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei bufSize, GLsizei* length, GLint* params)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetProgramResourceiv(program, programInterface, index, propCount, props, bufSize, length, params);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat* params)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetTexLevelParameterfv(target, level, pname, params);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->GetTexLevelParameteriv(target, level, pname, params);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline GLboolean QOpenGLExtraFunctions::glIsProgramPipeline(GLuint pipeline)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ GLboolean result = d->IsProgramPipeline(pipeline);
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline void QOpenGLExtraFunctions::glMemoryBarrier(GLbitfield barriers)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->MemoryBarrierFunc(barriers);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glMemoryBarrierByRegion(GLbitfield barriers)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->MemoryBarrierByRegion(barriers);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniform1f(GLuint program, GLint location, GLfloat v0)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniform1f(program, location, v0);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniform1fv(GLuint program, GLint location, GLsizei count, const GLfloat * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniform1fv(program, location, count, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniform1i(GLuint program, GLint location, GLint v0)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniform1i(program, location, v0);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniform1iv(GLuint program, GLint location, GLsizei count, const GLint * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniform1iv(program, location, count, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniform1ui(GLuint program, GLint location, GLuint v0)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniform1ui(program, location, v0);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniform1uiv(GLuint program, GLint location, GLsizei count, const GLuint * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniform1uiv(program, location, count, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniform2f(program, location, v0, v1);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniform2fv(GLuint program, GLint location, GLsizei count, const GLfloat * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniform2fv(program, location, count, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniform2i(program, location, v0, v1);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniform2iv(GLuint program, GLint location, GLsizei count, const GLint * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniform2iv(program, location, count, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniform2ui(program, location, v0, v1);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniform2uiv(GLuint program, GLint location, GLsizei count, const GLuint * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniform2uiv(program, location, count, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniform3f(program, location, v0, v1, v2);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniform3fv(GLuint program, GLint location, GLsizei count, const GLfloat * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniform3fv(program, location, count, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniform3i(program, location, v0, v1, v2);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniform3iv(GLuint program, GLint location, GLsizei count, const GLint * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniform3iv(program, location, count, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniform3ui(program, location, v0, v1, v2);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniform3uiv(GLuint program, GLint location, GLsizei count, const GLuint * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniform3uiv(program, location, count, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniform4f(program, location, v0, v1, v2, v3);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniform4fv(GLuint program, GLint location, GLsizei count, const GLfloat * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniform4fv(program, location, count, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniform4i(program, location, v0, v1, v2, v3);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniform4iv(GLuint program, GLint location, GLsizei count, const GLint * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniform4iv(program, location, count, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniform4ui(program, location, v0, v1, v2, v3);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniform4uiv(GLuint program, GLint location, GLsizei count, const GLuint * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniform4uiv(program, location, count, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniformMatrix2fv(program, location, count, transpose, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniformMatrix2x3fv(program, location, count, transpose, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniformMatrix2x4fv(program, location, count, transpose, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniformMatrix3fv(program, location, count, transpose, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniformMatrix3x2fv(program, location, count, transpose, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniformMatrix3x4fv(program, location, count, transpose, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniformMatrix4fv(program, location, count, transpose, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniformMatrix4x2fv(program, location, count, transpose, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ProgramUniformMatrix4x3fv(program, location, count, transpose, value);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glSampleMaski(GLuint maskNumber, GLbitfield mask)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->SampleMaski(maskNumber, mask);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glTexStorage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->TexStorage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->UseProgramStages(pipeline, stages, program);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glValidateProgramPipeline(GLuint pipeline)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->ValidateProgramPipeline(pipeline);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glVertexAttribBinding(GLuint attribindex, GLuint bindingindex)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->VertexAttribBinding(attribindex, bindingindex);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glVertexAttribFormat(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->VertexAttribFormat(attribindex, size, type, normalized, relativeoffset);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glVertexAttribIFormat(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->VertexAttribIFormat(attribindex, size, type, relativeoffset);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtraFunctions::glVertexBindingDivisor(GLuint bindingindex, GLuint divisor)
+{
+ Q_D(QOpenGLExtraFunctions);
+ Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d));
+ d->VertexBindingDivisor(bindingindex, divisor);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_OPENGL
+
+#endif
diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp
index 1cf748d15f..5184283a31 100644
--- a/src/gui/opengl/qopenglframebufferobject.cpp
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -167,7 +167,7 @@ void QOpenGLFramebufferObjectFormat::detach()
the format of an OpenGL framebuffer object.
By default the format specifies a non-multisample framebuffer object with no
- attachments, texture target \c GL_TEXTURE_2D, and internal format \c GL_RGBA8.
+ depth/stencil attachments, texture target \c GL_TEXTURE_2D, and internal format \c GL_RGBA8.
On OpenGL/ES systems, the default internal format is \c GL_RGBA.
\sa samples(), attachment(), internalTextureFormat()
@@ -437,10 +437,10 @@ namespace
}
}
-void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSize &sz,
- QOpenGLFramebufferObject::Attachment attachment,
- GLenum texture_target, GLenum internal_format,
- GLint samples, bool mipmap)
+void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSize &size,
+ QOpenGLFramebufferObject::Attachment attachment,
+ GLenum texture_target, GLenum internal_format,
+ GLint samples, bool mipmap)
{
QOpenGLContext *ctx = QOpenGLContext::currentContext();
@@ -459,9 +459,13 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
samples = qBound(0, int(samples), int(maxSamples));
}
+ colorAttachments.append(ColorAttachment(size, internal_format));
+
+ dsSize = size;
+
samples = qMax(0, samples);
requestedSamples = samples;
- size = sz;
+
target = texture_target;
QT_RESET_GLERROR(); // reset error state
@@ -472,64 +476,30 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
QOpenGLContextPrivate::get(ctx)->qgl_current_fbo_invalid = true;
- GLuint color_buffer = 0;
-
QT_CHECK_GLERROR();
- // init texture
- if (samples == 0) {
- initTexture(texture_target, internal_format, size, mipmap);
- } else {
- GLenum storageFormat = internal_format;
- // ES requires a sized format. The older desktop extension does not. Correct the format on ES.
- if (ctx->isOpenGLES() && internal_format == GL_RGBA) {
- if (funcs.hasOpenGLExtension(QOpenGLExtensions::Sized8Formats))
- storageFormat = GL_RGBA8;
- else
- storageFormat = GL_RGBA4;
- }
-
- mipmap = false;
- funcs.glGenRenderbuffers(1, &color_buffer);
- funcs.glBindRenderbuffer(GL_RENDERBUFFER, color_buffer);
- funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storageFormat, size.width(), size.height());
- funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- GL_RENDERBUFFER, color_buffer);
- QT_CHECK_GLERROR();
- valid = checkFramebufferStatus(ctx);
-
- if (valid) {
- // Query the actual number of samples. This can be greater than the requested
- // value since the typically supported values are 0, 4, 8, ..., and the
- // requests are mapped to the next supported value.
- funcs.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
- color_buffer_guard = new QOpenGLSharedResourceGuard(ctx, color_buffer, freeRenderbufferFunc);
- }
- }
format.setTextureTarget(target);
- format.setSamples(int(samples));
format.setInternalTextureFormat(internal_format);
format.setMipmap(mipmap);
- initAttachments(ctx, attachment);
+ if (samples == 0)
+ initTexture(0);
+ else
+ initColorBuffer(0, &samples);
+
+ format.setSamples(int(samples));
- if (valid) {
+ initDepthStencilAttachments(ctx, attachment);
+
+ if (valid)
fbo_guard = new QOpenGLSharedResourceGuard(ctx, fbo, freeFramebufferFunc);
- } else {
- if (color_buffer_guard) {
- color_buffer_guard->free();
- color_buffer_guard = 0;
- } else if (texture_guard) {
- texture_guard->free();
- texture_guard = 0;
- }
+ else
funcs.glDeleteFramebuffers(1, &fbo);
- }
+
QT_CHECK_GLERROR();
}
-void QOpenGLFramebufferObjectPrivate::initTexture(GLenum target, GLenum internal_format,
- const QSize &size, bool mipmap)
+void QOpenGLFramebufferObjectPrivate::initTexture(int idx)
{
QOpenGLContext *ctx = QOpenGLContext::currentContext();
GLuint texture = 0;
@@ -542,37 +512,76 @@ void QOpenGLFramebufferObjectPrivate::initTexture(GLenum target, GLenum internal
funcs.glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
funcs.glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ ColorAttachment &color(colorAttachments[idx]);
+
GLuint pixelType = GL_UNSIGNED_BYTE;
- if (internal_format == GL_RGB10_A2 || internal_format == GL_RGB10)
+ if (color.internalFormat == GL_RGB10_A2 || color.internalFormat == GL_RGB10)
pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
- funcs.glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0,
+ funcs.glTexImage2D(target, 0, color.internalFormat, color.size.width(), color.size.height(), 0,
GL_RGBA, pixelType, NULL);
- if (mipmap) {
- int width = size.width();
- int height = size.height();
+ if (format.mipmap()) {
+ int width = color.size.width();
+ int height = color.size.height();
int level = 0;
while (width > 1 || height > 1) {
width = qMax(1, width >> 1);
height = qMax(1, height >> 1);
++level;
- funcs.glTexImage2D(target, level, internal_format, width, height, 0,
+ funcs.glTexImage2D(target, level, color.internalFormat, width, height, 0,
GL_RGBA, pixelType, NULL);
}
}
- funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + idx,
target, texture, 0);
QT_CHECK_GLERROR();
funcs.glBindTexture(target, 0);
valid = checkFramebufferStatus(ctx);
- if (valid)
- texture_guard = new QOpenGLSharedResourceGuard(ctx, texture, freeTextureFunc);
- else
+ if (valid) {
+ color.guard = new QOpenGLSharedResourceGuard(ctx, texture, freeTextureFunc);
+ } else {
funcs.glDeleteTextures(1, &texture);
+ }
+}
+
+void QOpenGLFramebufferObjectPrivate::initColorBuffer(int idx, GLint *samples)
+{
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ GLuint color_buffer = 0;
+
+ ColorAttachment &color(colorAttachments[idx]);
+
+ GLenum storageFormat = color.internalFormat;
+ // ES requires a sized format. The older desktop extension does not. Correct the format on ES.
+ if (ctx->isOpenGLES() && color.internalFormat == GL_RGBA) {
+ if (funcs.hasOpenGLExtension(QOpenGLExtensions::Sized8Formats))
+ storageFormat = GL_RGBA8;
+ else
+ storageFormat = GL_RGBA4;
+ }
+
+ funcs.glGenRenderbuffers(1, &color_buffer);
+ funcs.glBindRenderbuffer(GL_RENDERBUFFER, color_buffer);
+ funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, *samples, storageFormat, color.size.width(), color.size.height());
+ funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + idx,
+ GL_RENDERBUFFER, color_buffer);
+
+ QT_CHECK_GLERROR();
+ valid = checkFramebufferStatus(ctx);
+ if (valid) {
+ // Query the actual number of samples. This can be greater than the requested
+ // value since the typically supported values are 0, 4, 8, ..., and the
+ // requests are mapped to the next supported value.
+ funcs.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, samples);
+ color.guard = new QOpenGLSharedResourceGuard(ctx, color_buffer, freeRenderbufferFunc);
+ } else {
+ funcs.glDeleteRenderbuffers(1, &color_buffer);
+ }
}
-void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpenGLFramebufferObject::Attachment attachment)
+void QOpenGLFramebufferObjectPrivate::initDepthStencilAttachments(QOpenGLContext *ctx,
+ QOpenGLFramebufferObject::Attachment attachment)
{
// Use the same sample count for all attachments. format.samples() already contains
// the actual number of samples for the color attachment and is not suitable. Use
@@ -609,10 +618,10 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen
Q_ASSERT(funcs.glIsRenderbuffer(depth_buffer));
if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample))
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
- GL_DEPTH24_STENCIL8, size.width(), size.height());
+ GL_DEPTH24_STENCIL8, dsSize.width(), dsSize.height());
else
funcs.glRenderbufferStorage(GL_RENDERBUFFER,
- GL_DEPTH24_STENCIL8, size.width(), size.height());
+ GL_DEPTH24_STENCIL8, dsSize.width(), dsSize.height());
stencil_buffer = depth_buffer;
funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
@@ -637,25 +646,25 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen
if (ctx->isOpenGLES()) {
if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24))
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
- GL_DEPTH_COMPONENT24, size.width(), size.height());
+ GL_DEPTH_COMPONENT24, dsSize.width(), dsSize.height());
else
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
- GL_DEPTH_COMPONENT16, size.width(), size.height());
+ GL_DEPTH_COMPONENT16, dsSize.width(), dsSize.height());
} else {
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
- GL_DEPTH_COMPONENT, size.width(), size.height());
+ GL_DEPTH_COMPONENT, dsSize.width(), dsSize.height());
}
} else {
if (ctx->isOpenGLES()) {
if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) {
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24,
- size.width(), size.height());
+ dsSize.width(), dsSize.height());
} else {
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
- size.width(), size.height());
+ dsSize.width(), dsSize.height());
}
} else {
- funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height());
+ funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, dsSize.width(), dsSize.height());
}
}
funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
@@ -679,9 +688,9 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen
#endif
if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample))
- funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storage, size.width(), size.height());
+ funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storage, dsSize.width(), dsSize.height());
else
- funcs.glRenderbufferStorage(GL_RENDERBUFFER, storage, size.width(), size.height());
+ funcs.glRenderbufferStorage(GL_RENDERBUFFER, storage, dsSize.width(), dsSize.height());
funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, stencil_buffer);
@@ -757,6 +766,11 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen
format, and will be bound to the \c GL_COLOR_ATTACHMENT0
attachment in the framebuffer object.
+ Multiple render targets are also supported, in case the OpenGL
+ implementation supports this. Here there will be multiple textures (or, in
+ case of multisampling, renderbuffers) present and each of them will get
+ attached to \c GL_COLOR_ATTACHMENT0, \c 1, \c 2, ...
+
If you want to use a framebuffer object with multisampling enabled
as a texture, you first need to copy from it to a regular framebuffer
object using QOpenGLContext::blitFramebuffer().
@@ -786,6 +800,16 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen
\sa attachment()
*/
+static inline GLenum effectiveInternalFormat(GLenum internalFormat)
+{
+ if (!internalFormat)
+#ifdef QT_OPENGL_ES_2
+ internalFormat = GL_RGBA;
+#else
+ internalFormat = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8;
+#endif
+ return internalFormat;
+}
/*! \fn QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, GLenum target)
@@ -815,13 +839,7 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, GLenum tar
: d_ptr(new QOpenGLFramebufferObjectPrivate)
{
Q_D(QOpenGLFramebufferObject);
- d->init(this, size, NoAttachment, target,
-#ifndef QT_OPENGL_ES_2
- QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8
-#else
- GL_RGBA
-#endif
- );
+ d->init(this, size, NoAttachment, target, effectiveInternalFormat(0));
}
/*! \overload
@@ -835,13 +853,7 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, GLenum
: d_ptr(new QOpenGLFramebufferObjectPrivate)
{
Q_D(QOpenGLFramebufferObject);
- d->init(this, QSize(width, height), NoAttachment, target,
-#ifndef QT_OPENGL_ES_2
- QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8
-#else
- GL_RGBA
-#endif
- );
+ d->init(this, QSize(width, height), NoAttachment, target, effectiveInternalFormat(0));
}
/*! \overload
@@ -878,7 +890,7 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, const
buffer of the given \a width and \a height.
The \a attachment parameter describes the depth/stencil buffer
- configuration, \a target the texture target and \a internal_format
+ configuration, \a target the texture target and \a internalFormat
the internal texture format. The default texture target is \c
GL_TEXTURE_2D, while the default internal format is \c GL_RGBA8
for desktop OpenGL and \c GL_RGBA for OpenGL/ES.
@@ -886,17 +898,11 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, const
\sa size(), texture(), attachment()
*/
QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, Attachment attachment,
- GLenum target, GLenum internal_format)
+ GLenum target, GLenum internalFormat)
: d_ptr(new QOpenGLFramebufferObjectPrivate)
{
Q_D(QOpenGLFramebufferObject);
- if (!internal_format)
-#ifdef QT_OPENGL_ES_2
- internal_format = GL_RGBA;
-#else
- internal_format = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8;
-#endif
- d->init(this, QSize(width, height), attachment, target, internal_format);
+ d->init(this, QSize(width, height), attachment, target, effectiveInternalFormat(internalFormat));
}
/*! \overload
@@ -905,7 +911,7 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, Attach
buffer of the given \a size.
The \a attachment parameter describes the depth/stencil buffer
- configuration, \a target the texture target and \a internal_format
+ configuration, \a target the texture target and \a internalFormat
the internal texture format. The default texture target is \c
GL_TEXTURE_2D, while the default internal format is \c GL_RGBA8
for desktop OpenGL and \c GL_RGBA for OpenGL/ES.
@@ -913,17 +919,11 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, Attach
\sa size(), texture(), attachment()
*/
QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, Attachment attachment,
- GLenum target, GLenum internal_format)
+ GLenum target, GLenum internalFormat)
: d_ptr(new QOpenGLFramebufferObjectPrivate)
{
Q_D(QOpenGLFramebufferObject);
- if (!internal_format)
-#ifdef QT_OPENGL_ES_2
- internal_format = GL_RGBA;
-#else
- internal_format = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8;
-#endif
- d->init(this, size, attachment, target, internal_format);
+ d->init(this, size, attachment, target, effectiveInternalFormat(internalFormat));
}
/*!
@@ -937,10 +937,12 @@ QOpenGLFramebufferObject::~QOpenGLFramebufferObject()
if (isBound())
release();
- if (d->texture_guard)
- d->texture_guard->free();
- if (d->color_buffer_guard)
- d->color_buffer_guard->free();
+ foreach (const QOpenGLFramebufferObjectPrivate::ColorAttachment &color, d->colorAttachments) {
+ if (color.guard)
+ color.guard->free();
+ }
+ d->colorAttachments.clear();
+
if (d->depth_buffer_guard)
d->depth_buffer_guard->free();
if (d->stencil_buffer_guard && d->stencil_buffer_guard != d->depth_buffer_guard)
@@ -950,6 +952,70 @@ QOpenGLFramebufferObject::~QOpenGLFramebufferObject()
}
/*!
+ Creates and attaches an additional texture or renderbuffer of \a size width
+ and height.
+
+ There is always an attachment at GL_COLOR_ATTACHMENT0. Call this function
+ to set up additional attachments at GL_COLOR_ATTACHMENT1,
+ GL_COLOR_ATTACHMENT2, ...
+
+ When \a internalFormat is not \c 0, it specifies the internal format of the
+ texture or renderbuffer. Otherwise a default of GL_RGBA or GL_RGBA8 is
+ used.
+
+ \note This is only functional when multiple render targets are supported by
+ the OpenGL implementation. When that is not the case, the function will not
+ add any additional color attachments. Call
+ QOpenGLFunctions::hasOpenGLFeature() with
+ QOpenGLFunctions::MultipleRenderTargets at runtime to check if MRT is
+ supported.
+
+ \note The internal format of the color attachments may differ but there may
+ be limitations on the supported combinations, depending on the drivers.
+
+ \note The size of the color attachments may differ but rendering is limited
+ to the area that fits all the attachments, according to the OpenGL
+ specification. Some drivers may not be fully conformant in this respect,
+ however.
+
+ \since 5.6
+ */
+void QOpenGLFramebufferObject::addColorAttachment(const QSize &size, GLenum internalFormat)
+{
+ Q_D(QOpenGLFramebufferObject);
+
+ if (!QOpenGLContext::currentContext()->functions()->hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets)) {
+ qWarning("Multiple render targets not supported, ignoring extra color attachment request");
+ return;
+ }
+
+ QOpenGLFramebufferObjectPrivate::ColorAttachment color(size, effectiveInternalFormat(internalFormat));
+ d->colorAttachments.append(color);
+ const int idx = d->colorAttachments.count() - 1;
+
+ if (d->requestedSamples == 0) {
+ d->initTexture(idx);
+ } else {
+ GLint samples = d->requestedSamples;
+ d->initColorBuffer(idx, &samples);
+ }
+}
+
+/*! \overload
+
+ Creates and attaches an additional texture or renderbuffer of size \a width and \a height.
+
+ When \a internalFormat is not \c 0, it specifies the internal format of the texture or
+ renderbuffer. Otherwise a default of GL_RGBA or GL_RGBA8 is used.
+
+ \since 5.6
+ */
+void QOpenGLFramebufferObject::addColorAttachment(int width, int height, GLenum internalFormat)
+{
+ addColorAttachment(QSize(width, height), internalFormat);
+}
+
+/*!
\fn bool QOpenGLFramebufferObject::isValid() const
Returns \c true if the framebuffer object is valid.
@@ -1003,10 +1069,14 @@ bool QOpenGLFramebufferObject::bind()
QOpenGLContextPrivate::get(current)->qgl_current_fbo_invalid = true;
- if (d->texture_guard || d->format.samples() != 0)
- d->valid = d->checkFramebufferStatus(current);
- else
- d->initTexture(d->format.textureTarget(), d->format.internalTextureFormat(), d->size, d->format.mipmap());
+ if (d->format.samples() == 0) {
+ // Create new textures to replace the ones stolen via takeTexture().
+ for (int i = 0; i < d->colorAttachments.count(); ++i) {
+ if (!d->colorAttachments[i].guard)
+ d->initTexture(i);
+ }
+ }
+
return d->valid;
}
@@ -1053,12 +1123,36 @@ bool QOpenGLFramebufferObject::release()
If a multisample framebuffer object is used then the value returned
from this function will be invalid.
- \sa takeTexture()
+ When multiple textures are attached, the return value is the ID of
+ the first one.
+
+ \sa takeTexture(), textures()
*/
GLuint QOpenGLFramebufferObject::texture() const
{
Q_D(const QOpenGLFramebufferObject);
- return d->texture_guard ? d->texture_guard->id() : 0;
+ return d->colorAttachments[0].guard ? d->colorAttachments[0].guard->id() : 0;
+}
+
+/*!
+ Returns the texture id for all attached textures.
+
+ If a multisample framebuffer object is used, then an empty vector is returned.
+
+ \since 5.6
+
+ \sa takeTexture(), texture()
+*/
+QVector<GLuint> QOpenGLFramebufferObject::textures() const
+{
+ Q_D(const QOpenGLFramebufferObject);
+ QVector<GLuint> ids;
+ if (d->format.samples() != 0)
+ return ids;
+ ids.reserve(d->colorAttachments.count());
+ foreach (const QOpenGLFramebufferObjectPrivate::ColorAttachment &color, d->colorAttachments)
+ ids.append(color.guard ? color.guard->id() : 0);
+ return ids;
}
/*!
@@ -1081,30 +1175,68 @@ GLuint QOpenGLFramebufferObject::texture() const
*/
GLuint QOpenGLFramebufferObject::takeTexture()
{
+ return takeTexture(0);
+}
+
+/*! \overload
+
+ Returns the texture id for the texture attached to the color attachment of
+ index \a colorAttachmentIndex of this framebuffer object. The ownership of
+ the texture is transferred to the caller.
+
+ When \a colorAttachmentIndex is \c 0, the behavior is identical to the
+ parameter-less variant of this function.
+
+ If the framebuffer object is currently bound, an implicit release()
+ will be done. During the next call to bind() a new texture will be
+ created.
+
+ If a multisample framebuffer object is used, then there is no
+ texture and the return value from this function will be invalid.
+ Similarly, incomplete framebuffer objects will also return 0.
+
+ \since 5.6
+ */
+GLuint QOpenGLFramebufferObject::takeTexture(int colorAttachmentIndex)
+{
Q_D(QOpenGLFramebufferObject);
GLuint id = 0;
- if (isValid() && d->texture_guard) {
+ if (isValid() && d->format.samples() == 0 && d->colorAttachments.count() > colorAttachmentIndex) {
QOpenGLContext *current = QOpenGLContext::currentContext();
if (current && current->shareGroup() == d->fbo_guard->group() && isBound())
release();
- id = d->texture_guard->id();
+ id = d->colorAttachments[colorAttachmentIndex].guard ? d->colorAttachments[colorAttachmentIndex].guard->id() : 0;
// Do not call free() on texture_guard, just null it out.
// This way the texture will not be deleted when the guard is destroyed.
- d->texture_guard = 0;
+ d->colorAttachments[colorAttachmentIndex].guard = 0;
}
return id;
}
/*!
- \fn QSize QOpenGLFramebufferObject::size() const
+ \return the size of the color and depth/stencil attachments attached to
+ this framebuffer object.
+*/
+QSize QOpenGLFramebufferObject::size() const
+{
+ Q_D(const QOpenGLFramebufferObject);
+ return d->dsSize;
+}
- Returns the size of the texture attached to this framebuffer
+/*!
+ \return the sizes of all color attachments attached to this framebuffer
object.
+
+ \since 5.6
*/
-QSize QOpenGLFramebufferObject::size() const
+QVector<QSize> QOpenGLFramebufferObject::sizes() const
{
Q_D(const QOpenGLFramebufferObject);
- return d->size;
+ QVector<QSize> sz;
+ sz.reserve(d->colorAttachments.size());
+ foreach (const QOpenGLFramebufferObjectPrivate::ColorAttachment &color, d->colorAttachments)
+ sz.append(color.size);
+ return sz;
}
/*!
@@ -1243,6 +1375,37 @@ Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format,
QImage QOpenGLFramebufferObject::toImage(bool flipped) const
{
+ return toImage(flipped, 0);
+}
+
+/*!
+ \fn QImage QOpenGLFramebufferObject::toImage() const
+ \overload
+
+ Returns the contents of this framebuffer object as a QImage. This method flips
+ the image from OpenGL coordinates to raster coordinates.
+*/
+// ### Qt 6: Remove this method and make it a default argument instead.
+QImage QOpenGLFramebufferObject::toImage() const
+{
+ return toImage(true, 0);
+}
+
+/*! \overload
+
+ Returns the contents of the color attachment of index \a
+ colorAttachmentIndex of this framebuffer object as a QImage. This method
+ flips the image from OpenGL coordinates to raster coordinates when \a
+ flipped is set to \c true.
+
+ \note This overload is only fully functional when multiple render targets are
+ supported by the OpenGL implementation. When that is not the case, only one
+ color attachment will be set up.
+
+ \since 5.6
+*/
+QImage QOpenGLFramebufferObject::toImage(bool flipped, int colorAttachmentIndex) const
+{
Q_D(const QOpenGLFramebufferObject);
if (!d->valid)
return QImage();
@@ -1253,6 +1416,11 @@ QImage QOpenGLFramebufferObject::toImage(bool flipped) const
return QImage();
}
+ if (d->colorAttachments.count() <= colorAttachmentIndex) {
+ qWarning("QOpenGLFramebufferObject::toImage() called for missing color attachment");
+ return QImage();
+ }
+
GLuint prevFbo = 0;
ctx->functions()->glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint *) &prevFbo);
@@ -1260,16 +1428,33 @@ QImage QOpenGLFramebufferObject::toImage(bool flipped) const
const_cast<QOpenGLFramebufferObject *>(this)->bind();
QImage image;
+ QOpenGLExtraFunctions *extraFuncs = ctx->extraFunctions();
// qt_gl_read_framebuffer doesn't work on a multisample FBO
if (format().samples() != 0) {
- QOpenGLFramebufferObject temp(size(), QOpenGLFramebufferObjectFormat());
-
QRect rect(QPoint(0, 0), size());
- blitFramebuffer(&temp, rect, const_cast<QOpenGLFramebufferObject *>(this), rect);
-
- image = temp.toImage(flipped);
+ if (extraFuncs->hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets)) {
+ QOpenGLFramebufferObject temp(d->colorAttachments[colorAttachmentIndex].size, QOpenGLFramebufferObjectFormat());
+ blitFramebuffer(&temp, rect, const_cast<QOpenGLFramebufferObject *>(this), rect,
+ GL_COLOR_BUFFER_BIT, GL_NEAREST,
+ colorAttachmentIndex, 0);
+ image = temp.toImage(flipped);
+ } else {
+ QOpenGLFramebufferObject temp(size(), QOpenGLFramebufferObjectFormat());
+ blitFramebuffer(&temp, rect, const_cast<QOpenGLFramebufferObject *>(this), rect);
+ image = temp.toImage(flipped);
+ }
} else {
- image = qt_gl_read_framebuffer(d->size, format().internalTextureFormat(), true, flipped);
+ if (extraFuncs->hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets)) {
+ extraFuncs->glReadBuffer(GL_COLOR_ATTACHMENT0 + colorAttachmentIndex);
+ image = qt_gl_read_framebuffer(d->colorAttachments[colorAttachmentIndex].size,
+ d->colorAttachments[colorAttachmentIndex].internalFormat,
+ true, flipped);
+ extraFuncs->glReadBuffer(GL_COLOR_ATTACHMENT0);
+ } else {
+ image = qt_gl_read_framebuffer(d->colorAttachments[0].size,
+ d->colorAttachments[0].internalFormat,
+ true, flipped);
+ }
}
if (prevFbo != d->fbo())
@@ -1279,19 +1464,6 @@ QImage QOpenGLFramebufferObject::toImage(bool flipped) const
}
/*!
- \fn QImage QOpenGLFramebufferObject::toImage() const
- \overload
-
- Returns the contents of this framebuffer object as a QImage. This method flips
- the image from OpenGL coordinates to raster coordinates.
-*/
-// ### Qt 6: Remove this method and make it a default argument instead.
-QImage QOpenGLFramebufferObject::toImage() const
-{
- return toImage(true);
-}
-
-/*!
\fn bool QOpenGLFramebufferObject::bindDefault()
Switches rendering back to the default, windowing system provided
@@ -1377,7 +1549,7 @@ void QOpenGLFramebufferObject::setAttachment(QOpenGLFramebufferObject::Attachmen
#endif
d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, d->fbo());
QOpenGLContextPrivate::get(current)->qgl_current_fbo_invalid = true;
- d->initAttachments(current, attachment);
+ d->initDepthStencilAttachments(current, attachment);
}
/*!
@@ -1439,6 +1611,18 @@ void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target,
buffers, filter);
}
+/*! \overload
+ *
+ Convenience overload to blit between two framebuffer objects.
+*/
+void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, const QRect &targetRect,
+ QOpenGLFramebufferObject *source, const QRect &sourceRect,
+ GLbitfield buffers,
+ GLenum filter)
+{
+ blitFramebuffer(target, targetRect, source, sourceRect, buffers, filter, 0, 0);
+}
+
/*!
Blits from the \a sourceRect rectangle in the \a source framebuffer
object to the \a targetRect rectangle in the \a target framebuffer object.
@@ -1467,12 +1651,18 @@ void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target,
\note The scissor test will restrict the blit area if enabled.
+ When multiple render targets are in use, \a readColorAttachmentIndex and \a
+ drawColorAttachmentIndex specify the index of the color attachments in the
+ source and destination framebuffers.
+
\sa hasOpenGLFramebufferBlit()
*/
void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, const QRect &targetRect,
- QOpenGLFramebufferObject *source, const QRect &sourceRect,
- GLbitfield buffers,
- GLenum filter)
+ QOpenGLFramebufferObject *source, const QRect &sourceRect,
+ GLbitfield buffers,
+ GLenum filter,
+ int readColorAttachmentIndex,
+ int drawColorAttachmentIndex)
{
QOpenGLContext *ctx = QOpenGLContext::currentContext();
if (!ctx)
@@ -1500,10 +1690,21 @@ void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target,
extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, source ? source->handle() : defaultFboId);
extensions.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, target ? target->handle() : defaultFboId);
+ if (extensions.hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets)) {
+ extensions.glReadBuffer(GL_COLOR_ATTACHMENT0 + readColorAttachmentIndex);
+ if (target) {
+ GLenum drawBuf = GL_COLOR_ATTACHMENT0 + drawColorAttachmentIndex;
+ extensions.glDrawBuffers(1, &drawBuf);
+ }
+ }
+
extensions.glBlitFramebuffer(sx0, sy0, sx1, sy1,
tx0, ty0, tx1, ty1,
buffers, filter);
+ if (extensions.hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets))
+ extensions.glReadBuffer(GL_COLOR_ATTACHMENT0);
+
ctx->functions()->glBindFramebuffer(GL_FRAMEBUFFER, prevFbo); // sets both READ and DRAW
}
diff --git a/src/gui/opengl/qopenglframebufferobject.h b/src/gui/opengl/qopenglframebufferobject.h
index 4ce0ee26cb..cead4ad10f 100644
--- a/src/gui/opengl/qopenglframebufferobject.h
+++ b/src/gui/opengl/qopenglframebufferobject.h
@@ -63,15 +63,18 @@ public:
QOpenGLFramebufferObject(int width, int height, GLenum target = GL_TEXTURE_2D);
QOpenGLFramebufferObject(const QSize &size, Attachment attachment,
- GLenum target = GL_TEXTURE_2D, GLenum internal_format = 0);
+ GLenum target = GL_TEXTURE_2D, GLenum internalFormat = 0);
QOpenGLFramebufferObject(int width, int height, Attachment attachment,
- GLenum target = GL_TEXTURE_2D, GLenum internal_format = 0);
+ GLenum target = GL_TEXTURE_2D, GLenum internalFormat = 0);
QOpenGLFramebufferObject(const QSize &size, const QOpenGLFramebufferObjectFormat &format);
QOpenGLFramebufferObject(int width, int height, const QOpenGLFramebufferObjectFormat &format);
virtual ~QOpenGLFramebufferObject();
+ void addColorAttachment(const QSize &size, GLenum internalFormat = 0);
+ void addColorAttachment(int width, int height, GLenum internalFormat = 0);
+
QOpenGLFramebufferObjectFormat format() const;
bool isValid() const;
@@ -83,12 +86,19 @@ public:
int height() const { return size().height(); }
GLuint texture() const;
+ QVector<GLuint> textures() const;
+
GLuint takeTexture();
+ GLuint takeTexture(int colorAttachmentIndex);
+
QSize size() const;
+ QVector<QSize> sizes() const;
+
QImage toImage() const;
QImage toImage(bool flipped) const;
- Attachment attachment() const;
+ QImage toImage(bool flipped, int colorAttachmentIndex) const;
+ Attachment attachment() const;
void setAttachment(Attachment attachment);
GLuint handle() const;
@@ -100,6 +110,12 @@ public:
static bool hasOpenGLFramebufferBlit();
static void blitFramebuffer(QOpenGLFramebufferObject *target, const QRect &targetRect,
QOpenGLFramebufferObject *source, const QRect &sourceRect,
+ GLbitfield buffers,
+ GLenum filter,
+ int readColorAttachmentIndex,
+ int drawColorAttachmentIndex);
+ static void blitFramebuffer(QOpenGLFramebufferObject *target, const QRect &targetRect,
+ QOpenGLFramebufferObject *source, const QRect &sourceRect,
GLbitfield buffers = GL_COLOR_BUFFER_BIT,
GLenum filter = GL_NEAREST);
static void blitFramebuffer(QOpenGLFramebufferObject *target,
diff --git a/src/gui/opengl/qopenglframebufferobject_p.h b/src/gui/opengl/qopenglframebufferobject_p.h
index 7f0068dfc4..6c45fda57f 100644
--- a/src/gui/opengl/qopenglframebufferobject_p.h
+++ b/src/gui/opengl/qopenglframebufferobject_p.h
@@ -102,32 +102,41 @@ public:
class QOpenGLFramebufferObjectPrivate
{
public:
- QOpenGLFramebufferObjectPrivate() : fbo_guard(0), texture_guard(0), depth_buffer_guard(0)
- , stencil_buffer_guard(0), color_buffer_guard(0)
+ QOpenGLFramebufferObjectPrivate() : fbo_guard(0), depth_buffer_guard(0)
+ , stencil_buffer_guard(0)
, valid(false) {}
~QOpenGLFramebufferObjectPrivate() {}
- void init(QOpenGLFramebufferObject *q, const QSize& sz,
+ void init(QOpenGLFramebufferObject *q, const QSize &size,
QOpenGLFramebufferObject::Attachment attachment,
- GLenum internal_format, GLenum texture_target,
+ GLenum texture_target, GLenum internal_format,
GLint samples = 0, bool mipmap = false);
- void initTexture(GLenum target, GLenum internal_format, const QSize &size, bool mipmap);
- void initAttachments(QOpenGLContext *ctx, QOpenGLFramebufferObject::Attachment attachment);
+ void initTexture(int idx);
+ void initColorBuffer(int idx, GLint *samples);
+ void initDepthStencilAttachments(QOpenGLContext *ctx, QOpenGLFramebufferObject::Attachment attachment);
bool checkFramebufferStatus(QOpenGLContext *ctx) const;
QOpenGLSharedResourceGuard *fbo_guard;
- QOpenGLSharedResourceGuard *texture_guard;
QOpenGLSharedResourceGuard *depth_buffer_guard;
QOpenGLSharedResourceGuard *stencil_buffer_guard;
- QOpenGLSharedResourceGuard *color_buffer_guard;
GLenum target;
- QSize size;
+ QSize dsSize;
QOpenGLFramebufferObjectFormat format;
int requestedSamples;
uint valid : 1;
QOpenGLFramebufferObject::Attachment fbo_attachment;
QOpenGLExtensions funcs;
+ struct ColorAttachment {
+ ColorAttachment() : internalFormat(0), guard(0) { }
+ ColorAttachment(const QSize &size, GLenum internalFormat)
+ : size(size), internalFormat(internalFormat), guard(0) { }
+ QSize size;
+ GLenum internalFormat;
+ QOpenGLSharedResourceGuard *guard;
+ };
+ QVector<ColorAttachment> colorAttachments;
+
inline GLuint fbo() const { return fbo_guard ? fbo_guard->id() : 0; }
};
diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp
index 8ddb693e73..be1a979c37 100644
--- a/src/gui/opengl/qopenglfunctions.cpp
+++ b/src/gui/opengl/qopenglfunctions.cpp
@@ -32,12 +32,14 @@
****************************************************************************/
#include "qopenglfunctions.h"
+#include "qopenglextrafunctions.h"
#include "qopenglextensions_p.h"
#include "qdebug.h"
#include <QtGui/private/qopenglcontext_p.h>
#include <QtGui/private/qopengl_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformintegration.h>
+#include <QtCore/qloggingcategory.h>
#ifdef Q_OS_IOS
#include <dlfcn.h>
@@ -49,6 +51,8 @@
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcGLES3, "qt.opengl.es3")
+
/*!
\class QOpenGLFunctions
\brief The QOpenGLFunctions class provides cross-platform access to the OpenGL ES 2.0 API.
@@ -92,7 +96,7 @@ QT_BEGIN_NAMESPACE
// Setup scene and render it
initializeGL();
- paintGL()
+ paintGL();
}
void MyGLWindow::initializeGL()
@@ -155,6 +159,8 @@ QT_BEGIN_NAMESPACE
QOpenGLFunctions funcs(QOpenGLContext::currentContext());
bool npot = funcs.hasOpenGLFeature(QOpenGLFunctions::NPOTTextures);
\endcode
+
+ \sa QOpenGLContext, QSurfaceFormat
*/
/*!
@@ -178,6 +184,7 @@ QT_BEGIN_NAMESPACE
\value NPOTTextureRepeat Non power of two textures can use GL_REPEAT as wrap parameter.
\value FixedFunctionPipeline The fixed function pipeline is available.
\value TextureRGFormats The GL_RED and GL_RG texture formats are available.
+ \value MultipleRenderTargets Multiple color attachments to framebuffer objects are available.
*/
// Hidden private fields for additional extension data.
@@ -251,12 +258,11 @@ QOpenGLFunctions::QOpenGLFunctions(QOpenGLContext *context)
}
QOpenGLExtensions::QOpenGLExtensions()
- : QOpenGLFunctions()
{
}
QOpenGLExtensions::QOpenGLExtensions(QOpenGLContext *context)
- : QOpenGLFunctions(context)
+ : QOpenGLExtraFunctions(context)
{
}
@@ -270,7 +276,7 @@ static int qt_gl_resolve_features()
{
QOpenGLContext *ctx = QOpenGLContext::currentContext();
if (ctx->isOpenGLES()) {
- // OpenGL ES 2
+ // OpenGL ES
int features = QOpenGLFunctions::Multitexture |
QOpenGLFunctions::Shaders |
QOpenGLFunctions::Buffers |
@@ -295,6 +301,8 @@ static int qt_gl_resolve_features()
if (!(renderer && strstr(renderer, "Mesa")))
features |= QOpenGLFunctions::TextureRGFormats;
}
+ if (ctx->format().majorVersion() >= 3)
+ features |= QOpenGLFunctions::MultipleRenderTargets;
return features;
} else {
// OpenGL
@@ -303,10 +311,9 @@ static int qt_gl_resolve_features()
QOpenGLExtensionMatcher extensions;
if (format.majorVersion() >= 3)
- features |= QOpenGLFunctions::Framebuffers;
- else if (extensions.match("GL_EXT_framebuffer_object") ||
- extensions.match("GL_ARB_framebuffer_object"))
- features |= QOpenGLFunctions::Framebuffers;
+ features |= QOpenGLFunctions::Framebuffers | QOpenGLFunctions::MultipleRenderTargets;
+ else if (extensions.match("GL_EXT_framebuffer_object") || extensions.match("GL_ARB_framebuffer_object"))
+ features |= QOpenGLFunctions::Framebuffers | QOpenGLFunctions::MultipleRenderTargets;
if (format.majorVersion() >= 2) {
features |= QOpenGLFunctions::BlendColor |
@@ -423,11 +430,14 @@ static int qt_gl_resolve_extensions()
// We don't match GL_APPLE_texture_format_BGRA8888 here because it has different semantics.
if (extensionMatcher.match("GL_IMG_texture_format_BGRA8888") || extensionMatcher.match("GL_EXT_texture_format_BGRA8888"))
extensions |= QOpenGLExtensions::BGRATextureFormat;
-
if (extensionMatcher.match("GL_EXT_discard_framebuffer"))
extensions |= QOpenGLExtensions::DiscardFramebuffer;
+ if (extensionMatcher.match("GL_EXT_texture_norm16"))
+ extensions |= QOpenGLExtensions::Sized16Formats;
} else {
- extensions |= QOpenGLExtensions::ElementIndexUint | QOpenGLExtensions::MapBuffer;
+ extensions |= QOpenGLExtensions::ElementIndexUint
+ | QOpenGLExtensions::MapBuffer
+ | QOpenGLExtensions::Sized16Formats;
if (format.version() >= qMakePair(1, 2))
extensions |= QOpenGLExtensions::BGRATextureFormat;
@@ -2121,6 +2131,9 @@ public:
template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10>
ReturnType operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10);
+ template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11>
+ ReturnType operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11);
+
private:
FuncType Base::*funcPointerName;
FuncType fallbackFuncPointer;
@@ -2172,6 +2185,9 @@ public:
template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10>
void operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10);
+ template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11>
+ void operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11);
+
private:
FuncType Base::*funcPointerName;
FuncType fallbackFuncPointer;
@@ -2421,6 +2437,14 @@ void Resolver<Base, FuncType, Policy, void>::operator()(P1 p1, P2 p2, P3 p3, P4
(funcs->*funcPointerName)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
}
+template <typename Base, typename FuncType, int Policy> template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11>
+void Resolver<Base, FuncType, Policy, void>::operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11)
+{
+ RESOLVER_COMMON_VOID
+
+ (funcs->*funcPointerName)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
+}
+
template <typename ReturnType, int Policy, typename Base, typename FuncType>
Resolver<Base, FuncType, Policy, ReturnType> functionResolverWithFallback(FuncType Base::*func, FuncType fallback, const char *name, const char *alternate = 0)
{
@@ -2433,7 +2457,7 @@ Resolver<Base, FuncType, Policy, ReturnType> functionResolver(FuncType Base::*fu
return Resolver<Base, FuncType, Policy, ReturnType>(func, 0, name, alternate);
}
-}
+} // namespace
#define RESOLVE_FUNC(RETURN_TYPE, POLICY, NAME) \
return functionResolver<RETURN_TYPE, POLICY>(&QOpenGLExtensionsPrivate::NAME, "gl" #NAME)
@@ -3201,79 +3225,7 @@ static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribPointer(GLuint indx, GL
#endif // !QT_OPENGL_ES_2
-// Functions part of the OpenGL ES 3.0+ standard need special handling. These,
-// just like the 2.0 functions, are not guaranteed to be resolvable via
-// eglGetProcAddress or similar. Calling them directly is, unlike the 2.0
-// functions, not feasible because one may build the binaries on a GLES3-capable
-// system and then deploy on a GLES2-only system that does not have these
-// symbols. Until ES3 gets universally available, they have to be dlsym'ed.
-
-Q_GLOBAL_STATIC(QOpenGLES3Helper, qgles3Helper)
-
-bool QOpenGLES3Helper::init()
-{
-#ifndef Q_OS_IOS
-# ifdef Q_OS_WIN
-# ifndef QT_DEBUG
- m_gl.setFileName(QStringLiteral("libGLESv2"));
-# else
- m_gl.setFileName(QStringLiteral("libGLESv2d"));
-# endif
-# else
-# ifdef Q_OS_ANDROID
- m_gl.setFileName(QStringLiteral("GLESv2"));
-# else
- m_gl.setFileNameAndVersion(QStringLiteral("GLESv2"), 2);
-# endif
-# endif // Q_OS_WIN
- return m_gl.load();
-#else
- return true;
-#endif // Q_OS_IOS
-}
-
-QFunctionPointer QOpenGLES3Helper::resolve(const char *name)
-{
-#ifdef Q_OS_IOS
- return QFunctionPointer(dlsym(RTLD_DEFAULT, name));
-#else
- return m_gl.resolve(name);
-#endif
-}
-
-QOpenGLES3Helper::QOpenGLES3Helper()
-{
- if (init()) {
- MapBufferRange = (GLvoid* (QOPENGLF_APIENTRYP)(GLenum, qopengl_GLintptr, qopengl_GLsizeiptr, GLbitfield)) resolve("glMapBufferRange");
- UnmapBuffer = (GLboolean (QOPENGLF_APIENTRYP)(GLenum)) resolve("glUnmapBuffer");
- BlitFramebuffer = (void (QOPENGLF_APIENTRYP)(GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum)) resolve("glBlitFramebuffer");
- RenderbufferStorageMultisample = (void (QOPENGLF_APIENTRYP)(GLenum, GLsizei, GLenum, GLsizei, GLsizei)) resolve("glRenderbufferStorageMultisample");
-
- GenVertexArrays = (void (QOPENGLF_APIENTRYP)(GLsizei, GLuint *)) resolve("glGenVertexArrays");
- DeleteVertexArrays = (void (QOPENGLF_APIENTRYP)(GLsizei, const GLuint *)) resolve("glDeleteVertexArrays");
- BindVertexArray = (void (QOPENGLF_APIENTRYP)(GLuint)) resolve("glBindVertexArray");
- IsVertexArray = (GLboolean (QOPENGLF_APIENTRYP)(GLuint)) resolve("glIsVertexArray");
-
- TexImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) resolve("glTexImage3D");
- TexSubImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) resolve("glTexSubImage3D");
- CompressedTexImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) resolve("glCompressedTexImage3D");
- CompressedTexSubImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) resolve("glCompressedTexSubImage3D");
-
- TexStorage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLsizei)) resolve("glTexStorage3D");
- TexStorage2D = (void (QOPENGLF_APIENTRYP)(GLenum, GLsizei, GLenum, GLsizei, GLsizei)) resolve("glTexStorage2D");
-
- if (!MapBufferRange || !GenVertexArrays || !TexImage3D || !TexStorage3D)
- qFatal("OpenGL ES 3.0 entry points not found");
- } else {
- qFatal("Failed to load libGLESv2");
- }
-}
-
-static inline bool isES3()
-{
- QOpenGLContext *ctx = QOpenGLContext::currentContext();
- return ctx->isOpenGLES() && ctx->format().majorVersion() >= 3;
-}
+// Extensions not standard in any ES version
static GLvoid *QOPENGLF_APIENTRY qopenglfResolveMapBuffer(GLenum target, GLenum access)
{
@@ -3281,7 +3233,8 @@ static GLvoid *QOPENGLF_APIENTRY qopenglfResolveMapBuffer(GLenum target, GLenum
// differentiate between glUnmapBufferOES and glUnmapBuffer causes extra
// headache. QOpenGLBuffer::map() will handle this automatically, while direct
// calls are better off with migrating to the standard glMapBufferRange.
- if (isES3()) {
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ if (ctx->isOpenGLES() && ctx->format().majorVersion() >= 3) {
qWarning("QOpenGLFunctions: glMapBuffer is not available in OpenGL ES 3.0 and up. Use glMapBufferRange instead.");
return 0;
} else {
@@ -3289,44 +3242,6 @@ static GLvoid *QOPENGLF_APIENTRY qopenglfResolveMapBuffer(GLenum target, GLenum
}
}
-static GLvoid *QOPENGLF_APIENTRY qopenglfResolveMapBufferRange(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr length, GLbitfield access)
-{
- if (isES3())
- return qgles3Helper()->MapBufferRange(target, offset, length, access);
- else
- RESOLVE_FUNC(GLvoid *, 0, MapBufferRange)(target, offset, length, access);
-}
-
-static GLboolean QOPENGLF_APIENTRY qopenglfResolveUnmapBuffer(GLenum target)
-{
- if (isES3())
- return qgles3Helper()->UnmapBuffer(target);
- else
- RESOLVE_FUNC(GLboolean, ResolveOES, UnmapBuffer)(target);
-}
-
-static void QOPENGLF_APIENTRY qopenglfResolveBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
- GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter)
-{
- if (isES3())
- qgles3Helper()->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
- else
- RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, BlitFramebuffer)
- (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
-}
-
-static void QOPENGLF_APIENTRY qopenglfResolveRenderbufferStorageMultisample(GLenum target, GLsizei samples,
- GLenum internalFormat,
- GLsizei width, GLsizei height)
-{
- if (isES3())
- qgles3Helper()->RenderbufferStorageMultisample(target, samples, internalFormat, width, height);
- else
- RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, RenderbufferStorageMultisample)
- (target, samples, internalFormat, width, height);
-}
-
static void QOPENGLF_APIENTRY qopenglfResolveGetBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, GLvoid *data)
{
RESOLVE_FUNC_VOID(ResolveEXT, GetBufferSubData)
@@ -3567,15 +3482,4129 @@ QOpenGLFunctionsPrivate::QOpenGLFunctionsPrivate(QOpenGLContext *)
#endif // !QT_OPENGL_ES_2
}
-QOpenGLExtensionsPrivate::QOpenGLExtensionsPrivate(QOpenGLContext *ctx)
- : QOpenGLFunctionsPrivate(ctx),
- flushVendorChecked(false)
+/*!
+ \class QOpenGLExtraFunctions
+ \brief The QOpenGLExtraFunctions class provides cross-platform access to the OpenGL ES 3.0 and 3.1 API.
+ \since 5.6
+ \ingroup painting-3D
+ \inmodule QtGui
+
+ This subclass of QOpenGLFunctions includes the OpenGL ES 3.0 and 3.1
+ functions. These will only work when an OpenGL ES 3.0 or 3.1 context, or an
+ OpenGL context of a version containing the functions in question either in
+ core or as extension, is in use. This allows developing GLES 3.0 and 3.1
+ applications in a cross-platform manner: development can happen on a desktop
+ platform with OpenGL 3.x or 4.x, deploying to a real GLES 3.1 device later
+ on will require no or minimal changes to the application.
+
+ \note This class is different from the versioned OpenGL wrappers, for
+ instance QOpenGLFunctions_3_2_Core. The versioned function wrappers target a
+ given version and profile of OpenGL. They are therefore not suitable for
+ cross-OpenGL-OpenGLES development.
+ */
+
+/*!
+ \fn void QOpenGLExtraFunctions::glBeginQuery(GLenum target, GLuint id)
+
+ Convenience function that calls glBeginQuery(\a target, \a id).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glBeginQuery.xml}{glBeginQuery()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glBeginTransformFeedback(GLenum primitiveMode)
+
+ Convenience function that calls glBeginTransformFeedback(\a primitiveMode).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glBeginTransformFeedback.xml}{glBeginTransformFeedback()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glBindBufferBase(GLenum target, GLuint index, GLuint buffer)
+
+ Convenience function that calls glBindBufferBase(\a target, \a index, \a buffer).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glBindBufferBase.xml}{glBindBufferBase()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
+
+ Convenience function that calls glBindBufferRange(\a target, \a index, \a buffer, \a offset, \a size).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glBindBufferRange.xml}{glBindBufferRange()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glBindSampler(GLuint unit, GLuint sampler)
+
+ Convenience function that calls glBindSampler(\a unit, \a sampler).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glBindSampler.xml}{glBindSampler()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glBindTransformFeedback(GLenum target, GLuint id)
+
+ Convenience function that calls glBindTransformFeedback(\a target, \a id).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glBindTransformFeedback.xml}{glBindTransformFeedback()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glBindVertexArray(GLuint array)
+
+ Convenience function that calls glBindVertexArray(\a array).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glBindVertexArray.xml}{glBindVertexArray()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
+
+ Convenience function that calls glBlitFramebuffer(\a srcX0, \a srcY0, \a srcX1, \a srcY1, \a dstX0, \a dstY0, \a dstX1, \a dstY1, \a mask, \a filter).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glBlitFramebuffer.xml}{glBlitFramebuffer()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
+
+ Convenience function that calls glClearBufferfi(\a buffer, \a drawbuffer, \a depth, \a stencil).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glClearBufferfi.xml}{glClearBufferfi()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat * value)
+
+ Convenience function that calls glClearBufferfv(\a buffer, \a drawbuffer, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glClearBufferfv.xml}{glClearBufferfv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint * value)
+
+ Convenience function that calls glClearBufferiv(\a buffer, \a drawbuffer, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glClearBufferiv.xml}{glClearBufferiv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint * value)
+
+ Convenience function that calls glClearBufferuiv(\a buffer, \a drawbuffer, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glClearBufferuiv.xml}{glClearBufferuiv()}.
+*/
+
+/*!
+ \fn GLenum QOpenGLExtraFunctions::glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+
+ Convenience function that calls glClientWaitSync(\a sync, \a flags, \a timeout).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glClientWaitSync.xml}{glClientWaitSync()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * data)
+
+ Convenience function that calls glCompressedTexImage3D(\a target, \a level, \a internalformat, \a width, \a height, \a depth, \a border, \a imageSize, \a data).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glCompressedTexImage3D.xml}{glCompressedTexImage3D()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data)
+
+ Convenience function that calls glCompressedTexSubImage3D(\a target, \a level, \a xoffset, \a yoffset, \a zoffset, \a width, \a height, \a depth, \a format, \a imageSize, \a data).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glCompressedTexSubImage3D.xml}{glCompressedTexSubImage3D()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size)
+
+ Convenience function that calls glCopyBufferSubData(\a readTarget, \a writeTarget, \a readOffset, \a writeOffset, \a size).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glCopyBufferSubData.xml}{glCopyBufferSubData()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+
+ Convenience function that calls glCopyTexSubImage3D(\a target, \a level, \a xoffset, \a yoffset, \a zoffset, \a x, \a y, \a width, \a height).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glCopyTexSubImage3D.xml}{glCopyTexSubImage3D()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glDeleteQueries(GLsizei n, const GLuint * ids)
+
+ Convenience function that calls glDeleteQueries(\a n, \a ids).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glDeleteQueries.xml}{glDeleteQueries()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glDeleteSamplers(GLsizei count, const GLuint * samplers)
+
+ Convenience function that calls glDeleteSamplers(\a count, \a samplers).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glDeleteSamplers.xml}{glDeleteSamplers()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glDeleteSync(GLsync sync)
+
+ Convenience function that calls glDeleteSync(\a sync).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glDeleteSync.xml}{glDeleteSync()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glDeleteTransformFeedbacks(GLsizei n, const GLuint * ids)
+
+ Convenience function that calls glDeleteTransformFeedbacks(\a n, \a ids).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glDeleteTransformFeedbacks.xml}{glDeleteTransformFeedbacks()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glDeleteVertexArrays(GLsizei n, const GLuint * arrays)
+
+ Convenience function that calls glDeleteVertexArrays(\a n, \a arrays).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glDeleteVertexArrays.xml}{glDeleteVertexArrays()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount)
+
+ Convenience function that calls glDrawArraysInstanced(\a mode, \a first, \a count, \a instancecount).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glDrawArraysInstanced.xml}{glDrawArraysInstanced()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glDrawBuffers(GLsizei n, const GLenum * bufs)
+
+ Convenience function that calls glDrawBuffers(\a n, \a bufs).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glDrawBuffers.xml}{glDrawBuffers()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount)
+
+ Convenience function that calls glDrawElementsInstanced(\a mode, \a count, \a type, \a indices, \a instancecount).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glDrawElementsInstanced.xml}{glDrawElementsInstanced()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices)
+
+ Convenience function that calls glDrawRangeElements(\a mode, \a start, \a end, \a count, \a type, \a indices).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glDrawRangeElements.xml}{glDrawRangeElements()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glEndQuery(GLenum target)
+
+ Convenience function that calls glEndQuery(\a target).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glEndQuery.xml}{glEndQuery()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glEndTransformFeedback(void)
+
+ Convenience function that calls glEndTransformFeedback().
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glEndTransformFeedback.xml}{glEndTransformFeedback()}.
+*/
+
+/*!
+ \fn GLsync QOpenGLExtraFunctions::glFenceSync(GLenum condition, GLbitfield flags)
+
+ Convenience function that calls glFenceSync(\a condition, \a flags).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glFenceSync.xml}{glFenceSync()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
+
+ Convenience function that calls glFlushMappedBufferRange(\a target, \a offset, \a length).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glFlushMappedBufferRange.xml}{glFlushMappedBufferRange()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
+
+ Convenience function that calls glFramebufferTextureLayer(\a target, \a attachment, \a texture, \a level, \a layer).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glFramebufferTextureLayer.xml}{glFramebufferTextureLayer()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGenQueries(GLsizei n, GLuint* ids)
+
+ Convenience function that calls glGenQueries(\a n, \a ids).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGenQueries.xml}{glGenQueries()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGenSamplers(GLsizei count, GLuint* samplers)
+
+ Convenience function that calls glGenSamplers(\a count, \a samplers).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGenSamplers.xml}{glGenSamplers()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGenTransformFeedbacks(GLsizei n, GLuint* ids)
+
+ Convenience function that calls glGenTransformFeedbacks(\a n, \a ids).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGenTransformFeedbacks.xml}{glGenTransformFeedbacks()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGenVertexArrays(GLsizei n, GLuint* arrays)
+
+ Convenience function that calls glGenVertexArrays(\a n, \a arrays).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGenVertexArrays.xml}{glGenVertexArrays()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName)
+
+ Convenience function that calls glGetActiveUniformBlockName(\a program, \a uniformBlockIndex, \a bufSize, \a length, \a uniformBlockName).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetActiveUniformBlockName.xml}{glGetActiveUniformBlockName()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params)
+
+ Convenience function that calls glGetActiveUniformBlockiv(\a program, \a uniformBlockIndex, \a pname, \a params).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetActiveUniformBlockiv.xml}{glGetActiveUniformBlockiv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint * uniformIndices, GLenum pname, GLint* params)
+
+ Convenience function that calls glGetActiveUniformsiv(\a program, \a uniformCount, \a uniformIndices, \a pname, \a params).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetActiveUniformsiv.xml}{glGetActiveUniformsiv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params)
+
+ Convenience function that calls glGetBufferParameteri64v(\a target, \a pname, \a params).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetBufferParameteri64v.xml}{glGetBufferParameteri64v()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetBufferPointerv(GLenum target, GLenum pname, void ** params)
+
+ Convenience function that calls glGetBufferPointerv(\a target, \a pname, \a params).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetBufferPointerv.xml}{glGetBufferPointerv()}.
+*/
+
+/*!
+ \fn GLint QOpenGLExtraFunctions::glGetFragDataLocation(GLuint program, const GLchar * name)
+
+ Convenience function that calls glGetFragDataLocation(\a program, \a name).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetFragDataLocation.xml}{glGetFragDataLocation()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetInteger64i_v(GLenum target, GLuint index, GLint64* data)
+
+ Convenience function that calls glGetInteger64i_v(\a target, \a index, \a data).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetInteger64i_v.xml}{glGetInteger64i_v()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetInteger64v(GLenum pname, GLint64* data)
+
+ Convenience function that calls glGetInteger64v(\a pname, \a data).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetInteger64v.xml}{glGetInteger64v()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetIntegeri_v(GLenum target, GLuint index, GLint* data)
+
+ Convenience function that calls glGetIntegeri_v(\a target, \a index, \a data).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetIntegeri_v.xml}{glGetIntegeri_v()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params)
+
+ Convenience function that calls glGetInternalformativ(\a target, \a internalformat, \a pname, \a bufSize, \a params).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetInternalformativ.xml}{glGetInternalformativ()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, void * binary)
+
+ Convenience function that calls glGetProgramBinary(\a program, \a bufSize, \a length, \a binaryFormat, \a binary).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetProgramBinary.xml}{glGetProgramBinary()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params)
+
+ Convenience function that calls glGetQueryObjectuiv(\a id, \a pname, \a params).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetQueryObjectuiv.xml}{glGetQueryObjectuiv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetQueryiv(GLenum target, GLenum pname, GLint* params)
+
+ Convenience function that calls glGetQueryiv(\a target, \a pname, \a params).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetQueryiv.xml}{glGetQueryiv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params)
+
+ Convenience function that calls glGetSamplerParameterfv(\a sampler, \a pname, \a params).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetSamplerParameterfv.xml}{glGetSamplerParameterfv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params)
+
+ Convenience function that calls glGetSamplerParameteriv(\a sampler, \a pname, \a params).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetSamplerParameteriv.xml}{glGetSamplerParameteriv()}.
+*/
+
+/*!
+ \fn const GLubyte * QOpenGLExtraFunctions::glGetStringi(GLenum name, GLuint index)
+
+ Convenience function that calls glGetStringi(\a name, \a index).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetStringi.xml}{glGetStringi()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values)
+
+ Convenience function that calls glGetSynciv(\a sync, \a pname, \a bufSize, \a length, \a values).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetSynciv.xml}{glGetSynciv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name)
+
+ Convenience function that calls glGetTransformFeedbackVarying(\a program, \a index, \a bufSize, \a length, \a size, \a type, \a name).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetTransformFeedbackVarying.xml}{glGetTransformFeedbackVarying()}.
+*/
+
+/*!
+ \fn GLuint QOpenGLExtraFunctions::glGetUniformBlockIndex(GLuint program, const GLchar * uniformBlockName)
+
+ Convenience function that calls glGetUniformBlockIndex(\a program, \a uniformBlockName).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetUniformBlockIndex.xml}{glGetUniformBlockIndex()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar *const* uniformNames, GLuint* uniformIndices)
+
+ Convenience function that calls glGetUniformIndices(\a program, \a uniformCount, \a uniformNames, \a uniformIndices).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetUniformIndices.xml}{glGetUniformIndices()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetUniformuiv(GLuint program, GLint location, GLuint* params)
+
+ Convenience function that calls glGetUniformuiv(\a program, \a location, \a params).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetUniformuiv.xml}{glGetUniformuiv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params)
+
+ Convenience function that calls glGetVertexAttribIiv(\a index, \a pname, \a params).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetVertexAttribIiv.xml}{glGetVertexAttribIiv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params)
+
+ Convenience function that calls glGetVertexAttribIuiv(\a index, \a pname, \a params).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetVertexAttribIuiv.xml}{glGetVertexAttribIuiv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum * attachments)
+
+ Convenience function that calls glInvalidateFramebuffer(\a target, \a numAttachments, \a attachments).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glInvalidateFramebuffer.xml}{glInvalidateFramebuffer()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height)
+
+ Convenience function that calls glInvalidateSubFramebuffer(\a target, \a numAttachments, \a attachments, \a x, \a y, \a width, \a height).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glInvalidateSubFramebuffer.xml}{glInvalidateSubFramebuffer()}.
+*/
+
+/*!
+ \fn GLboolean QOpenGLExtraFunctions::glIsQuery(GLuint id)
+
+ Convenience function that calls glIsQuery(\a id).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glIsQuery.xml}{glIsQuery()}.
+*/
+
+/*!
+ \fn GLboolean QOpenGLExtraFunctions::glIsSampler(GLuint sampler)
+
+ Convenience function that calls glIsSampler(\a sampler).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glIsSampler.xml}{glIsSampler()}.
+*/
+
+/*!
+ \fn GLboolean QOpenGLExtraFunctions::glIsSync(GLsync sync)
+
+ Convenience function that calls glIsSync(\a sync).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glIsSync.xml}{glIsSync()}.
+*/
+
+/*!
+ \fn GLboolean QOpenGLExtraFunctions::glIsTransformFeedback(GLuint id)
+
+ Convenience function that calls glIsTransformFeedback(\a id).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glIsTransformFeedback.xml}{glIsTransformFeedback()}.
+*/
+
+/*!
+ \fn GLboolean QOpenGLExtraFunctions::glIsVertexArray(GLuint array)
+
+ Convenience function that calls glIsVertexArray(\a array).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glIsVertexArray.xml}{glIsVertexArray()}.
+*/
+
+/*!
+ \fn void * QOpenGLExtraFunctions::glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
+
+ Convenience function that calls glMapBufferRange(\a target, \a offset, \a length, \a access).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glMapBufferRange.xml}{glMapBufferRange()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glPauseTransformFeedback(void)
+
+ Convenience function that calls glPauseTransformFeedback().
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glPauseTransformFeedback.xml}{glPauseTransformFeedback()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramBinary(GLuint program, GLenum binaryFormat, const void * binary, GLsizei length)
+
+ Convenience function that calls glProgramBinary(\a program, \a binaryFormat, \a binary, \a length).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramBinary.xml}{glProgramBinary()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramParameteri(GLuint program, GLenum pname, GLint value)
+
+ Convenience function that calls glProgramParameteri(\a program, \a pname, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramParameteri.xml}{glProgramParameteri()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glReadBuffer(GLenum src)
+
+ Convenience function that calls glReadBuffer(\a src).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glReadBuffer.xml}{glReadBuffer()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+
+ Convenience function that calls glRenderbufferStorageMultisample(\a target, \a samples, \a internalformat, \a width, \a height).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glRenderbufferStorageMultisample.xml}{glRenderbufferStorageMultisample()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glResumeTransformFeedback(void)
+
+ Convenience function that calls glResumeTransformFeedback().
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glResumeTransformFeedback.xml}{glResumeTransformFeedback()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
+
+ Convenience function that calls glSamplerParameterf(\a sampler, \a pname, \a param).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glSamplerParameterf.xml}{glSamplerParameterf()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat * param)
+
+ Convenience function that calls glSamplerParameterfv(\a sampler, \a pname, \a param).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glSamplerParameterfv.xml}{glSamplerParameterfv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glSamplerParameteri(GLuint sampler, GLenum pname, GLint param)
+
+ Convenience function that calls glSamplerParameteri(\a sampler, \a pname, \a param).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glSamplerParameteri.xml}{glSamplerParameteri()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint * param)
+
+ Convenience function that calls glSamplerParameteriv(\a sampler, \a pname, \a param).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glSamplerParameteriv.xml}{glSamplerParameteriv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels)
+
+ Convenience function that calls glTexImage3D(\a target, \a level, \a internalformat, \a width, \a height, \a depth, \a border, \a format, \a type, \a pixels).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glTexImage3D.xml}{glTexImage3D()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
+
+ Convenience function that calls glTexStorage2D(\a target, \a levels, \a internalformat, \a width, \a height).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glTexStorage2D.xml}{glTexStorage2D()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+
+ Convenience function that calls glTexStorage3D(\a target, \a levels, \a internalformat, \a width, \a height, \a depth).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glTexStorage3D.xml}{glTexStorage3D()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels)
+
+ Convenience function that calls glTexSubImage3D(\a target, \a level, \a xoffset, \a yoffset, \a zoffset, \a width, \a height, \a depth, \a format, \a type, \a pixels).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glTexSubImage3D.xml}{glTexSubImage3D()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode)
+
+ Convenience function that calls glTransformFeedbackVaryings(\a program, \a count, \a varyings, \a bufferMode).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glTransformFeedbackVaryings.xml}{glTransformFeedbackVaryings()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glUniform1ui(GLint location, GLuint v0)
+
+ Convenience function that calls glUniform1ui(\a location, \a v0).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniform1ui.xml}{glUniform1ui()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glUniform1uiv(GLint location, GLsizei count, const GLuint * value)
+
+ Convenience function that calls glUniform1uiv(\a location, \a count, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniform1uiv.xml}{glUniform1uiv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glUniform2ui(GLint location, GLuint v0, GLuint v1)
+
+ Convenience function that calls glUniform2ui(\a location, \a v0, \a v1).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniform2ui.xml}{glUniform2ui()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glUniform2uiv(GLint location, GLsizei count, const GLuint * value)
+
+ Convenience function that calls glUniform2uiv(\a location, \a count, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniform2uiv.xml}{glUniform2uiv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
+
+ Convenience function that calls glUniform3ui(\a location, \a v0, \a v1, \a v2).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniform3ui.xml}{glUniform3ui()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glUniform3uiv(GLint location, GLsizei count, const GLuint * value)
+
+ Convenience function that calls glUniform3uiv(\a location, \a count, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniform3uiv.xml}{glUniform3uiv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+
+ Convenience function that calls glUniform4ui(\a location, \a v0, \a v1, \a v2, \a v3).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniform4ui.xml}{glUniform4ui()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glUniform4uiv(GLint location, GLsizei count, const GLuint * value)
+
+ Convenience function that calls glUniform4uiv(\a location, \a count, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniform4uiv.xml}{glUniform4uiv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
+
+ Convenience function that calls glUniformBlockBinding(\a program, \a uniformBlockIndex, \a uniformBlockBinding).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniformBlockBinding.xml}{glUniformBlockBinding()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+
+ Convenience function that calls glUniformMatrix2x3fv(\a location, \a count, \a transpose, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniformMatrix2x3fv.xml}{glUniformMatrix2x3fv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+
+ Convenience function that calls glUniformMatrix2x4fv(\a location, \a count, \a transpose, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniformMatrix2x4fv.xml}{glUniformMatrix2x4fv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+
+ Convenience function that calls glUniformMatrix3x2fv(\a location, \a count, \a transpose, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniformMatrix3x2fv.xml}{glUniformMatrix3x2fv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+
+ Convenience function that calls glUniformMatrix3x4fv(\a location, \a count, \a transpose, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniformMatrix3x4fv.xml}{glUniformMatrix3x4fv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+
+ Convenience function that calls glUniformMatrix4x2fv(\a location, \a count, \a transpose, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniformMatrix4x2fv.xml}{glUniformMatrix4x2fv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+
+ Convenience function that calls glUniformMatrix4x3fv(\a location, \a count, \a transpose, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniformMatrix4x3fv.xml}{glUniformMatrix4x3fv()}.
+*/
+
+/*!
+ \fn GLboolean QOpenGLExtraFunctions::glUnmapBuffer(GLenum target)
+
+ Convenience function that calls glUnmapBuffer(\a target).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glUnmapBuffer.xml}{glUnmapBuffer()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glVertexAttribDivisor(GLuint index, GLuint divisor)
+
+ Convenience function that calls glVertexAttribDivisor(\a index, \a divisor).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribDivisor.xml}{glVertexAttribDivisor()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
+
+ Convenience function that calls glVertexAttribI4i(\a index, \a x, \a y, \a z, \a w).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribI4i.xml}{glVertexAttribI4i()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glVertexAttribI4iv(GLuint index, const GLint * v)
+
+ Convenience function that calls glVertexAttribI4iv(\a index, \a v).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribI4iv.xml}{glVertexAttribI4iv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
+
+ Convenience function that calls glVertexAttribI4ui(\a index, \a x, \a y, \a z, \a w).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribI4ui.xml}{glVertexAttribI4ui()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glVertexAttribI4uiv(GLuint index, const GLuint * v)
+
+ Convenience function that calls glVertexAttribI4uiv(\a index, \a v).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribI4uiv.xml}{glVertexAttribI4uiv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer)
+
+ Convenience function that calls glVertexAttribIPointer(\a index, \a size, \a type, \a stride, \a pointer).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribIPointer.xml}{glVertexAttribIPointer()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+
+ Convenience function that calls glWaitSync(\a sync, \a flags, \a timeout).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glWaitSync.xml}{glWaitSync()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glActiveShaderProgram(GLuint pipeline, GLuint program)
+
+ Convenience function that calls glActiveShaderProgram(\a pipeline, \a program).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glActiveShaderProgram.xml}{glActiveShaderProgram()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glBindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format)
+
+ Convenience function that calls glBindImageTexture(\a unit, \a texture, \a level, \a layered, \a layer, \a access, \a format).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glBindImageTexture.xml}{glBindImageTexture()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glBindProgramPipeline(GLuint pipeline)
+
+ Convenience function that calls glBindProgramPipeline(\a pipeline).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glBindProgramPipeline.xml}{glBindProgramPipeline()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glBindVertexBuffer(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride)
+
+ Convenience function that calls glBindVertexBuffer(\a bindingindex, \a buffer, \a offset, \a stride).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glBindVertexBuffer.xml}{glBindVertexBuffer()}.
+*/
+
+/*!
+ \fn GLuint QOpenGLExtraFunctions::glCreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const* strings)
+
+ Convenience function that calls glCreateShaderProgramv(\a type, \a count, \a strings).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glCreateShaderProgramv.xml}{glCreateShaderProgramv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glDeleteProgramPipelines(GLsizei n, const GLuint * pipelines)
+
+ Convenience function that calls glDeleteProgramPipelines(\a n, \a pipelines).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glDeleteProgramPipelines.xml}{glDeleteProgramPipelines()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z)
+
+ Convenience function that calls glDispatchCompute(\a num_groups_x, \a num_groups_y, \a num_groups_z).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glDispatchCompute.xml}{glDispatchCompute()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glDispatchComputeIndirect(GLintptr indirect)
+
+ Convenience function that calls glDispatchComputeIndirect(\a indirect).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glDispatchComputeIndirect.xml}{glDispatchComputeIndirect()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glDrawArraysIndirect(GLenum mode, const void * indirect)
+
+ Convenience function that calls glDrawArraysIndirect(\a mode, \a indirect).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glDrawArraysIndirect.xml}{glDrawArraysIndirect()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glDrawElementsIndirect(GLenum mode, GLenum type, const void * indirect)
+
+ Convenience function that calls glDrawElementsIndirect(\a mode, \a type, \a indirect).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glDrawElementsIndirect.xml}{glDrawElementsIndirect()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glFramebufferParameteri(GLenum target, GLenum pname, GLint param)
+
+ Convenience function that calls glFramebufferParameteri(\a target, \a pname, \a param).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glFramebufferParameteri.xml}{glFramebufferParameteri()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGenProgramPipelines(GLsizei n, GLuint* pipelines)
+
+ Convenience function that calls glGenProgramPipelines(\a n, \a pipelines).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGenProgramPipelines.xml}{glGenProgramPipelines()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetBooleani_v(GLenum target, GLuint index, GLboolean* data)
+
+ Convenience function that calls glGetBooleani_v(\a target, \a index, \a data).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetBooleani_v.xml}{glGetBooleani_v()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetFramebufferParameteriv(GLenum target, GLenum pname, GLint* params)
+
+ Convenience function that calls glGetFramebufferParameteriv(\a target, \a pname, \a params).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetFramebufferParameteriv.xml}{glGetFramebufferParameteriv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetMultisamplefv(GLenum pname, GLuint index, GLfloat* val)
+
+ Convenience function that calls glGetMultisamplefv(\a pname, \a index, \a val).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetMultisamplefv.xml}{glGetMultisamplefv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, GLint* params)
+
+ Convenience function that calls glGetProgramInterfaceiv(\a program, \a programInterface, \a pname, \a params).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetProgramInterfaceiv.xml}{glGetProgramInterfaceiv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar* infoLog)
+
+ Convenience function that calls glGetProgramPipelineInfoLog(\a pipeline, \a bufSize, \a length, \a infoLog).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetProgramPipelineInfoLog.xml}{glGetProgramPipelineInfoLog()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint* params)
+
+ Convenience function that calls glGetProgramPipelineiv(\a pipeline, \a pname, \a params).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetProgramPipelineiv.xml}{glGetProgramPipelineiv()}.
+*/
+
+/*!
+ \fn GLuint QOpenGLExtraFunctions::glGetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar * name)
+
+ Convenience function that calls glGetProgramResourceIndex(\a program, \a programInterface, \a name).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetProgramResourceIndex.xml}{glGetProgramResourceIndex()}.
+*/
+
+/*!
+ \fn GLint QOpenGLExtraFunctions::glGetProgramResourceLocation(GLuint program, GLenum programInterface, const GLchar * name)
+
+ Convenience function that calls glGetProgramResourceLocation(\a program, \a programInterface, \a name).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetProgramResourceLocation.xml}{glGetProgramResourceLocation()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetProgramResourceName(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, GLchar* name)
+
+ Convenience function that calls glGetProgramResourceName(\a program, \a programInterface, \a index, \a bufSize, \a length, \a name).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetProgramResourceName.xml}{glGetProgramResourceName()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei bufSize, GLsizei* length, GLint* params)
+
+ Convenience function that calls glGetProgramResourceiv(\a program, \a programInterface, \a index, \a propCount, \a props, \a bufSize, \a length, \a params).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetProgramResourceiv.xml}{glGetProgramResourceiv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat* params)
+
+ Convenience function that calls glGetTexLevelParameterfv(\a target, \a level, \a pname, \a params).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetTexLevelParameterfv.xml}{glGetTexLevelParameterfv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params)
+
+ Convenience function that calls glGetTexLevelParameteriv(\a target, \a level, \a pname, \a params).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetTexLevelParameteriv.xml}{glGetTexLevelParameteriv()}.
+*/
+
+/*!
+ \fn GLboolean QOpenGLExtraFunctions::glIsProgramPipeline(GLuint pipeline)
+
+ Convenience function that calls glIsProgramPipeline(\a pipeline).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glIsProgramPipeline.xml}{glIsProgramPipeline()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glMemoryBarrier(GLbitfield barriers)
+
+ Convenience function that calls glMemoryBarrier(\a barriers).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glMemoryBarrier.xml}{glMemoryBarrier()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glMemoryBarrierByRegion(GLbitfield barriers)
+
+ Convenience function that calls glMemoryBarrierByRegion(\a barriers).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glMemoryBarrierByRegion.xml}{glMemoryBarrierByRegion()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniform1f(GLuint program, GLint location, GLfloat v0)
+
+ Convenience function that calls glProgramUniform1f(\a program, \a location, \a v0).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform1f.xml}{glProgramUniform1f()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniform1fv(GLuint program, GLint location, GLsizei count, const GLfloat * value)
+
+ Convenience function that calls glProgramUniform1fv(\a program, \a location, \a count, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform1fv.xml}{glProgramUniform1fv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniform1i(GLuint program, GLint location, GLint v0)
+
+ Convenience function that calls glProgramUniform1i(\a program, \a location, \a v0).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform1i.xml}{glProgramUniform1i()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniform1iv(GLuint program, GLint location, GLsizei count, const GLint * value)
+
+ Convenience function that calls glProgramUniform1iv(\a program, \a location, \a count, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform1iv.xml}{glProgramUniform1iv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniform1ui(GLuint program, GLint location, GLuint v0)
+
+ Convenience function that calls glProgramUniform1ui(\a program, \a location, \a v0).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform1ui.xml}{glProgramUniform1ui()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniform1uiv(GLuint program, GLint location, GLsizei count, const GLuint * value)
+
+ Convenience function that calls glProgramUniform1uiv(\a program, \a location, \a count, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform1uiv.xml}{glProgramUniform1uiv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1)
+
+ Convenience function that calls glProgramUniform2f(\a program, \a location, \a v0, \a v1).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform2f.xml}{glProgramUniform2f()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniform2fv(GLuint program, GLint location, GLsizei count, const GLfloat * value)
+
+ Convenience function that calls glProgramUniform2fv(\a program, \a location, \a count, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform2fv.xml}{glProgramUniform2fv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1)
+
+ Convenience function that calls glProgramUniform2i(\a program, \a location, \a v0, \a v1).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform2i.xml}{glProgramUniform2i()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniform2iv(GLuint program, GLint location, GLsizei count, const GLint * value)
+
+ Convenience function that calls glProgramUniform2iv(\a program, \a location, \a count, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform2iv.xml}{glProgramUniform2iv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1)
+
+ Convenience function that calls glProgramUniform2ui(\a program, \a location, \a v0, \a v1).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform2ui.xml}{glProgramUniform2ui()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniform2uiv(GLuint program, GLint location, GLsizei count, const GLuint * value)
+
+ Convenience function that calls glProgramUniform2uiv(\a program, \a location, \a count, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform2uiv.xml}{glProgramUniform2uiv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
+
+ Convenience function that calls glProgramUniform3f(\a program, \a location, \a v0, \a v1, \a v2).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform3f.xml}{glProgramUniform3f()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniform3fv(GLuint program, GLint location, GLsizei count, const GLfloat * value)
+
+ Convenience function that calls glProgramUniform3fv(\a program, \a location, \a count, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform3fv.xml}{glProgramUniform3fv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
+
+ Convenience function that calls glProgramUniform3i(\a program, \a location, \a v0, \a v1, \a v2).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform3i.xml}{glProgramUniform3i()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniform3iv(GLuint program, GLint location, GLsizei count, const GLint * value)
+
+ Convenience function that calls glProgramUniform3iv(\a program, \a location, \a count, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform3iv.xml}{glProgramUniform3iv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2)
+
+ Convenience function that calls glProgramUniform3ui(\a program, \a location, \a v0, \a v1, \a v2).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform3ui.xml}{glProgramUniform3ui()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniform3uiv(GLuint program, GLint location, GLsizei count, const GLuint * value)
+
+ Convenience function that calls glProgramUniform3uiv(\a program, \a location, \a count, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform3uiv.xml}{glProgramUniform3uiv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
+
+ Convenience function that calls glProgramUniform4f(\a program, \a location, \a v0, \a v1, \a v2, \a v3).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform4f.xml}{glProgramUniform4f()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniform4fv(GLuint program, GLint location, GLsizei count, const GLfloat * value)
+
+ Convenience function that calls glProgramUniform4fv(\a program, \a location, \a count, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform4fv.xml}{glProgramUniform4fv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
+
+ Convenience function that calls glProgramUniform4i(\a program, \a location, \a v0, \a v1, \a v2, \a v3).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform4i.xml}{glProgramUniform4i()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniform4iv(GLuint program, GLint location, GLsizei count, const GLint * value)
+
+ Convenience function that calls glProgramUniform4iv(\a program, \a location, \a count, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform4iv.xml}{glProgramUniform4iv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+
+ Convenience function that calls glProgramUniform4ui(\a program, \a location, \a v0, \a v1, \a v2, \a v3).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform4ui.xml}{glProgramUniform4ui()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniform4uiv(GLuint program, GLint location, GLsizei count, const GLuint * value)
+
+ Convenience function that calls glProgramUniform4uiv(\a program, \a location, \a count, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform4uiv.xml}{glProgramUniform4uiv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+
+ Convenience function that calls glProgramUniformMatrix2fv(\a program, \a location, \a count, \a transpose, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix2fv.xml}{glProgramUniformMatrix2fv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+
+ Convenience function that calls glProgramUniformMatrix2x3fv(\a program, \a location, \a count, \a transpose, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix2x3fv.xml}{glProgramUniformMatrix2x3fv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+
+ Convenience function that calls glProgramUniformMatrix2x4fv(\a program, \a location, \a count, \a transpose, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix2x4fv.xml}{glProgramUniformMatrix2x4fv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+
+ Convenience function that calls glProgramUniformMatrix3fv(\a program, \a location, \a count, \a transpose, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix3fv.xml}{glProgramUniformMatrix3fv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+
+ Convenience function that calls glProgramUniformMatrix3x2fv(\a program, \a location, \a count, \a transpose, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix3x2fv.xml}{glProgramUniformMatrix3x2fv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+
+ Convenience function that calls glProgramUniformMatrix3x4fv(\a program, \a location, \a count, \a transpose, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix3x4fv.xml}{glProgramUniformMatrix3x4fv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+
+ Convenience function that calls glProgramUniformMatrix4fv(\a program, \a location, \a count, \a transpose, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix4fv.xml}{glProgramUniformMatrix4fv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+
+ Convenience function that calls glProgramUniformMatrix4x2fv(\a program, \a location, \a count, \a transpose, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix4x2fv.xml}{glProgramUniformMatrix4x2fv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+
+ Convenience function that calls glProgramUniformMatrix4x3fv(\a program, \a location, \a count, \a transpose, \a value).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix4x3fv.xml}{glProgramUniformMatrix4x3fv()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glSampleMaski(GLuint maskNumber, GLbitfield mask)
+
+ Convenience function that calls glSampleMaski(\a maskNumber, \a mask).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glSampleMaski.xml}{glSampleMaski()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glTexStorage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations)
+
+ Convenience function that calls glTexStorage2DMultisample(\a target, \a samples, \a internalformat, \a width, \a height, \a fixedsamplelocations).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glTexStorage2DMultisample.xml}{glTexStorage2DMultisample()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
+
+ Convenience function that calls glUseProgramStages(\a pipeline, \a stages, \a program).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glUseProgramStages.xml}{glUseProgramStages()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glValidateProgramPipeline(GLuint pipeline)
+
+ Convenience function that calls glValidateProgramPipeline(\a pipeline).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glValidateProgramPipeline.xml}{glValidateProgramPipeline()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glVertexAttribBinding(GLuint attribindex, GLuint bindingindex)
+
+ Convenience function that calls glVertexAttribBinding(\a attribindex, \a bindingindex).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribBinding.xml}{glVertexAttribBinding()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glVertexAttribFormat(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset)
+
+ Convenience function that calls glVertexAttribFormat(\a attribindex, \a size, \a type, \a normalized, \a relativeoffset).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribFormat.xml}{glVertexAttribFormat()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glVertexAttribIFormat(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset)
+
+ Convenience function that calls glVertexAttribIFormat(\a attribindex, \a size, \a type, \a relativeoffset).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribIFormat.xml}{glVertexAttribIFormat()}.
+*/
+
+/*!
+ \fn void QOpenGLExtraFunctions::glVertexBindingDivisor(GLuint bindingindex, GLuint divisor)
+
+ Convenience function that calls glVertexBindingDivisor(\a bindingindex, \a divisor).
+
+ This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running
+ with plain OpenGL, the function is only usable when the given profile and version contains the
+ function either in core or as an extension.
+
+ For more information, see the OpenGL ES 3.x documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexBindingDivisor.xml}{glVertexBindingDivisor()}.
+*/
+
+/*!
+ \fn bool QOpenGLExtraFunctions::isInitialized(const QOpenGLExtraFunctionsPrivate *d)
+ \internal
+*/
+
+// Functions part of the OpenGL ES 3.0+ standard need special handling. These, just like
+// the 2.0 functions, are not guaranteed to be resolvable via eglGetProcAddress or
+// similar. (we cannot count on EGL_KHR_(client_)get_all_proc_addresses being available)
+
+// Calling them directly is, unlike the 2.0 functions, not feasible because one may build
+// the binaries on a GLES3-capable system and then deploy on a GLES2-only system that does
+// not have these symbols, and vice versa. Until ES3 becomes universally available, they
+// have to be dlsym'ed.
+
+Q_GLOBAL_STATIC(QOpenGLES3Helper, qgles3Helper)
+
+bool QOpenGLES3Helper::init()
{
- MapBuffer = qopenglfResolveMapBuffer;
- MapBufferRange = qopenglfResolveMapBufferRange;
+#ifdef QT_NO_LIBRARY
+ return false;
+#elif !defined(Q_OS_IOS)
+# ifdef Q_OS_WIN
+# ifndef QT_DEBUG
+ m_gl.setFileName(QStringLiteral("libGLESv2"));
+# else
+ m_gl.setFileName(QStringLiteral("libGLESv2d"));
+# endif
+# else
+# ifdef Q_OS_ANDROID
+ m_gl.setFileName(QStringLiteral("GLESv2"));
+# else
+ m_gl.setFileNameAndVersion(QStringLiteral("GLESv2"), 2);
+# endif
+# endif // Q_OS_WIN
+ return m_gl.load();
+#else
+ return true;
+#endif // Q_OS_IOS
+}
+
+QFunctionPointer QOpenGLES3Helper::resolve(const char *name)
+{
+#ifdef Q_OS_IOS
+ return QFunctionPointer(dlsym(RTLD_DEFAULT, name));
+#elif !defined(QT_NO_LIBRARY)
+ return m_gl.resolve(name);
+#else
+ Q_UNUSED(name);
+ return 0;
+#endif
+}
+
+QOpenGLES3Helper::QOpenGLES3Helper()
+{
+ m_supportedVersion = qMakePair(2, 0);
+
+ if (init()) {
+ const QPair<int, int> contextVersion = QOpenGLContext::currentContext()->format().version();
+
+ qCDebug(lcGLES3, "Resolving OpenGL ES 3.0 entry points");
+
+ BeginQuery = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint)) resolve("glBeginQuery");
+ BeginTransformFeedback = (void (QOPENGLF_APIENTRYP) (GLenum)) resolve("glBeginTransformFeedback");
+ BindBufferBase = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint, GLuint)) resolve("glBindBufferBase");
+ BindBufferRange = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr)) resolve("glBindBufferRange");
+ BindSampler = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint)) resolve("glBindSampler");
+ BindTransformFeedback = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint)) resolve("glBindTransformFeedback");
+ BindVertexArray = (void (QOPENGLF_APIENTRYP) (GLuint)) resolve("glBindVertexArray");
+ BlitFramebuffer = (void (QOPENGLF_APIENTRYP) (GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum)) resolve("glBlitFramebuffer");
+ ClearBufferfi = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLfloat, GLint)) resolve("glClearBufferfi");
+ ClearBufferfv = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, const GLfloat *)) resolve("glClearBufferfv");
+ ClearBufferiv = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, const GLint *)) resolve("glClearBufferiv");
+ ClearBufferuiv = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, const GLuint *)) resolve("glClearBufferuiv");
+ ClientWaitSync = (GLenum (QOPENGLF_APIENTRYP) (GLsync, GLbitfield, GLuint64)) resolve("glClientWaitSync");
+ CompressedTexImage3D = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const void *)) resolve("glCompressedTexImage3D");
+ CompressedTexSubImage3D = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const void *)) resolve("glCompressedTexSubImage3D");
+ CopyBufferSubData = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, GLintptr, GLintptr, GLsizeiptr)) resolve("glCopyBufferSubData");
+ CopyTexSubImage3D = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)) resolve("glCopyTexSubImage3D");
+ DeleteQueries = (void (QOPENGLF_APIENTRYP) (GLsizei, const GLuint *)) resolve("glDeleteQueries");
+ DeleteSamplers = (void (QOPENGLF_APIENTRYP) (GLsizei, const GLuint *)) resolve("glDeleteSamplers");
+ DeleteSync = (void (QOPENGLF_APIENTRYP) (GLsync)) resolve("glDeleteSync");
+ DeleteTransformFeedbacks = (void (QOPENGLF_APIENTRYP) (GLsizei, const GLuint *)) resolve("glDeleteTransformFeedbacks");
+ DeleteVertexArrays = (void (QOPENGLF_APIENTRYP) (GLsizei, const GLuint *)) resolve("glDeleteVertexArrays");
+ DrawArraysInstanced = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLsizei, GLsizei)) resolve("glDrawArraysInstanced");
+ DrawBuffers = (void (QOPENGLF_APIENTRYP) (GLsizei, const GLenum *)) resolve("glDrawBuffers");
+ DrawElementsInstanced = (void (QOPENGLF_APIENTRYP) (GLenum, GLsizei, GLenum, const void *, GLsizei)) resolve("glDrawElementsInstanced");
+ DrawRangeElements = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint, GLuint, GLsizei, GLenum, const void *)) resolve("glDrawRangeElements");
+ EndQuery = (void (QOPENGLF_APIENTRYP) (GLenum)) resolve("glEndQuery");
+ EndTransformFeedback = (void (QOPENGLF_APIENTRYP) ()) resolve("glEndTransformFeedback");
+ FenceSync = (GLsync (QOPENGLF_APIENTRYP) (GLenum, GLbitfield)) resolve("glFenceSync");
+ FlushMappedBufferRange = (void (QOPENGLF_APIENTRYP) (GLenum, GLintptr, GLsizeiptr)) resolve("glFlushMappedBufferRange");
+ FramebufferTextureLayer = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, GLuint, GLint, GLint)) resolve("glFramebufferTextureLayer");
+ GenQueries = (void (QOPENGLF_APIENTRYP) (GLsizei, GLuint*)) resolve("glGenQueries");
+ GenSamplers = (void (QOPENGLF_APIENTRYP) (GLsizei, GLuint*)) resolve("glGenSamplers");
+ GenTransformFeedbacks = (void (QOPENGLF_APIENTRYP) (GLsizei, GLuint*)) resolve("glGenTransformFeedbacks");
+ GenVertexArrays = (void (QOPENGLF_APIENTRYP) (GLsizei, GLuint*)) resolve("glGenVertexArrays");
+ GetActiveUniformBlockName = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint, GLsizei, GLsizei*, GLchar*)) resolve("glGetActiveUniformBlockName");
+ GetActiveUniformBlockiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint, GLenum, GLint*)) resolve("glGetActiveUniformBlockiv");
+ GetActiveUniformsiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLsizei, const GLuint *, GLenum, GLint*)) resolve("glGetActiveUniformsiv");
+ GetBufferParameteri64v = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, GLint64*)) resolve("glGetBufferParameteri64v");
+ GetBufferPointerv = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, void **)) resolve("glGetBufferPointerv");
+ GetFragDataLocation = (GLint (QOPENGLF_APIENTRYP) (GLuint, const GLchar *)) resolve("glGetFragDataLocation");
+ GetInteger64i_v = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint, GLint64*)) resolve("glGetInteger64i_v");
+ GetInteger64v = (void (QOPENGLF_APIENTRYP) (GLenum, GLint64*)) resolve("glGetInteger64v");
+ GetIntegeri_v = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint, GLint*)) resolve("glGetIntegeri_v");
+ GetInternalformativ = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, GLenum, GLsizei, GLint*)) resolve("glGetInternalformativ");
+ GetProgramBinary = (void (QOPENGLF_APIENTRYP) (GLuint, GLsizei, GLsizei*, GLenum*, void *)) resolve("glGetProgramBinary");
+ GetQueryObjectuiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLuint*)) resolve("glGetQueryObjectuiv");
+ GetQueryiv = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, GLint*)) resolve("glGetQueryiv");
+ GetSamplerParameterfv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLfloat*)) resolve("glGetSamplerParameterfv");
+ GetSamplerParameteriv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLint*)) resolve("glGetSamplerParameteriv");
+ GetStringi = (const GLubyte * (QOPENGLF_APIENTRYP) (GLenum, GLuint)) resolve("glGetStringi");
+ GetSynciv = (void (QOPENGLF_APIENTRYP) (GLsync, GLenum, GLsizei, GLsizei*, GLint*)) resolve("glGetSynciv");
+ GetTransformFeedbackVarying = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint, GLsizei, GLsizei*, GLsizei*, GLenum*, GLchar*)) resolve("glGetTransformFeedbackVarying");
+ GetUniformBlockIndex = (GLuint (QOPENGLF_APIENTRYP) (GLuint, const GLchar *)) resolve("glGetUniformBlockIndex");
+ GetUniformIndices = (void (QOPENGLF_APIENTRYP) (GLuint, GLsizei, const GLchar *const*, GLuint*)) resolve("glGetUniformIndices");
+ GetUniformuiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLuint*)) resolve("glGetUniformuiv");
+ GetVertexAttribIiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLint*)) resolve("glGetVertexAttribIiv");
+ GetVertexAttribIuiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLuint*)) resolve("glGetVertexAttribIuiv");
+ InvalidateFramebuffer = (void (QOPENGLF_APIENTRYP) (GLenum, GLsizei, const GLenum *)) resolve("glInvalidateFramebuffer");
+ InvalidateSubFramebuffer = (void (QOPENGLF_APIENTRYP) (GLenum, GLsizei, const GLenum *, GLint, GLint, GLsizei, GLsizei)) resolve("glInvalidateSubFramebuffer");
+ IsQuery = (GLboolean (QOPENGLF_APIENTRYP) (GLuint)) resolve("glIsQuery");
+ IsSampler = (GLboolean (QOPENGLF_APIENTRYP) (GLuint)) resolve("glIsSampler");
+ IsSync = (GLboolean (QOPENGLF_APIENTRYP) (GLsync)) resolve("glIsSync");
+ IsTransformFeedback = (GLboolean (QOPENGLF_APIENTRYP) (GLuint)) resolve("glIsTransformFeedback");
+ IsVertexArray = (GLboolean (QOPENGLF_APIENTRYP) (GLuint)) resolve("glIsVertexArray");
+ MapBufferRange = (void * (QOPENGLF_APIENTRYP) (GLenum, GLintptr, GLsizeiptr, GLbitfield)) resolve("glMapBufferRange");
+ PauseTransformFeedback = (void (QOPENGLF_APIENTRYP) ()) resolve("glPauseTransformFeedback");
+ ProgramBinary = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, const void *, GLsizei)) resolve("glProgramBinary");
+ ProgramParameteri = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLint)) resolve("glProgramParameteri");
+ ReadBuffer = (void (QOPENGLF_APIENTRYP) (GLenum)) resolve("glReadBuffer");
+ RenderbufferStorageMultisample = (void (QOPENGLF_APIENTRYP) (GLenum, GLsizei, GLenum, GLsizei, GLsizei)) resolve("glRenderbufferStorageMultisample");
+ ResumeTransformFeedback = (void (QOPENGLF_APIENTRYP) ()) resolve("glResumeTransformFeedback");
+ SamplerParameterf = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLfloat)) resolve("glSamplerParameterf");
+ SamplerParameterfv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, const GLfloat *)) resolve("glSamplerParameterfv");
+ SamplerParameteri = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLint)) resolve("glSamplerParameteri");
+ SamplerParameteriv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, const GLint *)) resolve("glSamplerParameteriv");
+ TexImage3D = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const void *)) resolve("glTexImage3D");
+ TexStorage2D = (void (QOPENGLF_APIENTRYP) (GLenum, GLsizei, GLenum, GLsizei, GLsizei)) resolve("glTexStorage2D");
+ TexStorage3D = (void (QOPENGLF_APIENTRYP) (GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLsizei)) resolve("glTexStorage3D");
+ TexSubImage3D = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const void *)) resolve("glTexSubImage3D");
+ TransformFeedbackVaryings = (void (QOPENGLF_APIENTRYP) (GLuint, GLsizei, const GLchar *const*, GLenum)) resolve("glTransformFeedbackVaryings");
+ Uniform1ui = (void (QOPENGLF_APIENTRYP) (GLint, GLuint)) resolve("glUniform1ui");
+ Uniform1uiv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, const GLuint *)) resolve("glUniform1uiv");
+ Uniform2ui = (void (QOPENGLF_APIENTRYP) (GLint, GLuint, GLuint)) resolve("glUniform2ui");
+ Uniform2uiv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, const GLuint *)) resolve("glUniform2uiv");
+ Uniform3ui = (void (QOPENGLF_APIENTRYP) (GLint, GLuint, GLuint, GLuint)) resolve("glUniform3ui");
+ Uniform3uiv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, const GLuint *)) resolve("glUniform3uiv");
+ Uniform4ui = (void (QOPENGLF_APIENTRYP) (GLint, GLuint, GLuint, GLuint, GLuint)) resolve("glUniform4ui");
+ Uniform4uiv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, const GLuint *)) resolve("glUniform4uiv");
+ UniformBlockBinding = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint, GLuint)) resolve("glUniformBlockBinding");
+ UniformMatrix2x3fv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glUniformMatrix2x3fv");
+ UniformMatrix2x4fv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glUniformMatrix2x4fv");
+ UniformMatrix3x2fv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glUniformMatrix3x2fv");
+ UniformMatrix3x4fv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glUniformMatrix3x4fv");
+ UniformMatrix4x2fv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glUniformMatrix4x2fv");
+ UniformMatrix4x3fv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glUniformMatrix4x3fv");
+ UnmapBuffer = (GLboolean (QOPENGLF_APIENTRYP) (GLenum)) resolve("glUnmapBuffer");
+ VertexAttribDivisor = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint)) resolve("glVertexAttribDivisor");
+ VertexAttribI4i = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLint, GLint, GLint)) resolve("glVertexAttribI4i");
+ VertexAttribI4iv = (void (QOPENGLF_APIENTRYP) (GLuint, const GLint *)) resolve("glVertexAttribI4iv");
+ VertexAttribI4ui = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint, GLuint, GLuint, GLuint)) resolve("glVertexAttribI4ui");
+ VertexAttribI4uiv = (void (QOPENGLF_APIENTRYP) (GLuint, const GLuint *)) resolve("glVertexAttribI4uiv");
+ VertexAttribIPointer = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLenum, GLsizei, const void *)) resolve("glVertexAttribIPointer");
+ WaitSync = (void (QOPENGLF_APIENTRYP) (GLsync, GLbitfield, GLuint64)) resolve("glWaitSync");
+
+ if (!BeginQuery || !BlitFramebuffer || !GenTransformFeedbacks || !GenVertexArrays || !MapBufferRange
+ || !RenderbufferStorageMultisample || !TexStorage2D || !WaitSync) {
+ qWarning("OpenGL ES 3.0 entry points not found. This is odd because the driver returned a context of version %d.%d",
+ contextVersion.first, contextVersion.second);
+ return;
+ }
+ m_supportedVersion = qMakePair(3, 0);
+
+ if (contextVersion >= qMakePair(3, 1)) {
+ qCDebug(lcGLES3, "Resolving OpenGL ES 3.1 entry points");
+
+ ActiveShaderProgram = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint)) resolve("glActiveShaderProgram");
+ BindImageTexture = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint, GLint, GLboolean, GLint, GLenum, GLenum)) resolve("glBindImageTexture");
+ BindProgramPipeline = (void (QOPENGLF_APIENTRYP) (GLuint)) resolve("glBindProgramPipeline");
+ BindVertexBuffer = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint, GLintptr, GLsizei)) resolve("glBindVertexBuffer");
+ CreateShaderProgramv = (GLuint (QOPENGLF_APIENTRYP) (GLenum, GLsizei, const GLchar *const*)) resolve("glCreateShaderProgramv");
+ DeleteProgramPipelines = (void (QOPENGLF_APIENTRYP) (GLsizei, const GLuint *)) resolve("glDeleteProgramPipelines");
+ DispatchCompute = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint, GLuint)) resolve("glDispatchCompute");
+ DispatchComputeIndirect = (void (QOPENGLF_APIENTRYP) (GLintptr)) resolve("glDispatchComputeIndirect");
+ DrawArraysIndirect = (void (QOPENGLF_APIENTRYP) (GLenum, const void *)) resolve("glDrawArraysIndirect");
+ DrawElementsIndirect = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, const void *)) resolve("glDrawElementsIndirect");
+ FramebufferParameteri = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, GLint)) resolve("glFramebufferParameteri");
+ GenProgramPipelines = (void (QOPENGLF_APIENTRYP) (GLsizei, GLuint*)) resolve("glGenProgramPipelines");
+ GetBooleani_v = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint, GLboolean*)) resolve("glGetBooleani_v");
+ GetFramebufferParameteriv = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, GLint*)) resolve("glGetFramebufferParameteriv");
+ GetMultisamplefv = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint, GLfloat*)) resolve("glGetMultisamplefv");
+ GetProgramInterfaceiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLenum, GLint*)) resolve("glGetProgramInterfaceiv");
+ GetProgramPipelineInfoLog = (void (QOPENGLF_APIENTRYP) (GLuint, GLsizei, GLsizei*, GLchar*)) resolve("glGetProgramPipelineInfoLog");
+ GetProgramPipelineiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLint*)) resolve("glGetProgramPipelineiv");
+ GetProgramResourceIndex = (GLuint (QOPENGLF_APIENTRYP) (GLuint, GLenum, const GLchar *)) resolve("glGetProgramResourceIndex");
+ GetProgramResourceLocation = (GLint (QOPENGLF_APIENTRYP) (GLuint, GLenum, const GLchar *)) resolve("glGetProgramResourceLocation");
+ GetProgramResourceName = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLuint, GLsizei, GLsizei*, GLchar*)) resolve("glGetProgramResourceName");
+ GetProgramResourceiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLuint, GLsizei, const GLenum *, GLsizei, GLsizei*, GLint*)) resolve("glGetProgramResourceiv");
+ GetTexLevelParameterfv = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLenum, GLfloat*)) resolve("glGetTexLevelParameterfv");
+ GetTexLevelParameteriv = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLenum, GLint*)) resolve("glGetTexLevelParameteriv");
+ IsProgramPipeline = (GLboolean (QOPENGLF_APIENTRYP) (GLuint)) resolve("glIsProgramPipeline");
+ MemoryBarrierFunc = (void (QOPENGLF_APIENTRYP) (GLbitfield)) resolve("glMemoryBarrier");
+ MemoryBarrierByRegion = (void (QOPENGLF_APIENTRYP) (GLbitfield)) resolve("glMemoryBarrierByRegion");
+ ProgramUniform1f = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLfloat)) resolve("glProgramUniform1f");
+ ProgramUniform1fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLfloat *)) resolve("glProgramUniform1fv");
+ ProgramUniform1i = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLint)) resolve("glProgramUniform1i");
+ ProgramUniform1iv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLint *)) resolve("glProgramUniform1iv");
+ ProgramUniform1ui = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLuint)) resolve("glProgramUniform1ui");
+ ProgramUniform1uiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLuint *)) resolve("glProgramUniform1uiv");
+ ProgramUniform2f = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLfloat, GLfloat)) resolve("glProgramUniform2f");
+ ProgramUniform2fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLfloat *)) resolve("glProgramUniform2fv");
+ ProgramUniform2i = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLint, GLint)) resolve("glProgramUniform2i");
+ ProgramUniform2iv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLint *)) resolve("glProgramUniform2iv");
+ ProgramUniform2ui = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLuint, GLuint)) resolve("glProgramUniform2ui");
+ ProgramUniform2uiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLuint *)) resolve("glProgramUniform2uiv");
+ ProgramUniform3f = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLfloat, GLfloat, GLfloat)) resolve("glProgramUniform3f");
+ ProgramUniform3fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLfloat *)) resolve("glProgramUniform3fv");
+ ProgramUniform3i = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLint, GLint, GLint)) resolve("glProgramUniform3i");
+ ProgramUniform3iv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLint *)) resolve("glProgramUniform3iv");
+ ProgramUniform3ui = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLuint, GLuint, GLuint)) resolve("glProgramUniform3ui");
+ ProgramUniform3uiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLuint *)) resolve("glProgramUniform3uiv");
+ ProgramUniform4f = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLfloat, GLfloat, GLfloat, GLfloat)) resolve("glProgramUniform4f");
+ ProgramUniform4fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLfloat *)) resolve("glProgramUniform4fv");
+ ProgramUniform4i = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLint, GLint, GLint, GLint)) resolve("glProgramUniform4i");
+ ProgramUniform4iv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLint *)) resolve("glProgramUniform4iv");
+ ProgramUniform4ui = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLuint, GLuint, GLuint, GLuint)) resolve("glProgramUniform4ui");
+ ProgramUniform4uiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLuint *)) resolve("glProgramUniform4uiv");
+ ProgramUniformMatrix2fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix2fv");
+ ProgramUniformMatrix2x3fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix2x3fv");
+ ProgramUniformMatrix2x4fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix2x4fv");
+ ProgramUniformMatrix3fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix3fv");
+ ProgramUniformMatrix3x2fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix3x2fv");
+ ProgramUniformMatrix3x4fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix3x4fv");
+ ProgramUniformMatrix4fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix4fv");
+ ProgramUniformMatrix4x2fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix4x2fv");
+ ProgramUniformMatrix4x3fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix4x3fv");
+ SampleMaski = (void (QOPENGLF_APIENTRYP) (GLuint, GLbitfield)) resolve("glSampleMaski");
+ TexStorage2DMultisample = (void (QOPENGLF_APIENTRYP) (GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLboolean)) resolve("glTexStorage2DMultisample");
+ UseProgramStages = (void (QOPENGLF_APIENTRYP) (GLuint, GLbitfield, GLuint)) resolve("glUseProgramStages");
+ ValidateProgramPipeline = (void (QOPENGLF_APIENTRYP) (GLuint)) resolve("glValidateProgramPipeline");
+ VertexAttribBinding = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint)) resolve("glVertexAttribBinding");
+ VertexAttribFormat = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLenum, GLboolean, GLuint)) resolve("glVertexAttribFormat");
+ VertexAttribIFormat = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLenum, GLuint)) resolve("glVertexAttribIFormat");
+ VertexBindingDivisor = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint)) resolve("glVertexBindingDivisor");
+
+ if (!ActiveShaderProgram || !BindImageTexture || !DispatchCompute || !DrawArraysIndirect
+ || !GenProgramPipelines || !MemoryBarrierFunc) {
+ qWarning("OpenGL ES 3.1 entry points not found. This is odd because the driver returned a context of version %d.%d",
+ contextVersion.first, contextVersion.second);
+ return;
+ }
+ m_supportedVersion = qMakePair(3, 1);
+ }
+ } else {
+ qFatal("Failed to load libGLESv2");
+ }
+}
+
+// GLES 3.0 and 3.1
+
+// Checks for true OpenGL ES 3.x. OpenGL with GL_ARB_ES3_compatibility
+// does not count because there the plain resolvers work anyhow.
+static inline bool isES3(int minor)
+{
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+
+ const bool libMatches = QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES;
+ const bool contextMatches = ctx->isOpenGLES() && ctx->format().version() >= qMakePair(3, minor);
+
+ // Resolving happens whenever qgles3Helper() is called first. So do it only
+ // when the driver gives a 3.0+ context.
+ if (libMatches && contextMatches)
+ return qgles3Helper()->supportedVersion() >= qMakePair(3, minor);
+
+ return false;
+}
+
+// Go through the dlsym-based helper for real ES 3, resolve using
+// wglGetProcAddress or similar when on plain OpenGL.
+
+static void QOPENGLF_APIENTRY qopenglfResolveBeginQuery(GLenum target, GLuint id)
+{
+ if (isES3(0))
+ qgles3Helper()->BeginQuery(target, id);
+ else
+ RESOLVE_FUNC_VOID(0, BeginQuery)(target, id);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveBeginTransformFeedback(GLenum primitiveMode)
+{
+ if (isES3(0))
+ qgles3Helper()->BeginTransformFeedback(primitiveMode);
+ else
+ RESOLVE_FUNC_VOID(0, BeginTransformFeedback)(primitiveMode);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveBindBufferBase(GLenum target, GLuint index, GLuint buffer)
+{
+ if (isES3(0))
+ qgles3Helper()->BindBufferBase(target, index, buffer);
+ else
+ RESOLVE_FUNC_VOID(0, BindBufferBase)(target, index, buffer);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
+{
+ if (isES3(0))
+ qgles3Helper()->BindBufferRange(target, index, buffer, offset, size);
+ else
+ RESOLVE_FUNC_VOID(0, BindBufferRange)(target, index, buffer, offset, size);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveBindSampler(GLuint unit, GLuint sampler)
+{
+ if (isES3(0))
+ qgles3Helper()->BindSampler(unit, sampler);
+ else
+ RESOLVE_FUNC_VOID(0, BindSampler)(unit, sampler);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveBindTransformFeedback(GLenum target, GLuint id)
+{
+ if (isES3(0))
+ qgles3Helper()->BindTransformFeedback(target, id);
+ else
+ RESOLVE_FUNC_VOID(0, BindTransformFeedback)(target, id);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveBindVertexArray(GLuint array)
+{
+ if (isES3(0))
+ qgles3Helper()->BindVertexArray(array);
+ else
+ RESOLVE_FUNC_VOID(0, BindVertexArray)(array);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
+{
+ if (isES3(0))
+ qgles3Helper()->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+ else
+ RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, BlitFramebuffer)
+ (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
+{
+ if (isES3(0))
+ qgles3Helper()->ClearBufferfi(buffer, drawbuffer, depth, stencil);
+ else
+ RESOLVE_FUNC_VOID(0, ClearBufferfi)(buffer, drawbuffer, depth, stencil);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat * value)
+{
+ if (isES3(0))
+ qgles3Helper()->ClearBufferfv(buffer, drawbuffer, value);
+ else
+ RESOLVE_FUNC_VOID(0, ClearBufferfv)(buffer, drawbuffer, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint * value)
+{
+ if (isES3(0))
+ qgles3Helper()->ClearBufferiv(buffer, drawbuffer, value);
+ else
+ RESOLVE_FUNC_VOID(0, ClearBufferiv)(buffer, drawbuffer, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint * value)
+{
+ if (isES3(0))
+ qgles3Helper()->ClearBufferuiv(buffer, drawbuffer, value);
+ else
+ RESOLVE_FUNC_VOID(0, ClearBufferuiv)(buffer, drawbuffer, value);
+}
+
+static GLenum QOPENGLF_APIENTRY qopenglfResolveClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+ if (isES3(0))
+ return qgles3Helper()->ClientWaitSync(sync, flags, timeout);
+ else
+ RESOLVE_FUNC(GLenum, 0, ClientWaitSync)(sync, flags, timeout);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * data)
+{
+ if (isES3(0))
+ qgles3Helper()->CompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data);
+ else
+ RESOLVE_FUNC_VOID(0, CompressedTexImage3D)(target, level, internalformat, width, height, depth, border, imageSize, data);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data)
+{
+ if (isES3(0))
+ qgles3Helper()->CompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
+ else
+ RESOLVE_FUNC_VOID(0, CompressedTexSubImage3D)(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size)
+{
+ if (isES3(0))
+ qgles3Helper()->CopyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size);
+ else
+ RESOLVE_FUNC_VOID(0, CopyBufferSubData)(readTarget, writeTarget, readOffset, writeOffset, size);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ if (isES3(0))
+ qgles3Helper()->CopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height);
+ else
+ RESOLVE_FUNC_VOID(0, CopyTexSubImage3D)(target, level, xoffset, yoffset, zoffset, x, y, width, height);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveDeleteQueries(GLsizei n, const GLuint * ids)
+{
+ if (isES3(0))
+ qgles3Helper()->DeleteQueries(n, ids);
+ else
+ RESOLVE_FUNC_VOID(0, DeleteQueries)(n, ids);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveDeleteSamplers(GLsizei count, const GLuint * samplers)
+{
+ if (isES3(0))
+ qgles3Helper()->DeleteSamplers(count, samplers);
+ else
+ RESOLVE_FUNC_VOID(0, DeleteSamplers)(count, samplers);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveDeleteSync(GLsync sync)
+{
+ if (isES3(0))
+ qgles3Helper()->DeleteSync(sync);
+ else
+ RESOLVE_FUNC_VOID(0, DeleteSync)(sync);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveDeleteTransformFeedbacks(GLsizei n, const GLuint * ids)
+{
+ if (isES3(0))
+ qgles3Helper()->DeleteTransformFeedbacks(n, ids);
+ else
+ RESOLVE_FUNC_VOID(0, DeleteTransformFeedbacks)(n, ids);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveDeleteVertexArrays(GLsizei n, const GLuint * arrays)
+{
+ if (isES3(0))
+ qgles3Helper()->DeleteVertexArrays(n, arrays);
+ else
+ RESOLVE_FUNC_VOID(0, DeleteVertexArrays)(n, arrays);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount)
+{
+ if (isES3(0))
+ qgles3Helper()->DrawArraysInstanced(mode, first, count, instancecount);
+ else
+ RESOLVE_FUNC_VOID(0, DrawArraysInstanced)(mode, first, count, instancecount);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveDrawBuffers(GLsizei n, const GLenum * bufs)
+{
+ if (isES3(0))
+ qgles3Helper()->DrawBuffers(n, bufs);
+ else
+ RESOLVE_FUNC_VOID(0, DrawBuffers)(n, bufs);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount)
+{
+ if (isES3(0))
+ qgles3Helper()->DrawElementsInstanced(mode, count, type, indices, instancecount);
+ else
+ RESOLVE_FUNC_VOID(0, DrawElementsInstanced)(mode, count, type, indices, instancecount);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices)
+{
+ if (isES3(0))
+ qgles3Helper()->DrawRangeElements(mode, start, end, count, type, indices);
+ else
+ RESOLVE_FUNC_VOID(0, DrawRangeElements)(mode, start, end, count, type, indices);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveEndQuery(GLenum target)
+{
+ if (isES3(0))
+ qgles3Helper()->EndQuery(target);
+ else
+ RESOLVE_FUNC_VOID(0, EndQuery)(target);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveEndTransformFeedback()
+{
+ if (isES3(0))
+ qgles3Helper()->EndTransformFeedback();
+ else
+ RESOLVE_FUNC_VOID(0, EndTransformFeedback)();
+}
+
+static GLsync QOPENGLF_APIENTRY qopenglfResolveFenceSync(GLenum condition, GLbitfield flags)
+{
+ if (isES3(0))
+ return qgles3Helper()->FenceSync(condition, flags);
+ else
+ RESOLVE_FUNC(GLsync, 0, FenceSync)(condition, flags);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
+{
+ if (isES3(0))
+ qgles3Helper()->FlushMappedBufferRange(target, offset, length);
+ else
+ RESOLVE_FUNC_VOID(0, FlushMappedBufferRange)(target, offset, length);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
+{
+ if (isES3(0))
+ qgles3Helper()->FramebufferTextureLayer(target, attachment, texture, level, layer);
+ else
+ RESOLVE_FUNC_VOID(0, FramebufferTextureLayer)(target, attachment, texture, level, layer);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGenQueries(GLsizei n, GLuint* ids)
+{
+ if (isES3(0))
+ qgles3Helper()->GenQueries(n, ids);
+ else
+ RESOLVE_FUNC_VOID(0, GenQueries)(n, ids);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGenSamplers(GLsizei count, GLuint* samplers)
+{
+ if (isES3(0))
+ qgles3Helper()->GenSamplers(count, samplers);
+ else
+ RESOLVE_FUNC_VOID(0, GenSamplers)(count, samplers);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGenTransformFeedbacks(GLsizei n, GLuint* ids)
+{
+ if (isES3(0))
+ qgles3Helper()->GenTransformFeedbacks(n, ids);
+ else
+ RESOLVE_FUNC_VOID(0, GenTransformFeedbacks)(n, ids);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGenVertexArrays(GLsizei n, GLuint* arrays)
+{
+ if (isES3(0))
+ qgles3Helper()->GenVertexArrays(n, arrays);
+ else
+ RESOLVE_FUNC_VOID(0, GenVertexArrays)(n, arrays);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName)
+{
+ if (isES3(0))
+ qgles3Helper()->GetActiveUniformBlockName(program, uniformBlockIndex, bufSize, length, uniformBlockName);
+ else
+ RESOLVE_FUNC_VOID(0, GetActiveUniformBlockName)(program, uniformBlockIndex, bufSize, length, uniformBlockName);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params)
+{
+ if (isES3(0))
+ qgles3Helper()->GetActiveUniformBlockiv(program, uniformBlockIndex, pname, params);
+ else
+ RESOLVE_FUNC_VOID(0, GetActiveUniformBlockiv)(program, uniformBlockIndex, pname, params);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint * uniformIndices, GLenum pname, GLint* params)
+{
+ if (isES3(0))
+ qgles3Helper()->GetActiveUniformsiv(program, uniformCount, uniformIndices, pname, params);
+ else
+ RESOLVE_FUNC_VOID(0, GetActiveUniformsiv)(program, uniformCount, uniformIndices, pname, params);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params)
+{
+ if (isES3(0))
+ qgles3Helper()->GetBufferParameteri64v(target, pname, params);
+ else
+ RESOLVE_FUNC_VOID(0, GetBufferParameteri64v)(target, pname, params);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetBufferPointerv(GLenum target, GLenum pname, void ** params)
+{
+ if (isES3(0))
+ qgles3Helper()->GetBufferPointerv(target, pname, params);
+ else
+ RESOLVE_FUNC_VOID(0, GetBufferPointerv)(target, pname, params);
+}
+
+static GLint QOPENGLF_APIENTRY qopenglfResolveGetFragDataLocation(GLuint program, const GLchar * name)
+{
+ if (isES3(0))
+ return qgles3Helper()->GetFragDataLocation(program, name);
+ else
+ RESOLVE_FUNC(GLint, 0, GetFragDataLocation)(program, name);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetInteger64i_v(GLenum target, GLuint index, GLint64* data)
+{
+ if (isES3(0))
+ qgles3Helper()->GetInteger64i_v(target, index, data);
+ else
+ RESOLVE_FUNC_VOID(0, GetInteger64i_v)(target, index, data);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetInteger64v(GLenum pname, GLint64* data)
+{
+ if (isES3(0))
+ qgles3Helper()->GetInteger64v(pname, data);
+ else
+ RESOLVE_FUNC_VOID(0, GetInteger64v)(pname, data);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetIntegeri_v(GLenum target, GLuint index, GLint* data)
+{
+ if (isES3(0))
+ qgles3Helper()->GetIntegeri_v(target, index, data);
+ else
+ RESOLVE_FUNC_VOID(0, GetIntegeri_v)(target, index, data);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params)
+{
+ if (isES3(0))
+ qgles3Helper()->GetInternalformativ(target, internalformat, pname, bufSize, params);
+ else
+ RESOLVE_FUNC_VOID(0, GetInternalformativ)(target, internalformat, pname, bufSize, params);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, void * binary)
+{
+ if (isES3(0))
+ qgles3Helper()->GetProgramBinary(program, bufSize, length, binaryFormat, binary);
+ else
+ RESOLVE_FUNC_VOID(0, GetProgramBinary)(program, bufSize, length, binaryFormat, binary);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params)
+{
+ if (isES3(0))
+ qgles3Helper()->GetQueryObjectuiv(id, pname, params);
+ else
+ RESOLVE_FUNC_VOID(0, GetQueryObjectuiv)(id, pname, params);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetQueryiv(GLenum target, GLenum pname, GLint* params)
+{
+ if (isES3(0))
+ qgles3Helper()->GetQueryiv(target, pname, params);
+ else
+ RESOLVE_FUNC_VOID(0, GetQueryiv)(target, pname, params);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params)
+{
+ if (isES3(0))
+ qgles3Helper()->GetSamplerParameterfv(sampler, pname, params);
+ else
+ RESOLVE_FUNC_VOID(0, GetSamplerParameterfv)(sampler, pname, params);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params)
+{
+ if (isES3(0))
+ qgles3Helper()->GetSamplerParameteriv(sampler, pname, params);
+ else
+ RESOLVE_FUNC_VOID(0, GetSamplerParameteriv)(sampler, pname, params);
+}
+
+static const GLubyte * QOPENGLF_APIENTRY qopenglfResolveGetStringi(GLenum name, GLuint index)
+{
+ if (isES3(0))
+ return qgles3Helper()->GetStringi(name, index);
+ else
+ RESOLVE_FUNC(const GLubyte *, 0, GetStringi)(name, index);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values)
+{
+ if (isES3(0))
+ qgles3Helper()->GetSynciv(sync, pname, bufSize, length, values);
+ else
+ RESOLVE_FUNC_VOID(0, GetSynciv)(sync, pname, bufSize, length, values);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name)
+{
+ if (isES3(0))
+ qgles3Helper()->GetTransformFeedbackVarying(program, index, bufSize, length, size, type, name);
+ else
+ RESOLVE_FUNC_VOID(0, GetTransformFeedbackVarying)(program, index, bufSize, length, size, type, name);
+}
+
+static GLuint QOPENGLF_APIENTRY qopenglfResolveGetUniformBlockIndex(GLuint program, const GLchar * uniformBlockName)
+{
+ if (isES3(0))
+ return qgles3Helper()->GetUniformBlockIndex(program, uniformBlockName);
+ else
+ RESOLVE_FUNC(GLuint, 0, GetUniformBlockIndex)(program, uniformBlockName);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar *const* uniformNames, GLuint* uniformIndices)
+{
+ if (isES3(0))
+ qgles3Helper()->GetUniformIndices(program, uniformCount, uniformNames, uniformIndices);
+ else
+ RESOLVE_FUNC_VOID(0, GetUniformIndices)(program, uniformCount, uniformNames, uniformIndices);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetUniformuiv(GLuint program, GLint location, GLuint* params)
+{
+ if (isES3(0))
+ qgles3Helper()->GetUniformuiv(program, location, params);
+ else
+ RESOLVE_FUNC_VOID(0, GetUniformuiv)(program, location, params);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params)
+{
+ if (isES3(0))
+ qgles3Helper()->GetVertexAttribIiv(index, pname, params);
+ else
+ RESOLVE_FUNC_VOID(0, GetVertexAttribIiv)(index, pname, params);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params)
+{
+ if (isES3(0))
+ qgles3Helper()->GetVertexAttribIuiv(index, pname, params);
+ else
+ RESOLVE_FUNC_VOID(0, GetVertexAttribIuiv)(index, pname, params);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum * attachments)
+{
+ if (isES3(0))
+ qgles3Helper()->InvalidateFramebuffer(target, numAttachments, attachments);
+ else
+ RESOLVE_FUNC_VOID(0, InvalidateFramebuffer)(target, numAttachments, attachments);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ if (isES3(0))
+ qgles3Helper()->InvalidateSubFramebuffer(target, numAttachments, attachments, x, y, width, height);
+ else
+ RESOLVE_FUNC_VOID(0, InvalidateSubFramebuffer)(target, numAttachments, attachments, x, y, width, height);
+}
+
+static GLboolean QOPENGLF_APIENTRY qopenglfResolveIsQuery(GLuint id)
+{
+ if (isES3(0))
+ return qgles3Helper()->IsQuery(id);
+ else
+ RESOLVE_FUNC(GLboolean, 0, IsQuery)(id);
+}
+
+static GLboolean QOPENGLF_APIENTRY qopenglfResolveIsSampler(GLuint sampler)
+{
+ if (isES3(0))
+ return qgles3Helper()->IsSampler(sampler);
+ else
+ RESOLVE_FUNC(GLboolean, 0, IsSampler)(sampler);
+}
+
+static GLboolean QOPENGLF_APIENTRY qopenglfResolveIsSync(GLsync sync)
+{
+ if (isES3(0))
+ return qgles3Helper()->IsSync(sync);
+ else
+ RESOLVE_FUNC(GLboolean, 0, IsSync)(sync);
+}
+
+static GLboolean QOPENGLF_APIENTRY qopenglfResolveIsTransformFeedback(GLuint id)
+{
+ if (isES3(0))
+ return qgles3Helper()->IsTransformFeedback(id);
+ else
+ RESOLVE_FUNC(GLboolean, 0, IsTransformFeedback)(id);
+}
+
+static GLboolean QOPENGLF_APIENTRY qopenglfResolveIsVertexArray(GLuint array)
+{
+ if (isES3(0))
+ return qgles3Helper()->IsVertexArray(array);
+ else
+ RESOLVE_FUNC(GLboolean, 0, IsVertexArray)(array);
+}
+
+static void * QOPENGLF_APIENTRY qopenglfResolveMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
+{
+ if (isES3(0))
+ return qgles3Helper()->MapBufferRange(target, offset, length, access);
+ else
+ RESOLVE_FUNC(void *, 0, MapBufferRange)(target, offset, length, access);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolvePauseTransformFeedback()
+{
+ if (isES3(0))
+ qgles3Helper()->PauseTransformFeedback();
+ else
+ RESOLVE_FUNC_VOID(0, PauseTransformFeedback)();
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramBinary(GLuint program, GLenum binaryFormat, const void * binary, GLsizei length)
+{
+ if (isES3(0))
+ qgles3Helper()->ProgramBinary(program, binaryFormat, binary, length);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramBinary)(program, binaryFormat, binary, length);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramParameteri(GLuint program, GLenum pname, GLint value)
+{
+ if (isES3(0))
+ qgles3Helper()->ProgramParameteri(program, pname, value);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramParameteri)(program, pname, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveReadBuffer(GLenum src)
+{
+ if (isES3(0))
+ qgles3Helper()->ReadBuffer(src);
+ else
+ RESOLVE_FUNC_VOID(0, ReadBuffer)(src);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ if (isES3(0))
+ qgles3Helper()->RenderbufferStorageMultisample(target, samples, internalformat, width, height);
+ else
+ RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, RenderbufferStorageMultisample)
+ (target, samples, internalformat, width, height);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveResumeTransformFeedback()
+{
+ if (isES3(0))
+ qgles3Helper()->ResumeTransformFeedback();
+ else
+ RESOLVE_FUNC_VOID(0, ResumeTransformFeedback)();
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
+{
+ if (isES3(0))
+ qgles3Helper()->SamplerParameterf(sampler, pname, param);
+ else
+ RESOLVE_FUNC_VOID(0, SamplerParameterf)(sampler, pname, param);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat * param)
+{
+ if (isES3(0))
+ qgles3Helper()->SamplerParameterfv(sampler, pname, param);
+ else
+ RESOLVE_FUNC_VOID(0, SamplerParameterfv)(sampler, pname, param);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveSamplerParameteri(GLuint sampler, GLenum pname, GLint param)
+{
+ if (isES3(0))
+ qgles3Helper()->SamplerParameteri(sampler, pname, param);
+ else
+ RESOLVE_FUNC_VOID(0, SamplerParameteri)(sampler, pname, param);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveSamplerParameteriv(GLuint sampler, GLenum pname, const GLint * param)
+{
+ if (isES3(0))
+ qgles3Helper()->SamplerParameteriv(sampler, pname, param);
+ else
+ RESOLVE_FUNC_VOID(0, SamplerParameteriv)(sampler, pname, param);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels)
+{
+ if (isES3(0))
+ qgles3Helper()->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
+ else
+ RESOLVE_FUNC_VOID(0, TexImage3D)(target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ if (isES3(0))
+ qgles3Helper()->TexStorage2D(target, levels, internalformat, width, height);
+ else
+ RESOLVE_FUNC_VOID(0, TexStorage2D)(target, levels, internalformat, width, height);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+{
+ if (isES3(0))
+ qgles3Helper()->TexStorage3D(target, levels, internalformat, width, height, depth);
+ else
+ RESOLVE_FUNC_VOID(0, TexStorage3D)(target, levels, internalformat, width, height, depth);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels)
+{
+ if (isES3(0))
+ qgles3Helper()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
+ else
+ RESOLVE_FUNC_VOID(0, TexSubImage3D)(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode)
+{
+ if (isES3(0))
+ qgles3Helper()->TransformFeedbackVaryings(program, count, varyings, bufferMode);
+ else
+ RESOLVE_FUNC_VOID(0, TransformFeedbackVaryings)(program, count, varyings, bufferMode);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniform1ui(GLint location, GLuint v0)
+{
+ if (isES3(0))
+ qgles3Helper()->Uniform1ui(location, v0);
+ else
+ RESOLVE_FUNC_VOID(0, Uniform1ui)(location, v0);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniform1uiv(GLint location, GLsizei count, const GLuint * value)
+{
+ if (isES3(0))
+ qgles3Helper()->Uniform1uiv(location, count, value);
+ else
+ RESOLVE_FUNC_VOID(0, Uniform1uiv)(location, count, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniform2ui(GLint location, GLuint v0, GLuint v1)
+{
+ if (isES3(0))
+ qgles3Helper()->Uniform2ui(location, v0, v1);
+ else
+ RESOLVE_FUNC_VOID(0, Uniform2ui)(location, v0, v1);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniform2uiv(GLint location, GLsizei count, const GLuint * value)
+{
+ if (isES3(0))
+ qgles3Helper()->Uniform2uiv(location, count, value);
+ else
+ RESOLVE_FUNC_VOID(0, Uniform2uiv)(location, count, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
+{
+ if (isES3(0))
+ qgles3Helper()->Uniform3ui(location, v0, v1, v2);
+ else
+ RESOLVE_FUNC_VOID(0, Uniform3ui)(location, v0, v1, v2);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniform3uiv(GLint location, GLsizei count, const GLuint * value)
+{
+ if (isES3(0))
+ qgles3Helper()->Uniform3uiv(location, count, value);
+ else
+ RESOLVE_FUNC_VOID(0, Uniform3uiv)(location, count, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+{
+ if (isES3(0))
+ qgles3Helper()->Uniform4ui(location, v0, v1, v2, v3);
+ else
+ RESOLVE_FUNC_VOID(0, Uniform4ui)(location, v0, v1, v2, v3);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniform4uiv(GLint location, GLsizei count, const GLuint * value)
+{
+ if (isES3(0))
+ qgles3Helper()->Uniform4uiv(location, count, value);
+ else
+ RESOLVE_FUNC_VOID(0, Uniform4uiv)(location, count, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
+{
+ if (isES3(0))
+ qgles3Helper()->UniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding);
+ else
+ RESOLVE_FUNC_VOID(0, UniformBlockBinding)(program, uniformBlockIndex, uniformBlockBinding);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ if (isES3(0))
+ qgles3Helper()->UniformMatrix2x3fv(location, count, transpose, value);
+ else
+ RESOLVE_FUNC_VOID(0, UniformMatrix2x3fv)(location, count, transpose, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ if (isES3(0))
+ qgles3Helper()->UniformMatrix2x4fv(location, count, transpose, value);
+ else
+ RESOLVE_FUNC_VOID(0, UniformMatrix2x4fv)(location, count, transpose, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ if (isES3(0))
+ qgles3Helper()->UniformMatrix3x2fv(location, count, transpose, value);
+ else
+ RESOLVE_FUNC_VOID(0, UniformMatrix3x2fv)(location, count, transpose, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ if (isES3(0))
+ qgles3Helper()->UniformMatrix3x4fv(location, count, transpose, value);
+ else
+ RESOLVE_FUNC_VOID(0, UniformMatrix3x4fv)(location, count, transpose, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ if (isES3(0))
+ qgles3Helper()->UniformMatrix4x2fv(location, count, transpose, value);
+ else
+ RESOLVE_FUNC_VOID(0, UniformMatrix4x2fv)(location, count, transpose, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ if (isES3(0))
+ qgles3Helper()->UniformMatrix4x3fv(location, count, transpose, value);
+ else
+ RESOLVE_FUNC_VOID(0, UniformMatrix4x3fv)(location, count, transpose, value);
+}
+
+static GLboolean QOPENGLF_APIENTRY qopenglfResolveUnmapBuffer(GLenum target)
+{
+ if (isES3(0))
+ return qgles3Helper()->UnmapBuffer(target);
+ else
+ RESOLVE_FUNC(GLboolean, ResolveOES, UnmapBuffer)(target);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribDivisor(GLuint index, GLuint divisor)
+{
+ if (isES3(0))
+ qgles3Helper()->VertexAttribDivisor(index, divisor);
+ else
+ RESOLVE_FUNC_VOID(0, VertexAttribDivisor)(index, divisor);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
+{
+ if (isES3(0))
+ qgles3Helper()->VertexAttribI4i(index, x, y, z, w);
+ else
+ RESOLVE_FUNC_VOID(0, VertexAttribI4i)(index, x, y, z, w);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribI4iv(GLuint index, const GLint * v)
+{
+ if (isES3(0))
+ qgles3Helper()->VertexAttribI4iv(index, v);
+ else
+ RESOLVE_FUNC_VOID(0, VertexAttribI4iv)(index, v);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
+{
+ if (isES3(0))
+ qgles3Helper()->VertexAttribI4ui(index, x, y, z, w);
+ else
+ RESOLVE_FUNC_VOID(0, VertexAttribI4ui)(index, x, y, z, w);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribI4uiv(GLuint index, const GLuint * v)
+{
+ if (isES3(0))
+ qgles3Helper()->VertexAttribI4uiv(index, v);
+ else
+ RESOLVE_FUNC_VOID(0, VertexAttribI4uiv)(index, v);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer)
+{
+ if (isES3(0))
+ qgles3Helper()->VertexAttribIPointer(index, size, type, stride, pointer);
+ else
+ RESOLVE_FUNC_VOID(0, VertexAttribIPointer)(index, size, type, stride, pointer);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+ if (isES3(0))
+ qgles3Helper()->WaitSync(sync, flags, timeout);
+ else
+ RESOLVE_FUNC_VOID(0, WaitSync)(sync, flags, timeout);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveActiveShaderProgram(GLuint pipeline, GLuint program)
+{
+ if (isES3(1))
+ qgles3Helper()->ActiveShaderProgram(pipeline, program);
+ else
+ RESOLVE_FUNC_VOID(0, ActiveShaderProgram)(pipeline, program);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveBindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format)
+{
+ if (isES3(1))
+ qgles3Helper()->BindImageTexture(unit, texture, level, layered, layer, access, format);
+ else
+ RESOLVE_FUNC_VOID(0, BindImageTexture)(unit, texture, level, layered, layer, access, format);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveBindProgramPipeline(GLuint pipeline)
+{
+ if (isES3(1))
+ qgles3Helper()->BindProgramPipeline(pipeline);
+ else
+ RESOLVE_FUNC_VOID(0, BindProgramPipeline)(pipeline);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveBindVertexBuffer(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride)
+{
+ if (isES3(1))
+ qgles3Helper()->BindVertexBuffer(bindingindex, buffer, offset, stride);
+ else
+ RESOLVE_FUNC_VOID(0, BindVertexBuffer)(bindingindex, buffer, offset, stride);
+}
+
+static GLuint QOPENGLF_APIENTRY qopenglfResolveCreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const* strings)
+{
+ if (isES3(1))
+ return qgles3Helper()->CreateShaderProgramv(type, count, strings);
+ else
+ RESOLVE_FUNC(GLuint, 0, CreateShaderProgramv)(type, count, strings);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveDeleteProgramPipelines(GLsizei n, const GLuint * pipelines)
+{
+ if (isES3(1))
+ qgles3Helper()->DeleteProgramPipelines(n, pipelines);
+ else
+ RESOLVE_FUNC_VOID(0, DeleteProgramPipelines)(n, pipelines);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z)
+{
+ if (isES3(1))
+ qgles3Helper()->DispatchCompute(num_groups_x, num_groups_y, num_groups_z);
+ else
+ RESOLVE_FUNC_VOID(0, DispatchCompute)(num_groups_x, num_groups_y, num_groups_z);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveDispatchComputeIndirect(GLintptr indirect)
+{
+ if (isES3(1))
+ qgles3Helper()->DispatchComputeIndirect(indirect);
+ else
+ RESOLVE_FUNC_VOID(0, DispatchComputeIndirect)(indirect);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveDrawArraysIndirect(GLenum mode, const void * indirect)
+{
+ if (isES3(1))
+ qgles3Helper()->DrawArraysIndirect(mode, indirect);
+ else
+ RESOLVE_FUNC_VOID(0, DrawArraysIndirect)(mode, indirect);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveDrawElementsIndirect(GLenum mode, GLenum type, const void * indirect)
+{
+ if (isES3(1))
+ qgles3Helper()->DrawElementsIndirect(mode, type, indirect);
+ else
+ RESOLVE_FUNC_VOID(0, DrawElementsIndirect)(mode, type, indirect);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveFramebufferParameteri(GLenum target, GLenum pname, GLint param)
+{
+ if (isES3(1))
+ qgles3Helper()->FramebufferParameteri(target, pname, param);
+ else
+ RESOLVE_FUNC_VOID(0, FramebufferParameteri)(target, pname, param);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGenProgramPipelines(GLsizei n, GLuint* pipelines)
+{
+ if (isES3(1))
+ qgles3Helper()->GenProgramPipelines(n, pipelines);
+ else
+ RESOLVE_FUNC_VOID(0, GenProgramPipelines)(n, pipelines);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetBooleani_v(GLenum target, GLuint index, GLboolean* data)
+{
+ if (isES3(1))
+ qgles3Helper()->GetBooleani_v(target, index, data);
+ else
+ RESOLVE_FUNC_VOID(0, GetBooleani_v)(target, index, data);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetFramebufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+ if (isES3(1))
+ qgles3Helper()->GetFramebufferParameteriv(target, pname, params);
+ else
+ RESOLVE_FUNC_VOID(0, GetFramebufferParameteriv)(target, pname, params);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetMultisamplefv(GLenum pname, GLuint index, GLfloat* val)
+{
+ if (isES3(1))
+ qgles3Helper()->GetMultisamplefv(pname, index, val);
+ else
+ RESOLVE_FUNC_VOID(0, GetMultisamplefv)(pname, index, val);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, GLint* params)
+{
+ if (isES3(1))
+ qgles3Helper()->GetProgramInterfaceiv(program, programInterface, pname, params);
+ else
+ RESOLVE_FUNC_VOID(0, GetProgramInterfaceiv)(program, programInterface, pname, params);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar* infoLog)
+{
+ if (isES3(1))
+ qgles3Helper()->GetProgramPipelineInfoLog(pipeline, bufSize, length, infoLog);
+ else
+ RESOLVE_FUNC_VOID(0, GetProgramPipelineInfoLog)(pipeline, bufSize, length, infoLog);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint* params)
+{
+ if (isES3(1))
+ qgles3Helper()->GetProgramPipelineiv(pipeline, pname, params);
+ else
+ RESOLVE_FUNC_VOID(0, GetProgramPipelineiv)(pipeline, pname, params);
+}
+
+static GLuint QOPENGLF_APIENTRY qopenglfResolveGetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar * name)
+{
+ if (isES3(1))
+ return qgles3Helper()->GetProgramResourceIndex(program, programInterface, name);
+ else
+ RESOLVE_FUNC(GLuint, 0, GetProgramResourceIndex)(program, programInterface, name);
+}
+
+static GLint QOPENGLF_APIENTRY qopenglfResolveGetProgramResourceLocation(GLuint program, GLenum programInterface, const GLchar * name)
+{
+ if (isES3(1))
+ return qgles3Helper()->GetProgramResourceLocation(program, programInterface, name);
+ else
+ RESOLVE_FUNC(GLint, 0, GetProgramResourceLocation)(program, programInterface, name);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetProgramResourceName(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, GLchar* name)
+{
+ if (isES3(1))
+ qgles3Helper()->GetProgramResourceName(program, programInterface, index, bufSize, length, name);
+ else
+ RESOLVE_FUNC_VOID(0, GetProgramResourceName)(program, programInterface, index, bufSize, length, name);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei bufSize, GLsizei* length, GLint* params)
+{
+ if (isES3(1))
+ qgles3Helper()->GetProgramResourceiv(program, programInterface, index, propCount, props, bufSize, length, params);
+ else
+ RESOLVE_FUNC_VOID(0, GetProgramResourceiv)(program, programInterface, index, propCount, props, bufSize, length, params);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat* params)
+{
+ if (isES3(1))
+ qgles3Helper()->GetTexLevelParameterfv(target, level, pname, params);
+ else
+ RESOLVE_FUNC_VOID(0, GetTexLevelParameterfv)(target, level, pname, params);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params)
+{
+ if (isES3(1))
+ qgles3Helper()->GetTexLevelParameteriv(target, level, pname, params);
+ else
+ RESOLVE_FUNC_VOID(0, GetTexLevelParameteriv)(target, level, pname, params);
+}
+
+static GLboolean QOPENGLF_APIENTRY qopenglfResolveIsProgramPipeline(GLuint pipeline)
+{
+ if (isES3(1))
+ return qgles3Helper()->IsProgramPipeline(pipeline);
+ else
+ RESOLVE_FUNC(GLboolean, 0, IsProgramPipeline)(pipeline);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveMemoryBarrier(GLbitfield barriers)
+{
+ if (isES3(1))
+ qgles3Helper()->MemoryBarrierFunc(barriers);
+ else
+ RESOLVE_FUNC_VOID(0, MemoryBarrierFunc)(barriers);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveMemoryBarrierByRegion(GLbitfield barriers)
+{
+ if (isES3(1))
+ qgles3Helper()->MemoryBarrierByRegion(barriers);
+ else
+ RESOLVE_FUNC_VOID(0, MemoryBarrierByRegion)(barriers);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform1f(GLuint program, GLint location, GLfloat v0)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniform1f(program, location, v0);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniform1f)(program, location, v0);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform1fv(GLuint program, GLint location, GLsizei count, const GLfloat * value)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniform1fv(program, location, count, value);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniform1fv)(program, location, count, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform1i(GLuint program, GLint location, GLint v0)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniform1i(program, location, v0);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniform1i)(program, location, v0);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform1iv(GLuint program, GLint location, GLsizei count, const GLint * value)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniform1iv(program, location, count, value);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniform1iv)(program, location, count, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform1ui(GLuint program, GLint location, GLuint v0)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniform1ui(program, location, v0);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniform1ui)(program, location, v0);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform1uiv(GLuint program, GLint location, GLsizei count, const GLuint * value)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniform1uiv(program, location, count, value);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniform1uiv)(program, location, count, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniform2f(program, location, v0, v1);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniform2f)(program, location, v0, v1);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform2fv(GLuint program, GLint location, GLsizei count, const GLfloat * value)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniform2fv(program, location, count, value);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniform2fv)(program, location, count, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniform2i(program, location, v0, v1);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniform2i)(program, location, v0, v1);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform2iv(GLuint program, GLint location, GLsizei count, const GLint * value)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniform2iv(program, location, count, value);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniform2iv)(program, location, count, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniform2ui(program, location, v0, v1);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniform2ui)(program, location, v0, v1);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform2uiv(GLuint program, GLint location, GLsizei count, const GLuint * value)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniform2uiv(program, location, count, value);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniform2uiv)(program, location, count, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniform3f(program, location, v0, v1, v2);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniform3f)(program, location, v0, v1, v2);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform3fv(GLuint program, GLint location, GLsizei count, const GLfloat * value)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniform3fv(program, location, count, value);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniform3fv)(program, location, count, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniform3i(program, location, v0, v1, v2);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniform3i)(program, location, v0, v1, v2);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform3iv(GLuint program, GLint location, GLsizei count, const GLint * value)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniform3iv(program, location, count, value);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniform3iv)(program, location, count, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniform3ui(program, location, v0, v1, v2);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniform3ui)(program, location, v0, v1, v2);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform3uiv(GLuint program, GLint location, GLsizei count, const GLuint * value)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniform3uiv(program, location, count, value);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniform3uiv)(program, location, count, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniform4f(program, location, v0, v1, v2, v3);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniform4f)(program, location, v0, v1, v2, v3);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform4fv(GLuint program, GLint location, GLsizei count, const GLfloat * value)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniform4fv(program, location, count, value);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniform4fv)(program, location, count, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniform4i(program, location, v0, v1, v2, v3);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniform4i)(program, location, v0, v1, v2, v3);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform4iv(GLuint program, GLint location, GLsizei count, const GLint * value)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniform4iv(program, location, count, value);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniform4iv)(program, location, count, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniform4ui(program, location, v0, v1, v2, v3);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniform4ui)(program, location, v0, v1, v2, v3);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform4uiv(GLuint program, GLint location, GLsizei count, const GLuint * value)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniform4uiv(program, location, count, value);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniform4uiv)(program, location, count, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniformMatrix2fv(program, location, count, transpose, value);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniformMatrix2fv)(program, location, count, transpose, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniformMatrix2x3fv(program, location, count, transpose, value);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniformMatrix2x3fv)(program, location, count, transpose, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniformMatrix2x4fv(program, location, count, transpose, value);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniformMatrix2x4fv)(program, location, count, transpose, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniformMatrix3fv(program, location, count, transpose, value);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniformMatrix3fv)(program, location, count, transpose, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniformMatrix3x2fv(program, location, count, transpose, value);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniformMatrix3x2fv)(program, location, count, transpose, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniformMatrix3x4fv(program, location, count, transpose, value);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniformMatrix3x4fv)(program, location, count, transpose, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniformMatrix4fv(program, location, count, transpose, value);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniformMatrix4fv)(program, location, count, transpose, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniformMatrix4x2fv(program, location, count, transpose, value);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniformMatrix4x2fv)(program, location, count, transpose, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ if (isES3(1))
+ qgles3Helper()->ProgramUniformMatrix4x3fv(program, location, count, transpose, value);
+ else
+ RESOLVE_FUNC_VOID(0, ProgramUniformMatrix4x3fv)(program, location, count, transpose, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveSampleMaski(GLuint maskNumber, GLbitfield mask)
+{
+ if (isES3(1))
+ qgles3Helper()->SampleMaski(maskNumber, mask);
+ else
+ RESOLVE_FUNC_VOID(0, SampleMaski)(maskNumber, mask);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveTexStorage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations)
+{
+ if (isES3(1))
+ qgles3Helper()->TexStorage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations);
+ else
+ RESOLVE_FUNC_VOID(0, TexStorage2DMultisample)(target, samples, internalformat, width, height, fixedsamplelocations);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
+{
+ if (isES3(1))
+ qgles3Helper()->UseProgramStages(pipeline, stages, program);
+ else
+ RESOLVE_FUNC_VOID(0, UseProgramStages)(pipeline, stages, program);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveValidateProgramPipeline(GLuint pipeline)
+{
+ if (isES3(1))
+ qgles3Helper()->ValidateProgramPipeline(pipeline);
+ else
+ RESOLVE_FUNC_VOID(0, ValidateProgramPipeline)(pipeline);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribBinding(GLuint attribindex, GLuint bindingindex)
+{
+ if (isES3(1))
+ qgles3Helper()->VertexAttribBinding(attribindex, bindingindex);
+ else
+ RESOLVE_FUNC_VOID(0, VertexAttribBinding)(attribindex, bindingindex);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribFormat(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset)
+{
+ if (isES3(1))
+ qgles3Helper()->VertexAttribFormat(attribindex, size, type, normalized, relativeoffset);
+ else
+ RESOLVE_FUNC_VOID(0, VertexAttribFormat)(attribindex, size, type, normalized, relativeoffset);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribIFormat(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset)
+{
+ if (isES3(1))
+ qgles3Helper()->VertexAttribIFormat(attribindex, size, type, relativeoffset);
+ else
+ RESOLVE_FUNC_VOID(0, VertexAttribIFormat)(attribindex, size, type, relativeoffset);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveVertexBindingDivisor(GLuint bindingindex, GLuint divisor)
+{
+ if (isES3(1))
+ qgles3Helper()->VertexBindingDivisor(bindingindex, divisor);
+ else
+ RESOLVE_FUNC_VOID(0, VertexBindingDivisor)(bindingindex, divisor);
+}
+
+/*!
+ Constructs a default function resolver. The resolver cannot be used until
+ \l {QOpenGLFunctions::}{initializeOpenGLFunctions()} is called to specify
+ the context.
+*/
+QOpenGLExtraFunctions::QOpenGLExtraFunctions()
+{
+}
+
+/*!
+ Constructs a function resolver for context. If \a context is null, then
+ the resolver will be created for the current QOpenGLContext.
+
+ The context or another context in the group must be current.
+
+ An object constructed in this way can only be used with context and other
+ contexts that share with it. Use \l {QOpenGLFunctions::}
+ {initializeOpenGLFunctions()} to change the object's context association.
+*/
+QOpenGLExtraFunctions::QOpenGLExtraFunctions(QOpenGLContext *context)
+ : QOpenGLFunctions(context)
+{
+}
+
+QOpenGLExtraFunctionsPrivate::QOpenGLExtraFunctionsPrivate(QOpenGLContext *ctx)
+ : QOpenGLFunctionsPrivate(ctx)
+{
+ ReadBuffer = qopenglfResolveReadBuffer;
+ DrawRangeElements = qopenglfResolveDrawRangeElements;
+ TexImage3D = qopenglfResolveTexImage3D;
+ TexSubImage3D = qopenglfResolveTexSubImage3D;
+ CopyTexSubImage3D = qopenglfResolveCopyTexSubImage3D;
+ CompressedTexImage3D = qopenglfResolveCompressedTexImage3D;
+ CompressedTexSubImage3D = qopenglfResolveCompressedTexSubImage3D;
+ GenQueries = qopenglfResolveGenQueries;
+ DeleteQueries = qopenglfResolveDeleteQueries;
+ IsQuery = qopenglfResolveIsQuery;
+ BeginQuery = qopenglfResolveBeginQuery;
+ EndQuery = qopenglfResolveEndQuery;
+ GetQueryiv = qopenglfResolveGetQueryiv;
+ GetQueryObjectuiv = qopenglfResolveGetQueryObjectuiv;
UnmapBuffer = qopenglfResolveUnmapBuffer;
+ GetBufferPointerv = qopenglfResolveGetBufferPointerv;
+ DrawBuffers = qopenglfResolveDrawBuffers;
+ UniformMatrix2x3fv = qopenglfResolveUniformMatrix2x3fv;
+ UniformMatrix3x2fv = qopenglfResolveUniformMatrix3x2fv;
+ UniformMatrix2x4fv = qopenglfResolveUniformMatrix2x4fv;
+ UniformMatrix4x2fv = qopenglfResolveUniformMatrix4x2fv;
+ UniformMatrix3x4fv = qopenglfResolveUniformMatrix3x4fv;
+ UniformMatrix4x3fv = qopenglfResolveUniformMatrix4x3fv;
BlitFramebuffer = qopenglfResolveBlitFramebuffer;
RenderbufferStorageMultisample = qopenglfResolveRenderbufferStorageMultisample;
+ FramebufferTextureLayer = qopenglfResolveFramebufferTextureLayer;
+ MapBufferRange = qopenglfResolveMapBufferRange;
+ FlushMappedBufferRange = qopenglfResolveFlushMappedBufferRange;
+ BindVertexArray = qopenglfResolveBindVertexArray;
+ DeleteVertexArrays = qopenglfResolveDeleteVertexArrays;
+ GenVertexArrays = qopenglfResolveGenVertexArrays;
+ IsVertexArray = qopenglfResolveIsVertexArray;
+ GetIntegeri_v = qopenglfResolveGetIntegeri_v;
+ BeginTransformFeedback = qopenglfResolveBeginTransformFeedback;
+ EndTransformFeedback = qopenglfResolveEndTransformFeedback;
+ BindBufferRange = qopenglfResolveBindBufferRange;
+ BindBufferBase = qopenglfResolveBindBufferBase;
+ TransformFeedbackVaryings = qopenglfResolveTransformFeedbackVaryings;
+ GetTransformFeedbackVarying = qopenglfResolveGetTransformFeedbackVarying;
+ VertexAttribIPointer = qopenglfResolveVertexAttribIPointer;
+ GetVertexAttribIiv = qopenglfResolveGetVertexAttribIiv;
+ GetVertexAttribIuiv = qopenglfResolveGetVertexAttribIuiv;
+ VertexAttribI4i = qopenglfResolveVertexAttribI4i;
+ VertexAttribI4ui = qopenglfResolveVertexAttribI4ui;
+ VertexAttribI4iv = qopenglfResolveVertexAttribI4iv;
+ VertexAttribI4uiv = qopenglfResolveVertexAttribI4uiv;
+ GetUniformuiv = qopenglfResolveGetUniformuiv;
+ GetFragDataLocation = qopenglfResolveGetFragDataLocation;
+ Uniform1ui = qopenglfResolveUniform1ui;
+ Uniform2ui = qopenglfResolveUniform2ui;
+ Uniform3ui = qopenglfResolveUniform3ui;
+ Uniform4ui = qopenglfResolveUniform4ui;
+ Uniform1uiv = qopenglfResolveUniform1uiv;
+ Uniform2uiv = qopenglfResolveUniform2uiv;
+ Uniform3uiv = qopenglfResolveUniform3uiv;
+ Uniform4uiv = qopenglfResolveUniform4uiv;
+ ClearBufferiv = qopenglfResolveClearBufferiv;
+ ClearBufferuiv = qopenglfResolveClearBufferuiv;
+ ClearBufferfv = qopenglfResolveClearBufferfv;
+ ClearBufferfi = qopenglfResolveClearBufferfi;
+ GetStringi = qopenglfResolveGetStringi;
+ CopyBufferSubData = qopenglfResolveCopyBufferSubData;
+ GetUniformIndices = qopenglfResolveGetUniformIndices;
+ GetActiveUniformsiv = qopenglfResolveGetActiveUniformsiv;
+ GetUniformBlockIndex = qopenglfResolveGetUniformBlockIndex;
+ GetActiveUniformBlockiv = qopenglfResolveGetActiveUniformBlockiv;
+ GetActiveUniformBlockName = qopenglfResolveGetActiveUniformBlockName;
+ UniformBlockBinding = qopenglfResolveUniformBlockBinding;
+ DrawArraysInstanced = qopenglfResolveDrawArraysInstanced;
+ DrawElementsInstanced = qopenglfResolveDrawElementsInstanced;
+ FenceSync = qopenglfResolveFenceSync;
+ IsSync = qopenglfResolveIsSync;
+ DeleteSync = qopenglfResolveDeleteSync;
+ ClientWaitSync = qopenglfResolveClientWaitSync;
+ WaitSync = qopenglfResolveWaitSync;
+ GetInteger64v = qopenglfResolveGetInteger64v;
+ GetSynciv = qopenglfResolveGetSynciv;
+ GetInteger64i_v = qopenglfResolveGetInteger64i_v;
+ GetBufferParameteri64v = qopenglfResolveGetBufferParameteri64v;
+ GenSamplers = qopenglfResolveGenSamplers;
+ DeleteSamplers = qopenglfResolveDeleteSamplers;
+ IsSampler = qopenglfResolveIsSampler;
+ BindSampler = qopenglfResolveBindSampler;
+ SamplerParameteri = qopenglfResolveSamplerParameteri;
+ SamplerParameteriv = qopenglfResolveSamplerParameteriv;
+ SamplerParameterf = qopenglfResolveSamplerParameterf;
+ SamplerParameterfv = qopenglfResolveSamplerParameterfv;
+ GetSamplerParameteriv = qopenglfResolveGetSamplerParameteriv;
+ GetSamplerParameterfv = qopenglfResolveGetSamplerParameterfv;
+ VertexAttribDivisor = qopenglfResolveVertexAttribDivisor;
+ BindTransformFeedback = qopenglfResolveBindTransformFeedback;
+ DeleteTransformFeedbacks = qopenglfResolveDeleteTransformFeedbacks;
+ GenTransformFeedbacks = qopenglfResolveGenTransformFeedbacks;
+ IsTransformFeedback = qopenglfResolveIsTransformFeedback;
+ PauseTransformFeedback = qopenglfResolvePauseTransformFeedback;
+ ResumeTransformFeedback = qopenglfResolveResumeTransformFeedback;
+ GetProgramBinary = qopenglfResolveGetProgramBinary;
+ ProgramBinary = qopenglfResolveProgramBinary;
+ ProgramParameteri = qopenglfResolveProgramParameteri;
+ InvalidateFramebuffer = qopenglfResolveInvalidateFramebuffer;
+ InvalidateSubFramebuffer = qopenglfResolveInvalidateSubFramebuffer;
+ TexStorage2D = qopenglfResolveTexStorage2D;
+ TexStorage3D = qopenglfResolveTexStorage3D;
+ GetInternalformativ = qopenglfResolveGetInternalformativ;
+
+ DispatchCompute = qopenglfResolveDispatchCompute;
+ DispatchComputeIndirect = qopenglfResolveDispatchComputeIndirect;
+ DrawArraysIndirect = qopenglfResolveDrawArraysIndirect;
+ DrawElementsIndirect = qopenglfResolveDrawElementsIndirect;
+ FramebufferParameteri = qopenglfResolveFramebufferParameteri;
+ GetFramebufferParameteriv = qopenglfResolveGetFramebufferParameteriv;
+ GetProgramInterfaceiv = qopenglfResolveGetProgramInterfaceiv;
+ GetProgramResourceIndex = qopenglfResolveGetProgramResourceIndex;
+ GetProgramResourceName = qopenglfResolveGetProgramResourceName;
+ GetProgramResourceiv = qopenglfResolveGetProgramResourceiv;
+ GetProgramResourceLocation = qopenglfResolveGetProgramResourceLocation;
+ UseProgramStages = qopenglfResolveUseProgramStages;
+ ActiveShaderProgram = qopenglfResolveActiveShaderProgram;
+ CreateShaderProgramv = qopenglfResolveCreateShaderProgramv;
+ BindProgramPipeline = qopenglfResolveBindProgramPipeline;
+ DeleteProgramPipelines = qopenglfResolveDeleteProgramPipelines;
+ GenProgramPipelines = qopenglfResolveGenProgramPipelines;
+ IsProgramPipeline = qopenglfResolveIsProgramPipeline;
+ GetProgramPipelineiv = qopenglfResolveGetProgramPipelineiv;
+ ProgramUniform1i = qopenglfResolveProgramUniform1i;
+ ProgramUniform2i = qopenglfResolveProgramUniform2i;
+ ProgramUniform3i = qopenglfResolveProgramUniform3i;
+ ProgramUniform4i = qopenglfResolveProgramUniform4i;
+ ProgramUniform1ui = qopenglfResolveProgramUniform1ui;
+ ProgramUniform2ui = qopenglfResolveProgramUniform2ui;
+ ProgramUniform3ui = qopenglfResolveProgramUniform3ui;
+ ProgramUniform4ui = qopenglfResolveProgramUniform4ui;
+ ProgramUniform1f = qopenglfResolveProgramUniform1f;
+ ProgramUniform2f = qopenglfResolveProgramUniform2f;
+ ProgramUniform3f = qopenglfResolveProgramUniform3f;
+ ProgramUniform4f = qopenglfResolveProgramUniform4f;
+ ProgramUniform1iv = qopenglfResolveProgramUniform1iv;
+ ProgramUniform2iv = qopenglfResolveProgramUniform2iv;
+ ProgramUniform3iv = qopenglfResolveProgramUniform3iv;
+ ProgramUniform4iv = qopenglfResolveProgramUniform4iv;
+ ProgramUniform1uiv = qopenglfResolveProgramUniform1uiv;
+ ProgramUniform2uiv = qopenglfResolveProgramUniform2uiv;
+ ProgramUniform3uiv = qopenglfResolveProgramUniform3uiv;
+ ProgramUniform4uiv = qopenglfResolveProgramUniform4uiv;
+ ProgramUniform1fv = qopenglfResolveProgramUniform1fv;
+ ProgramUniform2fv = qopenglfResolveProgramUniform2fv;
+ ProgramUniform3fv = qopenglfResolveProgramUniform3fv;
+ ProgramUniform4fv = qopenglfResolveProgramUniform4fv;
+ ProgramUniformMatrix2fv = qopenglfResolveProgramUniformMatrix2fv;
+ ProgramUniformMatrix3fv = qopenglfResolveProgramUniformMatrix3fv;
+ ProgramUniformMatrix4fv = qopenglfResolveProgramUniformMatrix4fv;
+ ProgramUniformMatrix2x3fv = qopenglfResolveProgramUniformMatrix2x3fv;
+ ProgramUniformMatrix3x2fv = qopenglfResolveProgramUniformMatrix3x2fv;
+ ProgramUniformMatrix2x4fv = qopenglfResolveProgramUniformMatrix2x4fv;
+ ProgramUniformMatrix4x2fv = qopenglfResolveProgramUniformMatrix4x2fv;
+ ProgramUniformMatrix3x4fv = qopenglfResolveProgramUniformMatrix3x4fv;
+ ProgramUniformMatrix4x3fv = qopenglfResolveProgramUniformMatrix4x3fv;
+ ValidateProgramPipeline = qopenglfResolveValidateProgramPipeline;
+ GetProgramPipelineInfoLog = qopenglfResolveGetProgramPipelineInfoLog;
+ BindImageTexture = qopenglfResolveBindImageTexture;
+ GetBooleani_v = qopenglfResolveGetBooleani_v;
+ MemoryBarrierFunc = qopenglfResolveMemoryBarrier;
+ MemoryBarrierByRegion = qopenglfResolveMemoryBarrierByRegion;
+ TexStorage2DMultisample = qopenglfResolveTexStorage2DMultisample;
+ GetMultisamplefv = qopenglfResolveGetMultisamplefv;
+ SampleMaski = qopenglfResolveSampleMaski;
+ GetTexLevelParameteriv = qopenglfResolveGetTexLevelParameteriv;
+ GetTexLevelParameterfv = qopenglfResolveGetTexLevelParameterfv;
+ BindVertexBuffer = qopenglfResolveBindVertexBuffer;
+ VertexAttribFormat = qopenglfResolveVertexAttribFormat;
+ VertexAttribIFormat = qopenglfResolveVertexAttribIFormat;
+ VertexAttribBinding = qopenglfResolveVertexAttribBinding;
+ VertexBindingDivisor = qopenglfResolveVertexBindingDivisor;
+}
+
+QOpenGLExtensionsPrivate::QOpenGLExtensionsPrivate(QOpenGLContext *ctx)
+ : QOpenGLExtraFunctionsPrivate(ctx),
+ flushVendorChecked(false)
+{
+ MapBuffer = qopenglfResolveMapBuffer;
GetBufferSubData = qopenglfResolveGetBufferSubData;
DiscardFramebuffer = qopenglfResolveDiscardFramebuffer;
}
diff --git a/src/gui/opengl/qopenglfunctions.h b/src/gui/opengl/qopenglfunctions.h
index b7cb4e53e9..e295f68e44 100644
--- a/src/gui/opengl/qopenglfunctions.h
+++ b/src/gui/opengl/qopenglfunctions.h
@@ -241,7 +241,8 @@ public:
NPOTTextures = 0x1000,
NPOTTextureRepeat = 0x2000,
FixedFunctionPipeline = 0x4000,
- TextureRGFormats = 0x8000
+ TextureRGFormats = 0x8000,
+ MultipleRenderTargets = 0x10000
};
Q_DECLARE_FLAGS(OpenGLFeatures, OpenGLFeature)
@@ -402,7 +403,7 @@ public:
protected:
QOpenGLFunctionsPrivate *d_ptr;
- static bool isInitialized(const QOpenGLFunctionsPrivate *d) { return d != 0; }
+ static bool isInitialized(const QOpenGLFunctionsPrivate *d) { return d != Q_NULLPTR; }
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QOpenGLFunctions::OpenGLFeatures)
diff --git a/src/gui/opengl/qopenglgradientcache.cpp b/src/gui/opengl/qopenglgradientcache.cpp
index ab493fa85c..13bad9aabb 100644
--- a/src/gui/opengl/qopenglgradientcache.cpp
+++ b/src/gui/opengl/qopenglgradientcache.cpp
@@ -34,8 +34,14 @@
#include "qopenglgradientcache_p.h"
#include <private/qdrawhelper_p.h>
#include <private/qopenglcontext_p.h>
+#include <private/qrgba64_p.h>
#include <QtCore/qmutex.h>
-#include <QtGui/qopenglfunctions.h>
+#include "qopenglfunctions.h"
+#include "qopenglextensions_p.h"
+
+#ifndef GL_RGBA16
+#define GL_RGBA16 0x805B
+#endif
QT_BEGIN_NAMESPACE
@@ -137,17 +143,79 @@ GLuint QOpenGL2GradientCache::addCacheElement(quint64 hash_val, const QGradient
}
CacheInfo cache_entry(gradient.stops(), opacity, gradient.interpolationMode());
- uint buffer[1024];
- generateGradientColorTable(gradient, buffer, paletteSize(), opacity);
funcs->glGenTextures(1, &cache_entry.texId);
funcs->glBindTexture(GL_TEXTURE_2D, cache_entry.texId);
- funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, paletteSize(), 1,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+ if (static_cast<QOpenGLExtensions *>(funcs)->hasOpenGLExtension(QOpenGLExtensions::Sized16Formats)) {
+ QRgba64 buffer[1024];
+ generateGradientColorTable(gradient, buffer, paletteSize(), opacity);
+ funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, paletteSize(), 1,
+ 0, GL_RGBA, GL_UNSIGNED_SHORT, buffer);
+ } else {
+ uint buffer[1024];
+ generateGradientColorTable(gradient, buffer, paletteSize(), opacity);
+ funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, paletteSize(), 1,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+ }
return cache.insert(hash_val, cache_entry).value().texId;
}
//TODO: Let GL generate the texture using an FBO
+void QOpenGL2GradientCache::generateGradientColorTable(const QGradient& gradient, QRgba64 *colorTable, int size, qreal opacity) const
+{
+ int pos = 0;
+ QGradientStops s = gradient.stops();
+ QVector<QRgba64> colors(s.size());
+
+ for (int i = 0; i < s.size(); ++i)
+ colors[i] = s[i].second.rgba64();
+
+ bool colorInterpolation = (gradient.interpolationMode() == QGradient::ColorInterpolation);
+
+ uint alpha = qRound(opacity * 256);
+ QRgba64 current_color = combineAlpha256(colors[0], alpha);
+ qreal incr = 1.0 / qreal(size);
+ qreal fpos = 1.5 * incr;
+ colorTable[pos++] = qPremultiply(current_color);
+
+ while (fpos <= s.first().first) {
+ colorTable[pos] = colorTable[pos - 1];
+ pos++;
+ fpos += incr;
+ }
+
+ if (colorInterpolation)
+ current_color = qPremultiply(current_color);
+
+ for (int i = 0; i < s.size() - 1; ++i) {
+ qreal delta = 1/(s[i+1].first - s[i].first);
+ QRgba64 next_color = combineAlpha256(colors[i+1], alpha);
+ if (colorInterpolation)
+ next_color = qPremultiply(next_color);
+
+ while (fpos < s[i+1].first && pos < size) {
+ int dist = int(256 * ((fpos - s[i].first) * delta));
+ int idist = 256 - dist;
+ if (colorInterpolation)
+ colorTable[pos] = interpolate256(current_color, idist, next_color, dist);
+ else
+ colorTable[pos] = qPremultiply(interpolate256(current_color, idist, next_color, dist));
+ ++pos;
+ fpos += incr;
+ }
+ current_color = next_color;
+ }
+
+ Q_ASSERT(s.size() > 0);
+
+ QRgba64 last_color = qPremultiply(combineAlpha256(colors[s.size() - 1], alpha));
+ for (;pos < size; ++pos)
+ colorTable[pos] = last_color;
+
+ // Make sure the last color stop is represented at the end of the table
+ colorTable[size-1] = last_color;
+}
+
void QOpenGL2GradientCache::generateGradientColorTable(const QGradient& gradient, uint *colorTable, int size, qreal opacity) const
{
int pos = 0;
diff --git a/src/gui/opengl/qopenglgradientcache_p.h b/src/gui/opengl/qopenglgradientcache_p.h
index bcdf3f4fcf..f2cc082250 100644
--- a/src/gui/opengl/qopenglgradientcache_p.h
+++ b/src/gui/opengl/qopenglgradientcache_p.h
@@ -50,6 +50,7 @@
#include <private/qopenglcontext_p.h>
#include <QtCore/qmutex.h>
#include <QGradient>
+#include <qrgba64.h>
QT_BEGIN_NAMESPACE
@@ -58,7 +59,7 @@ class QOpenGL2GradientCache : public QOpenGLSharedResource
struct CacheInfo
{
inline CacheInfo(QGradientStops s, qreal op, QGradient::InterpolationMode mode) :
- stops(s), opacity(op), interpolationMode(mode) {}
+ stops(qMove(s)), opacity(op), interpolationMode(mode) {}
GLuint texId;
QGradientStops stops;
@@ -83,6 +84,9 @@ public:
private:
inline int maxCacheSize() const { return 60; }
inline void generateGradientColorTable(const QGradient& gradient,
+ QRgba64 *colorTable,
+ int size, qreal opacity) const;
+ inline void generateGradientColorTable(const QGradient& gradient,
uint *colorTable,
int size, qreal opacity) const;
GLuint addCacheElement(quint64 hash_val, const QGradient &gradient, qreal opacity);
diff --git a/src/gui/opengl/qopenglpaintdevice.cpp b/src/gui/opengl/qopenglpaintdevice.cpp
index c0657feaa0..17a32774d8 100644
--- a/src/gui/opengl/qopenglpaintdevice.cpp
+++ b/src/gui/opengl/qopenglpaintdevice.cpp
@@ -169,6 +169,10 @@ QOpenGLPaintDevicePrivate::QOpenGLPaintDevicePrivate(const QSize &sz)
{
}
+QOpenGLPaintDevicePrivate::~QOpenGLPaintDevicePrivate()
+{
+}
+
class QOpenGLEngineThreadStorage
{
public:
@@ -271,6 +275,9 @@ int QOpenGLPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const
return qRound(d_ptr->dpmy * 0.0254);
case PdmDevicePixelRatio:
return d_ptr->devicePixelRatio;
+ case PdmDevicePixelRatioScaled:
+ return d_ptr->devicePixelRatio * QPaintDevice::devicePixelRatioFScale();
+
default:
qWarning("QOpenGLPaintDevice::metric() - metric %d not known", metric);
return 0;
diff --git a/src/gui/opengl/qopenglpaintdevice_p.h b/src/gui/opengl/qopenglpaintdevice_p.h
index 57d93ee80a..54ea09240d 100644
--- a/src/gui/opengl/qopenglpaintdevice_p.h
+++ b/src/gui/opengl/qopenglpaintdevice_p.h
@@ -56,7 +56,7 @@ class Q_GUI_EXPORT QOpenGLPaintDevicePrivate
{
public:
QOpenGLPaintDevicePrivate(const QSize &size);
- virtual ~QOpenGLPaintDevicePrivate() { }
+ virtual ~QOpenGLPaintDevicePrivate();
static QOpenGLPaintDevicePrivate *get(QOpenGLPaintDevice *dev) { return dev->d_func(); }
diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp
index a9a4adaddc..0b92bf4b1d 100644
--- a/src/gui/opengl/qopenglpaintengine.cpp
+++ b/src/gui/opengl/qopenglpaintengine.cpp
@@ -93,13 +93,6 @@ QOpenGL2PaintEngineExPrivate::~QOpenGL2PaintEngineExPrivate()
{
delete shaderManager;
- while (pathCaches.size()) {
- QVectorPath::CacheEntry *e = *(pathCaches.constBegin());
- e->cleanup(e->engine, e->data);
- e->data = 0;
- e->engine = 0;
- }
-
if (elementIndicesVBOId != 0) {
funcs.glDeleteBuffers(1, &elementIndicesVBOId);
elementIndicesVBOId = 0;
@@ -292,8 +285,6 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture()
}
updateTexture(QT_BRUSH_TEXTURE_UNIT, currentBrushImage, wrapMode, filterMode, ForceUpdate);
-
- textureInvertedY = false;
}
brushTextureDirty = false;
}
@@ -409,11 +400,7 @@ void QOpenGL2PaintEngineExPrivate::updateBrushUniforms()
dy = 0;
}
QTransform gl_to_qt(1, 0, 0, m22, 0, dy);
- QTransform inv_matrix;
- if (style == Qt::TexturePattern && textureInvertedY == -1)
- inv_matrix = gl_to_qt * (QTransform(1, 0, 0, -1, 0, currentBrush.texture().height()) * brushQTransform * matrix).inverted() * translate;
- else
- inv_matrix = gl_to_qt * (brushQTransform * matrix).inverted() * translate;
+ QTransform inv_matrix = gl_to_qt * (brushQTransform * matrix).inverted() * translate;
shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::BrushTransform), inv_matrix);
shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::BrushTexture), QT_BRUSH_TEXTURE_UNIT);
@@ -2076,7 +2063,7 @@ bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev)
d->device->ensureActiveTarget();
- if (d->device->context() != QOpenGLContext::currentContext()) {
+ if (d->device->context() != QOpenGLContext::currentContext() || !d->device->context()) {
qWarning("QPainter::begin(): QOpenGLPaintDevice's context needs to be current");
return false;
}
diff --git a/src/gui/opengl/qopenglpaintengine_p.h b/src/gui/opengl/qopenglpaintengine_p.h
index 17be72b1e9..f1ec669ca0 100644
--- a/src/gui/opengl/qopenglpaintengine_p.h
+++ b/src/gui/opengl/qopenglpaintengine_p.h
@@ -309,14 +309,9 @@ public:
bool needsSync;
bool multisamplingAlwaysEnabled;
- GLfloat depthRange[2];
-
- float textureInvertedY;
-
QTriangulatingStroker stroker;
QDashedStrokeProcessor dasher;
- QSet<QVectorPath::CacheEntry *> pathCaches;
QVector<GLuint> unusedVBOSToClean;
QVector<GLuint> unusedIBOSToClean;
diff --git a/src/gui/opengl/qopenglpixeltransferoptions.h b/src/gui/opengl/qopenglpixeltransferoptions.h
index bf726813bd..cb4697ec7c 100644
--- a/src/gui/opengl/qopenglpixeltransferoptions.h
+++ b/src/gui/opengl/qopenglpixeltransferoptions.h
@@ -49,15 +49,14 @@ class Q_GUI_EXPORT QOpenGLPixelTransferOptions
public:
QOpenGLPixelTransferOptions();
QOpenGLPixelTransferOptions(const QOpenGLPixelTransferOptions &);
- QOpenGLPixelTransferOptions &operator=(const QOpenGLPixelTransferOptions &);
- ~QOpenGLPixelTransferOptions();
-
#ifdef Q_COMPILER_RVALUE_REFS
- QOpenGLPixelTransferOptions &operator=(QOpenGLPixelTransferOptions &&other)
+ QOpenGLPixelTransferOptions &operator=(QOpenGLPixelTransferOptions &&other) Q_DECL_NOTHROW
{ swap(other); return *this; }
#endif
+ QOpenGLPixelTransferOptions &operator=(const QOpenGLPixelTransferOptions &);
+ ~QOpenGLPixelTransferOptions();
- void swap(QOpenGLPixelTransferOptions &other)
+ void swap(QOpenGLPixelTransferOptions &other) Q_DECL_NOTHROW
{ data.swap(other.data); }
void setAlignment(int alignment);
diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp
index 04b796ddb0..9714aa4bec 100644
--- a/src/gui/opengl/qopenglshaderprogram.cpp
+++ b/src/gui/opengl/qopenglshaderprogram.cpp
@@ -1783,7 +1783,7 @@ void QOpenGLShaderProgram::setAttributeBuffer
Q_UNUSED(d);
if (location != -1) {
d->glfuncs->glVertexAttribPointer(location, tupleSize, type, GL_TRUE, stride,
- reinterpret_cast<const void *>(offset));
+ reinterpret_cast<const void *>(qintptr(offset)));
}
}
diff --git a/src/gui/opengl/qopenglshaderprogram.h b/src/gui/opengl/qopenglshaderprogram.h
index 9f5957e612..b959954718 100644
--- a/src/gui/opengl/qopenglshaderprogram.h
+++ b/src/gui/opengl/qopenglshaderprogram.h
@@ -66,7 +66,7 @@ public:
};
Q_DECLARE_FLAGS(ShaderType, ShaderTypeBit)
- explicit QOpenGLShader(QOpenGLShader::ShaderType type, QObject *parent = 0);
+ explicit QOpenGLShader(QOpenGLShader::ShaderType type, QObject *parent = Q_NULLPTR);
virtual ~QOpenGLShader();
QOpenGLShader::ShaderType shaderType() const;
@@ -83,7 +83,7 @@ public:
GLuint shaderId() const;
- static bool hasOpenGLShaders(ShaderType type, QOpenGLContext *context = 0);
+ static bool hasOpenGLShaders(ShaderType type, QOpenGLContext *context = Q_NULLPTR);
private:
friend class QOpenGLShaderProgram;
@@ -101,7 +101,7 @@ class Q_GUI_EXPORT QOpenGLShaderProgram : public QObject
{
Q_OBJECT
public:
- explicit QOpenGLShaderProgram(QObject *parent = 0);
+ explicit QOpenGLShaderProgram(QObject *parent = Q_NULLPTR);
virtual ~QOpenGLShaderProgram();
bool addShader(QOpenGLShader *shader);
@@ -288,7 +288,7 @@ public:
void setUniformValueArray(const char *name, const QMatrix4x3 *values, int count);
void setUniformValueArray(const char *name, const QMatrix4x4 *values, int count);
- static bool hasOpenGLShaderPrograms(QOpenGLContext *context = 0);
+ static bool hasOpenGLShaderPrograms(QOpenGLContext *context = Q_NULLPTR);
private Q_SLOTS:
void shaderDestroyed();
diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp
index c58ddbd71e..6b83c17fd4 100644
--- a/src/gui/opengl/qopengltexture.cpp
+++ b/src/gui/opengl/qopengltexture.cpp
@@ -97,9 +97,11 @@ QOpenGLTexturePrivate::QOpenGLTexturePrivate(QOpenGLTexture::Target textureTarge
break;
case QOpenGLTexture::TargetCubeMap:
bindingTarget = QOpenGLTexture::BindingTargetCubeMap;
+ faces = 6;
break;
case QOpenGLTexture::TargetCubeMapArray:
bindingTarget = QOpenGLTexture::BindingTargetCubeMapArray;
+ faces = 6;
break;
case QOpenGLTexture::Target2DMultisample:
bindingTarget = QOpenGLTexture::BindingTarget2DMultisample;
@@ -175,7 +177,7 @@ bool QOpenGLTexturePrivate::create()
void QOpenGLTexturePrivate::destroy()
{
- if (!context) {
+ if (!textureId) {
// not created or already destroyed
return;
}
@@ -401,6 +403,9 @@ static bool isSizedTextureFormat(QOpenGLTexture::TextureFormat internalFormat)
case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC:
return true;
+ case QOpenGLTexture::RGB8_ETC1:
+ return false;
+
case QOpenGLTexture::DepthFormat:
case QOpenGLTexture::AlphaFormat:
@@ -442,20 +447,23 @@ static bool isTextureTargetMultisample(QOpenGLTexture::Target target)
return false;
}
-void QOpenGLTexturePrivate::allocateStorage(QOpenGLTexture::PixelFormat pixelFormat, QOpenGLTexture::PixelType pixelType)
+bool QOpenGLTexturePrivate::isUsingImmutableStorage() const
{
- // Resolve the actual number of mipmap levels we can use
- mipLevels = evaluateMipLevels();
-
// Use immutable storage whenever possible, falling back to mutable
// Note that if multisample textures are not supported at all, we'll still fail into
// the mutable storage allocation
- const bool useImmutableStorage = isSizedTextureFormat(format)
+ return isSizedTextureFormat(format)
&& (isTextureTargetMultisample(target)
? features.testFlag(QOpenGLTexture::ImmutableMultisampleStorage)
: features.testFlag(QOpenGLTexture::ImmutableStorage));
+}
+
+void QOpenGLTexturePrivate::allocateStorage(QOpenGLTexture::PixelFormat pixelFormat, QOpenGLTexture::PixelType pixelType)
+{
+ // Resolve the actual number of mipmap levels we can use
+ mipLevels = evaluateMipLevels();
- if (useImmutableStorage)
+ if (isUsingImmutableStorage())
allocateImmutableStorage();
else
allocateMutableStorage(pixelFormat, pixelType);
@@ -663,6 +671,7 @@ static QOpenGLTexture::PixelFormat pixelFormatCompatibleWithInternalFormat(QOpen
case QOpenGLTexture::SRGB_Alpha_DXT3:
case QOpenGLTexture::SRGB_Alpha_DXT5:
case QOpenGLTexture::SRGB_BP_UNorm:
+ case QOpenGLTexture::RGB8_ETC1:
return QOpenGLTexture::RGBA;
case QOpenGLTexture::R11_EAC_UNorm:
@@ -840,6 +849,7 @@ static QOpenGLTexture::PixelType pixelTypeCompatibleWithInternalFormat(QOpenGLTe
case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2:
case QOpenGLTexture::RGBA8_ETC2_EAC:
case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC:
+ case QOpenGLTexture::RGB8_ETC1:
return QOpenGLTexture::UInt8;
case QOpenGLTexture::DepthFormat:
@@ -857,8 +867,133 @@ static QOpenGLTexture::PixelType pixelTypeCompatibleWithInternalFormat(QOpenGLTe
return QOpenGLTexture::NoPixelType;
}
+static bool isCompressedFormat(QOpenGLTexture::TextureFormat internalFormat)
+{
+ switch (internalFormat) {
+ case QOpenGLTexture::NoFormat:
+
+ case QOpenGLTexture::R8_UNorm:
+ case QOpenGLTexture::RG8_UNorm:
+ case QOpenGLTexture::RGB8_UNorm:
+ case QOpenGLTexture::RGBA8_UNorm:
+ case QOpenGLTexture::R16_UNorm:
+ case QOpenGLTexture::RG16_UNorm:
+ case QOpenGLTexture::RGB16_UNorm:
+ case QOpenGLTexture::RGBA16_UNorm:
+ case QOpenGLTexture::R8_SNorm:
+ case QOpenGLTexture::RG8_SNorm:
+ case QOpenGLTexture::RGB8_SNorm:
+ case QOpenGLTexture::RGBA8_SNorm:
+ case QOpenGLTexture::R16_SNorm:
+ case QOpenGLTexture::RG16_SNorm:
+ case QOpenGLTexture::RGB16_SNorm:
+ case QOpenGLTexture::RGBA16_SNorm:
+ case QOpenGLTexture::R8U:
+ case QOpenGLTexture::RG8U:
+ case QOpenGLTexture::RGB8U:
+ case QOpenGLTexture::RGBA8U:
+ case QOpenGLTexture::R16U:
+ case QOpenGLTexture::RG16U:
+ case QOpenGLTexture::RGB16U:
+ case QOpenGLTexture::RGBA16U:
+ case QOpenGLTexture::R32U:
+ case QOpenGLTexture::RG32U:
+ case QOpenGLTexture::RGB32U:
+ case QOpenGLTexture::RGBA32U:
+ case QOpenGLTexture::R8I:
+ case QOpenGLTexture::RG8I:
+ case QOpenGLTexture::RGB8I:
+ case QOpenGLTexture::RGBA8I:
+ case QOpenGLTexture::R16I:
+ case QOpenGLTexture::RG16I:
+ case QOpenGLTexture::RGB16I:
+ case QOpenGLTexture::RGBA16I:
+ case QOpenGLTexture::R32I:
+ case QOpenGLTexture::RG32I:
+ case QOpenGLTexture::RGB32I:
+ case QOpenGLTexture::RGBA32I:
+ case QOpenGLTexture::R16F:
+ case QOpenGLTexture::RG16F:
+ case QOpenGLTexture::RGB16F:
+ case QOpenGLTexture::RGBA16F:
+ case QOpenGLTexture::R32F:
+ case QOpenGLTexture::RG32F:
+ case QOpenGLTexture::RGB32F:
+ case QOpenGLTexture::RGBA32F:
+ case QOpenGLTexture::RGB9E5:
+ case QOpenGLTexture::RG11B10F:
+ case QOpenGLTexture::RG3B2:
+ case QOpenGLTexture::R5G6B5:
+ case QOpenGLTexture::RGB5A1:
+ case QOpenGLTexture::RGBA4:
+ case QOpenGLTexture::RGB10A2:
+
+ case QOpenGLTexture::D16:
+ case QOpenGLTexture::D24:
+ case QOpenGLTexture::D32:
+ case QOpenGLTexture::D32F:
+
+ case QOpenGLTexture::D24S8:
+ case QOpenGLTexture::D32FS8X24:
+
+ case QOpenGLTexture::S8:
+ return false;
+
+ case QOpenGLTexture::RGB_DXT1:
+ case QOpenGLTexture::RGBA_DXT1:
+ case QOpenGLTexture::RGBA_DXT3:
+ case QOpenGLTexture::RGBA_DXT5:
+ case QOpenGLTexture::R_ATI1N_UNorm:
+ case QOpenGLTexture::R_ATI1N_SNorm:
+ case QOpenGLTexture::RG_ATI2N_UNorm:
+ case QOpenGLTexture::RG_ATI2N_SNorm:
+ case QOpenGLTexture::RGB_BP_UNSIGNED_FLOAT:
+ case QOpenGLTexture::RGB_BP_SIGNED_FLOAT:
+ case QOpenGLTexture::RGB_BP_UNorm:
+ case QOpenGLTexture::SRGB8:
+ case QOpenGLTexture::SRGB8_Alpha8:
+ case QOpenGLTexture::SRGB_DXT1:
+ case QOpenGLTexture::SRGB_Alpha_DXT1:
+ case QOpenGLTexture::SRGB_Alpha_DXT3:
+ case QOpenGLTexture::SRGB_Alpha_DXT5:
+ case QOpenGLTexture::SRGB_BP_UNorm:
+ case QOpenGLTexture::R11_EAC_UNorm:
+ case QOpenGLTexture::R11_EAC_SNorm:
+ case QOpenGLTexture::RG11_EAC_UNorm:
+ case QOpenGLTexture::RG11_EAC_SNorm:
+ case QOpenGLTexture::RGB8_ETC2:
+ case QOpenGLTexture::SRGB8_ETC2:
+ case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2:
+ case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2:
+ case QOpenGLTexture::RGBA8_ETC2_EAC:
+ case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC:
+ case QOpenGLTexture::RGB8_ETC1:
+ return true;
+
+ case QOpenGLTexture::DepthFormat:
+ case QOpenGLTexture::AlphaFormat:
+ case QOpenGLTexture::RGBFormat:
+ case QOpenGLTexture::RGBAFormat:
+ case QOpenGLTexture::LuminanceFormat:
+ case QOpenGLTexture::LuminanceAlphaFormat:
+ return false;
+ }
+
+ Q_UNREACHABLE();
+ return false;
+}
+
void QOpenGLTexturePrivate::allocateMutableStorage(QOpenGLTexture::PixelFormat pixelFormat, QOpenGLTexture::PixelType pixelType)
{
+ // There is no way to allocate mutable storage for compressed textures in in
+ // versions older than OpenGL 3.1 and OpenGL ES 3.0, because the older specs
+ // do not mandate accepting null data pointers for glCompressedTexImage*D,
+ // unlike glTexImage*D (which in turn does not accept compressed formats).
+ if (isCompressedFormat(format)) {
+ storageAllocated = true;
+ return;
+ }
+
switch (target) {
case QOpenGLTexture::TargetBuffer:
// Buffer textures get their storage from an external OpenGL buffer
@@ -1196,86 +1331,121 @@ void QOpenGLTexturePrivate::setCompressedData(int mipLevel, int layer, QOpenGLTe
int dataSize, const void *data,
const QOpenGLPixelTransferOptions * const options)
{
+ if (!isCompressedFormat(format)) {
+ qWarning("Cannot set compressed data for non-compressed format 0x%x", format);
+ return;
+ }
+
+ const bool needsFullSpec = !isUsingImmutableStorage(); // was allocateStorage() a no-op?
+
switch (target) {
case QOpenGLTexture::Target1D:
Q_UNUSED(layer);
Q_UNUSED(cubeFace);
- texFuncs->glCompressedTextureSubImage1D(textureId, target, bindingTarget, mipLevel,
- 0, mipLevelSize( mipLevel, dimensions[0] ),
- format, dataSize, data, options);
+ if (needsFullSpec) {
+ texFuncs->glCompressedTextureImage1D(textureId, target, bindingTarget, mipLevel,
+ format,
+ mipLevelSize(mipLevel, dimensions[0]),
+ 0, dataSize, data, options);
+ } else {
+ texFuncs->glCompressedTextureSubImage1D(textureId, target, bindingTarget, mipLevel,
+ 0, mipLevelSize( mipLevel, dimensions[0] ),
+ format, dataSize, data, options);
+ }
break;
case QOpenGLTexture::Target1DArray:
Q_UNUSED(cubeFace);
- texFuncs->glCompressedTextureSubImage2D(textureId, target, bindingTarget, mipLevel,
- 0, layer,
- mipLevelSize(mipLevel, dimensions[0]),
- 1,
- format, dataSize, data, options);
+ if (!needsFullSpec) {
+ texFuncs->glCompressedTextureSubImage2D(textureId, target, bindingTarget, mipLevel,
+ 0, layer,
+ mipLevelSize(mipLevel, dimensions[0]),
+ 1,
+ format, dataSize, data, options);
+ }
break;
case QOpenGLTexture::Target2D:
Q_UNUSED(layer);
Q_UNUSED(cubeFace);
- texFuncs->glCompressedTextureSubImage2D(textureId, target, bindingTarget, mipLevel,
- 0, 0,
- mipLevelSize(mipLevel, dimensions[0]),
- mipLevelSize(mipLevel, dimensions[1]),
- format, dataSize, data, options);
+ if (needsFullSpec) {
+ texFuncs->glCompressedTextureImage2D(textureId, target, bindingTarget, mipLevel,
+ format,
+ mipLevelSize(mipLevel, dimensions[0]),
+ mipLevelSize(mipLevel, dimensions[1]),
+ 0, dataSize, data, options);
+ } else {
+ texFuncs->glCompressedTextureSubImage2D(textureId, target, bindingTarget, mipLevel,
+ 0, 0,
+ mipLevelSize(mipLevel, dimensions[0]),
+ mipLevelSize(mipLevel, dimensions[1]),
+ format, dataSize, data, options);
+ }
break;
case QOpenGLTexture::Target2DArray:
Q_UNUSED(cubeFace);
- texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
- 0, 0, layer,
- mipLevelSize(mipLevel, dimensions[0]),
- mipLevelSize(mipLevel, dimensions[1]),
- 1,
- format, dataSize, data, options);
+ if (!needsFullSpec) {
+ texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
+ 0, 0, layer,
+ mipLevelSize(mipLevel, dimensions[0]),
+ mipLevelSize(mipLevel, dimensions[1]),
+ 1,
+ format, dataSize, data, options);
+ }
break;
case QOpenGLTexture::Target3D:
Q_UNUSED(cubeFace);
- texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
- 0, 0, layer,
- mipLevelSize(mipLevel, dimensions[0]),
- mipLevelSize(mipLevel, dimensions[1]),
- mipLevelSize(mipLevel, dimensions[2]),
- format, dataSize, data, options);
+ if (needsFullSpec) {
+ texFuncs->glCompressedTextureImage3D(textureId, target, bindingTarget, mipLevel,
+ format,
+ mipLevelSize(mipLevel, dimensions[0]),
+ mipLevelSize(mipLevel, dimensions[1]),
+ mipLevelSize(mipLevel, dimensions[2]),
+ 0, dataSize, data, options);
+ } else {
+ texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
+ 0, 0, layer,
+ mipLevelSize(mipLevel, dimensions[0]),
+ mipLevelSize(mipLevel, dimensions[1]),
+ mipLevelSize(mipLevel, dimensions[2]),
+ format, dataSize, data, options);
+ }
break;
case QOpenGLTexture::TargetCubeMap:
Q_UNUSED(layer);
- texFuncs->glCompressedTextureSubImage2D(textureId, cubeFace, bindingTarget, mipLevel,
- 0, 0,
- mipLevelSize(mipLevel, dimensions[0]),
- mipLevelSize(mipLevel, dimensions[1]),
- format, dataSize, data, options);
+ if (needsFullSpec) {
+ texFuncs->glCompressedTextureImage2D(textureId, cubeFace, bindingTarget, mipLevel,
+ format,
+ mipLevelSize(mipLevel, dimensions[0]),
+ mipLevelSize(mipLevel, dimensions[1]),
+ 0, dataSize, data, options);
+ } else {
+ texFuncs->glCompressedTextureSubImage2D(textureId, cubeFace, bindingTarget, mipLevel,
+ 0, 0,
+ mipLevelSize(mipLevel, dimensions[0]),
+ mipLevelSize(mipLevel, dimensions[1]),
+ format, dataSize, data, options);
+ }
break;
case QOpenGLTexture::TargetCubeMapArray: {
int faceIndex = cubeFace - QOpenGLTexture::CubeMapPositiveX;
int layerFace = 6 * layer + faceIndex;
- texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
- 0, 0, layerFace,
- mipLevelSize(mipLevel, dimensions[0]),
- mipLevelSize(mipLevel, dimensions[1]),
- 1,
- format, dataSize, data, options);
+ if (!needsFullSpec) {
+ texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
+ 0, 0, layerFace,
+ mipLevelSize(mipLevel, dimensions[0]),
+ mipLevelSize(mipLevel, dimensions[1]),
+ 1,
+ format, dataSize, data, options);
+ }
break;
}
case QOpenGLTexture::TargetRectangle:
- Q_UNUSED(mipLevel);
- Q_UNUSED(layer);
- Q_UNUSED(cubeFace);
- texFuncs->glCompressedTextureSubImage2D(textureId, target, bindingTarget, 0,
- 0, 0,
- dimensions[0],
- dimensions[1],
- format, dataSize, data, options);
- break;
-
case QOpenGLTexture::Target2DMultisample:
case QOpenGLTexture::Target2DMultisampleArray:
case QOpenGLTexture::TargetBuffer:
@@ -1857,6 +2027,7 @@ QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target
\value SRGB8_PunchThrough_Alpha1_ETC2 Equivalent to GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
\value RGBA8_ETC2_EAC Equivalent to GL_COMPRESSED_RGBA8_ETC2_EAC
\value SRGB8_Alpha8_ETC2_EAC Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
+ \value RGB8_ETC1 Equivalent to GL_ETC1_RGB8_OES
\value SRGB8 Equivalent to GL_SRGB8
\value SRGB8_Alpha8 Equivalent to GL_SRGB8_ALPHA8
@@ -2394,6 +2565,7 @@ void QOpenGLTexture::setFormat(TextureFormat format)
case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2:
case QOpenGLTexture::RGBA8_ETC2_EAC:
case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC:
+ case QOpenGLTexture::RGB8_ETC1:
case RG3B2:
case R5G6B5:
case RGB5A1:
@@ -3464,6 +3636,8 @@ QPair<int, int> QOpenGLTexture::mipLevelRange() const
The automatic mipmap generation is enabled by default.
+ \note Mipmap generation is not supported for compressed textures with OpenGL ES 2.0.
+
\sa isAutoMipMapGenerationEnabled(), generateMipMaps()
*/
void QOpenGLTexture::setAutoMipMapGenerationEnabled(bool enabled)
@@ -3489,6 +3663,9 @@ bool QOpenGLTexture::isAutoMipMapGenerationEnabled() const
have disabled automatic mipmap generation then you need to call this function
or the overload to create the mipmap chain.
+ \note Mipmap generation is not supported for compressed textures with OpenGL
+ ES 2.0.
+
\sa setAutoMipMapGenerationEnabled(), setMipLevels(), mipLevels()
*/
void QOpenGLTexture::generateMipMaps()
@@ -3496,6 +3673,11 @@ void QOpenGLTexture::generateMipMaps()
Q_D(QOpenGLTexture);
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
+ if (isCompressedFormat(d->format)) {
+ if (QOpenGLContext *ctx = QOpenGLContext::currentContext())
+ if (ctx->isOpenGLES() && ctx->format().majorVersion() < 3)
+ return;
+ }
d->texFuncs->glGenerateTextureMipmap(d->textureId, d->target, d->bindingTarget);
}
@@ -3516,6 +3698,11 @@ void QOpenGLTexture::generateMipMaps(int baseLevel, bool resetBaseLevel)
Q_D(QOpenGLTexture);
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
+ if (isCompressedFormat(d->format)) {
+ if (QOpenGLContext *ctx = QOpenGLContext::currentContext())
+ if (ctx->isOpenGLES() && ctx->format().majorVersion() < 3)
+ return;
+ }
int oldBaseLevel;
if (resetBaseLevel)
oldBaseLevel = mipBaseLevel();
diff --git a/src/gui/opengl/qopengltexture.h b/src/gui/opengl/qopengltexture.h
index 3017aac737..ec52a192fa 100644
--- a/src/gui/opengl/qopengltexture.h
+++ b/src/gui/opengl/qopengltexture.h
@@ -196,6 +196,7 @@ public:
SRGB8_PunchThrough_Alpha1_ETC2 = 0x9277, // GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
RGBA8_ETC2_EAC = 0x9278, // GL_COMPRESSED_RGBA8_ETC2_EAC
SRGB8_Alpha8_ETC2_EAC = 0x9279, // GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
+ RGB8_ETC1 = 0x8D64, // GL_ETC1_RGB8_OES
// sRGB formats
SRGB8 = 0x8C41, // GL_SRGB8
@@ -409,54 +410,54 @@ public:
#if QT_DEPRECATED_SINCE(5, 3)
QT_DEPRECATED void setData(int mipLevel, int layer, CubeMapFace cubeFace,
PixelFormat sourceFormat, PixelType sourceType,
- void *data, const QOpenGLPixelTransferOptions * const options = 0);
+ void *data, const QOpenGLPixelTransferOptions * const options = Q_NULLPTR);
QT_DEPRECATED void setData(int mipLevel, int layer,
PixelFormat sourceFormat, PixelType sourceType,
- void *data, const QOpenGLPixelTransferOptions * const options = 0);
+ void *data, const QOpenGLPixelTransferOptions * const options = Q_NULLPTR);
QT_DEPRECATED void setData(int mipLevel,
PixelFormat sourceFormat, PixelType sourceType,
- void *data, const QOpenGLPixelTransferOptions * const options = 0);
+ void *data, const QOpenGLPixelTransferOptions * const options = Q_NULLPTR);
QT_DEPRECATED void setData(PixelFormat sourceFormat, PixelType sourceType,
- void *data, const QOpenGLPixelTransferOptions * const options = 0);
+ void *data, const QOpenGLPixelTransferOptions * const options = Q_NULLPTR);
#endif // QT_DEPRECATED_SINCE(5, 3)
void setData(int mipLevel, int layer, CubeMapFace cubeFace,
PixelFormat sourceFormat, PixelType sourceType,
- const void *data, const QOpenGLPixelTransferOptions * const options = 0);
+ const void *data, const QOpenGLPixelTransferOptions * const options = Q_NULLPTR);
void setData(int mipLevel, int layer,
PixelFormat sourceFormat, PixelType sourceType,
- const void *data, const QOpenGLPixelTransferOptions * const options = 0);
+ const void *data, const QOpenGLPixelTransferOptions * const options = Q_NULLPTR);
void setData(int mipLevel,
PixelFormat sourceFormat, PixelType sourceType,
- const void *data, const QOpenGLPixelTransferOptions * const options = 0);
+ const void *data, const QOpenGLPixelTransferOptions * const options = Q_NULLPTR);
void setData(PixelFormat sourceFormat, PixelType sourceType,
- const void *data, const QOpenGLPixelTransferOptions * const options = 0);
+ const void *data, const QOpenGLPixelTransferOptions * const options = Q_NULLPTR);
// Compressed data upload
// ### Qt 6: remove the non-const void * overloads
#if QT_DEPRECATED_SINCE(5, 3)
QT_DEPRECATED void setCompressedData(int mipLevel, int layer, CubeMapFace cubeFace,
int dataSize, void *data,
- const QOpenGLPixelTransferOptions * const options = 0);
+ const QOpenGLPixelTransferOptions * const options = Q_NULLPTR);
QT_DEPRECATED void setCompressedData(int mipLevel, int layer,
int dataSize, void *data,
- const QOpenGLPixelTransferOptions * const options = 0);
+ const QOpenGLPixelTransferOptions * const options = Q_NULLPTR);
QT_DEPRECATED void setCompressedData(int mipLevel, int dataSize, void *data,
- const QOpenGLPixelTransferOptions * const options = 0);
+ const QOpenGLPixelTransferOptions * const options = Q_NULLPTR);
QT_DEPRECATED void setCompressedData(int dataSize, void *data,
- const QOpenGLPixelTransferOptions * const options = 0);
+ const QOpenGLPixelTransferOptions * const options = Q_NULLPTR);
#endif // QT_DEPRECATED_SINCE(5, 3)
void setCompressedData(int mipLevel, int layer, CubeMapFace cubeFace,
int dataSize, const void *data,
- const QOpenGLPixelTransferOptions * const options = 0);
+ const QOpenGLPixelTransferOptions * const options = Q_NULLPTR);
void setCompressedData(int mipLevel, int layer,
int dataSize, const void *data,
- const QOpenGLPixelTransferOptions * const options = 0);
+ const QOpenGLPixelTransferOptions * const options = Q_NULLPTR);
void setCompressedData(int mipLevel, int dataSize, const void *data,
- const QOpenGLPixelTransferOptions * const options = 0);
+ const QOpenGLPixelTransferOptions * const options = Q_NULLPTR);
void setCompressedData(int dataSize, const void *data,
- const QOpenGLPixelTransferOptions * const options = 0);
+ const QOpenGLPixelTransferOptions * const options = Q_NULLPTR);
// Helpful overloads for setData
void setData(const QImage& image, MipMapGeneration genMipMaps = GenerateMipMaps);
diff --git a/src/gui/opengl/qopengltexture_p.h b/src/gui/opengl/qopengltexture_p.h
index be4bf0e93c..40ceb1936c 100644
--- a/src/gui/opengl/qopengltexture_p.h
+++ b/src/gui/opengl/qopengltexture_p.h
@@ -117,6 +117,8 @@ public:
return std::floor(double(qMax(1, baseLevelSize >> mipLevel)));
}
+ bool isUsingImmutableStorage() const;
+
QOpenGLTexture *q_ptr;
QOpenGLContext *context;
QOpenGLTexture::Target target;
@@ -154,7 +156,6 @@ public:
bool autoGenerateMipMaps;
bool storageAllocated;
- QPair<int, int> glVersion;
QOpenGLTextureHelper *texFuncs;
QOpenGLTexture::Features features;
diff --git a/src/gui/opengl/qopengltextureblitter.cpp b/src/gui/opengl/qopengltextureblitter.cpp
index 0f9fa6400d..9e611a160d 100644
--- a/src/gui/opengl/qopengltextureblitter.cpp
+++ b/src/gui/opengl/qopengltextureblitter.cpp
@@ -39,6 +39,10 @@
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLFunctions>
+#ifndef GL_TEXTURE_EXTERNAL_OES
+#define GL_TEXTURE_EXTERNAL_OES 0x8D65
+#endif
+
QT_BEGIN_NAMESPACE
static const char vertex_shader150[] =
@@ -88,6 +92,18 @@ static const char fragment_shader[] =
" gl_FragColor = swizzle ? tmpFragColor.bgra : tmpFragColor;"
"}";
+static const char fragment_shader_external_oes[] =
+ "#extension GL_OES_EGL_image_external : require\n"
+ "varying highp vec2 uv;"
+ "uniform samplerExternalOES textureSampler;\n"
+ "uniform bool swizzle;"
+ "uniform highp float opacity;"
+ "void main() {"
+ " highp vec4 tmpFragColor = texture2D(textureSampler, uv);"
+ " tmpFragColor.a *= opacity;"
+ " gl_FragColor = swizzle ? tmpFragColor.bgra : tmpFragColor;"
+ "}";
+
static const GLfloat vertex_buffer_data[] = {
-1,-1, 0,
-1, 1, 0,
@@ -109,14 +125,17 @@ static const GLfloat texture_buffer_data[] = {
class TextureBinder
{
public:
- TextureBinder(GLuint textureId)
+ TextureBinder(GLenum target, GLuint textureId) : m_target(target)
{
- QOpenGLContext::currentContext()->functions()->glBindTexture(GL_TEXTURE_2D, textureId);
+ QOpenGLContext::currentContext()->functions()->glBindTexture(m_target, textureId);
}
~TextureBinder()
{
- QOpenGLContext::currentContext()->functions()->glBindTexture(GL_TEXTURE_2D, 0);
+ QOpenGLContext::currentContext()->functions()->glBindTexture(m_target, 0);
}
+
+private:
+ GLenum m_target;
};
class QOpenGLTextureBlitterPrivate
@@ -128,74 +147,106 @@ public:
IdentityFlipped
};
- QOpenGLTextureBlitterPrivate()
- : program(0)
- , vertexCoordAttribPos(0)
- , vertexTransformUniformPos(0)
- , textureCoordAttribPos(0)
- , textureTransformUniformPos(0)
- , swizzle(false)
- , swizzleOld(false)
- , opacity(1.0f)
- , opacityOld(0.0f)
- , textureMatrixUniformState(User)
- , vao(new QOpenGLVertexArrayObject())
+ enum ProgramIndex {
+ TEXTURE_2D,
+ TEXTURE_EXTERNAL_OES
+ };
+
+ QOpenGLTextureBlitterPrivate() :
+ swizzle(false),
+ opacity(1.0f),
+ vao(new QOpenGLVertexArrayObject),
+ currentTarget(TEXTURE_2D)
{ }
+ bool buildProgram(ProgramIndex idx, const char *vs, const char *fs);
+
void blit(GLuint texture, const QMatrix4x4 &vertexTransform, const QMatrix3x3 &textureTransform);
void blit(GLuint texture, const QMatrix4x4 &vertexTransform, QOpenGLTextureBlitter::Origin origin);
- void prepareProgram(const QMatrix4x4 &vertexTransform)
- {
- vertexBuffer.bind();
- program->setAttributeBuffer(vertexCoordAttribPos, GL_FLOAT, 0, 3, 0);
- program->enableAttributeArray(vertexCoordAttribPos);
- vertexBuffer.release();
-
- program->setUniformValue(vertexTransformUniformPos, vertexTransform);
-
- textureBuffer.bind();
- program->setAttributeBuffer(textureCoordAttribPos, GL_FLOAT, 0, 2, 0);
- program->enableAttributeArray(textureCoordAttribPos);
- textureBuffer.release();
-
- if (swizzle != swizzleOld) {
- program->setUniformValue(swizzleUniformPos, swizzle);
- swizzleOld = swizzle;
- }
-
- if (opacity != opacityOld) {
- program->setUniformValue(opacityUniformPos, opacity);
- opacityOld = opacity;
- }
- }
+ void prepareProgram(const QMatrix4x4 &vertexTransform);
QOpenGLBuffer vertexBuffer;
QOpenGLBuffer textureBuffer;
- QScopedPointer<QOpenGLShaderProgram> program;
- GLuint vertexCoordAttribPos;
- GLuint vertexTransformUniformPos;
- GLuint textureCoordAttribPos;
- GLuint textureTransformUniformPos;
- GLuint swizzleUniformPos;
- GLuint opacityUniformPos;
+ struct Program {
+ Program() :
+ vertexCoordAttribPos(0),
+ vertexTransformUniformPos(0),
+ textureCoordAttribPos(0),
+ textureTransformUniformPos(0),
+ swizzleUniformPos(0),
+ opacityUniformPos(0),
+ swizzle(false),
+ opacity(0.0f),
+ textureMatrixUniformState(User)
+ { }
+ QScopedPointer<QOpenGLShaderProgram> glProgram;
+ GLuint vertexCoordAttribPos;
+ GLuint vertexTransformUniformPos;
+ GLuint textureCoordAttribPos;
+ GLuint textureTransformUniformPos;
+ GLuint swizzleUniformPos;
+ GLuint opacityUniformPos;
+ bool swizzle;
+ float opacity;
+ TextureMatrixUniform textureMatrixUniformState;
+ } programs[2];
bool swizzle;
- bool swizzleOld;
float opacity;
- float opacityOld;
- TextureMatrixUniform textureMatrixUniformState;
QScopedPointer<QOpenGLVertexArrayObject> vao;
+ GLenum currentTarget;
};
+static inline QOpenGLTextureBlitterPrivate::ProgramIndex targetToProgramIndex(GLenum target)
+{
+ switch (target) {
+ case GL_TEXTURE_2D:
+ return QOpenGLTextureBlitterPrivate::TEXTURE_2D;
+ case GL_TEXTURE_EXTERNAL_OES:
+ return QOpenGLTextureBlitterPrivate::TEXTURE_EXTERNAL_OES;
+ default:
+ qWarning("Unsupported texture target 0x%x", target);
+ return QOpenGLTextureBlitterPrivate::TEXTURE_2D;
+ }
+}
+
+void QOpenGLTextureBlitterPrivate::prepareProgram(const QMatrix4x4 &vertexTransform)
+{
+ Program *program = &programs[targetToProgramIndex(currentTarget)];
+
+ vertexBuffer.bind();
+ program->glProgram->setAttributeBuffer(program->vertexCoordAttribPos, GL_FLOAT, 0, 3, 0);
+ program->glProgram->enableAttributeArray(program->vertexCoordAttribPos);
+ vertexBuffer.release();
+
+ program->glProgram->setUniformValue(program->vertexTransformUniformPos, vertexTransform);
+
+ textureBuffer.bind();
+ program->glProgram->setAttributeBuffer(program->textureCoordAttribPos, GL_FLOAT, 0, 2, 0);
+ program->glProgram->enableAttributeArray(program->textureCoordAttribPos);
+ textureBuffer.release();
+
+ if (swizzle != program->swizzle) {
+ program->glProgram->setUniformValue(program->swizzleUniformPos, swizzle);
+ program->swizzle = swizzle;
+ }
+
+ if (opacity != program->opacity) {
+ program->glProgram->setUniformValue(program->opacityUniformPos, opacity);
+ program->opacity = opacity;
+ }
+}
+
void QOpenGLTextureBlitterPrivate::blit(GLuint texture,
const QMatrix4x4 &vertexTransform,
const QMatrix3x3 &textureTransform)
{
- TextureBinder binder(texture);
+ TextureBinder binder(currentTarget, texture);
prepareProgram(vertexTransform);
- program->setUniformValue(textureTransformUniformPos, textureTransform);
- textureMatrixUniformState = User;
+ Program *program = &programs[targetToProgramIndex(currentTarget)];
+ program->glProgram->setUniformValue(program->textureTransformUniformPos, textureTransform);
+ program->textureMatrixUniformState = User;
QOpenGLContext::currentContext()->functions()->glDrawArrays(GL_TRIANGLES, 0, 6);
}
@@ -204,25 +255,54 @@ void QOpenGLTextureBlitterPrivate::blit(GLuint texture,
const QMatrix4x4 &vertexTransform,
QOpenGLTextureBlitter::Origin origin)
{
- TextureBinder binder(texture);
+ TextureBinder binder(currentTarget, texture);
prepareProgram(vertexTransform);
+ Program *program = &programs[targetToProgramIndex(currentTarget)];
if (origin == QOpenGLTextureBlitter::OriginTopLeft) {
- if (textureMatrixUniformState != IdentityFlipped) {
+ if (program->textureMatrixUniformState != IdentityFlipped) {
QMatrix3x3 flipped;
flipped(1,1) = -1;
flipped(1,2) = 1;
- program->setUniformValue(textureTransformUniformPos, flipped);
- textureMatrixUniformState = IdentityFlipped;
+ program->glProgram->setUniformValue(program->textureTransformUniformPos, flipped);
+ program->textureMatrixUniformState = IdentityFlipped;
}
- } else if (textureMatrixUniformState != Identity) {
- program->setUniformValue(textureTransformUniformPos, QMatrix3x3());
- textureMatrixUniformState = Identity;
+ } else if (program->textureMatrixUniformState != Identity) {
+ program->glProgram->setUniformValue(program->textureTransformUniformPos, QMatrix3x3());
+ program->textureMatrixUniformState = Identity;
}
QOpenGLContext::currentContext()->functions()->glDrawArrays(GL_TRIANGLES, 0, 6);
}
+bool QOpenGLTextureBlitterPrivate::buildProgram(ProgramIndex idx, const char *vs, const char *fs)
+{
+ Program *p = &programs[idx];
+
+ p->glProgram.reset(new QOpenGLShaderProgram);
+
+ p->glProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, vs);
+ p->glProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, fs);
+ p->glProgram->link();
+ if (!p->glProgram->isLinked()) {
+ qWarning() << "Could not link shader program:\n" << p->glProgram->log();
+ return false;
+ }
+
+ p->glProgram->bind();
+
+ p->vertexCoordAttribPos = p->glProgram->attributeLocation("vertexCoord");
+ p->vertexTransformUniformPos = p->glProgram->uniformLocation("vertexTransform");
+ p->textureCoordAttribPos = p->glProgram->attributeLocation("textureCoord");
+ p->textureTransformUniformPos = p->glProgram->uniformLocation("textureTransform");
+ p->swizzleUniformPos = p->glProgram->uniformLocation("swizzle");
+ p->opacityUniformPos = p->glProgram->uniformLocation("opacity");
+
+ p->glProgram->setUniformValue(p->swizzleUniformPos, false);
+
+ return true;
+}
+
QOpenGLTextureBlitter::QOpenGLTextureBlitter()
: d_ptr(new QOpenGLTextureBlitterPrivate)
{
@@ -241,28 +321,21 @@ bool QOpenGLTextureBlitter::create()
Q_D(QOpenGLTextureBlitter);
- if (d->program)
+ if (d->programs[QOpenGLTextureBlitterPrivate::TEXTURE_2D].glProgram)
return true;
- d->program.reset(new QOpenGLShaderProgram());
-
QSurfaceFormat format = currentContext->format();
-
if (format.profile() == QSurfaceFormat::CoreProfile && format.version() >= qMakePair(3,2)) {
- d->program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertex_shader150);
- d->program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragment_shader150);
+ if (!d->buildProgram(QOpenGLTextureBlitterPrivate::TEXTURE_2D, vertex_shader150, fragment_shader150))
+ return false;
} else {
- d->program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertex_shader);
- d->program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragment_shader);
- }
- d->program->link();
- if (!d->program->isLinked()) {
- qWarning() << Q_FUNC_INFO << "Could not link shader program:\n" << d->program->log();
- return false;
+ if (!d->buildProgram(QOpenGLTextureBlitterPrivate::TEXTURE_2D, vertex_shader, fragment_shader))
+ return false;
+ if (supportsExternalOESTarget())
+ if (!d->buildProgram(QOpenGLTextureBlitterPrivate::TEXTURE_EXTERNAL_OES, vertex_shader, fragment_shader_external_oes))
+ return false;
}
- d->program->bind();
-
// Create and bind the VAO, if supported.
QOpenGLVertexArrayObject::Binder vaoBinder(d->vao.data());
@@ -276,22 +349,13 @@ bool QOpenGLTextureBlitter::create()
d->textureBuffer.allocate(texture_buffer_data, sizeof(texture_buffer_data));
d->textureBuffer.release();
- d->vertexCoordAttribPos = d->program->attributeLocation("vertexCoord");
- d->vertexTransformUniformPos = d->program->uniformLocation("vertexTransform");
- d->textureCoordAttribPos = d->program->attributeLocation("textureCoord");
- d->textureTransformUniformPos = d->program->uniformLocation("textureTransform");
- d->swizzleUniformPos = d->program->uniformLocation("swizzle");
- d->opacityUniformPos = d->program->uniformLocation("opacity");
-
- d->program->setUniformValue(d->swizzleUniformPos,false);
-
return true;
}
bool QOpenGLTextureBlitter::isCreated() const
{
Q_D(const QOpenGLTextureBlitter);
- return d->program;
+ return d->programs[QOpenGLTextureBlitterPrivate::TEXTURE_2D].glProgram;
}
void QOpenGLTextureBlitter::destroy()
@@ -299,36 +363,45 @@ void QOpenGLTextureBlitter::destroy()
if (!isCreated())
return;
Q_D(QOpenGLTextureBlitter);
- d->program.reset();
+ d->programs[QOpenGLTextureBlitterPrivate::TEXTURE_2D].glProgram.reset();
+ d->programs[QOpenGLTextureBlitterPrivate::TEXTURE_EXTERNAL_OES].glProgram.reset();
d->vertexBuffer.destroy();
d->textureBuffer.destroy();
d->vao.reset();
}
-void QOpenGLTextureBlitter::bind()
+bool QOpenGLTextureBlitter::supportsExternalOESTarget() const
+{
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ return ctx && ctx->isOpenGLES() && ctx->hasExtension("GL_OES_EGL_image_external");
+}
+
+void QOpenGLTextureBlitter::bind(GLenum target)
{
Q_D(QOpenGLTextureBlitter);
if (d->vao->isCreated())
d->vao->bind();
- d->program->bind();
+ d->currentTarget = target;
+ QOpenGLTextureBlitterPrivate::Program *p = &d->programs[targetToProgramIndex(target)];
+ p->glProgram->bind();
d->vertexBuffer.bind();
- d->program->setAttributeBuffer(d->vertexCoordAttribPos, GL_FLOAT, 0, 3, 0);
- d->program->enableAttributeArray(d->vertexCoordAttribPos);
+ p->glProgram->setAttributeBuffer(p->vertexCoordAttribPos, GL_FLOAT, 0, 3, 0);
+ p->glProgram->enableAttributeArray(p->vertexCoordAttribPos);
d->vertexBuffer.release();
d->textureBuffer.bind();
- d->program->setAttributeBuffer(d->textureCoordAttribPos, GL_FLOAT, 0, 2, 0);
- d->program->enableAttributeArray(d->textureCoordAttribPos);
+ p->glProgram->setAttributeBuffer(p->textureCoordAttribPos, GL_FLOAT, 0, 2, 0);
+ p->glProgram->enableAttributeArray(p->textureCoordAttribPos);
d->textureBuffer.release();
}
void QOpenGLTextureBlitter::release()
{
Q_D(QOpenGLTextureBlitter);
- d->program->release();
+ d->programs[targetToProgramIndex(d->currentTarget)].glProgram->release();
if (d->vao->isCreated())
d->vao->release();
}
diff --git a/src/gui/opengl/qopengltextureblitter_p.h b/src/gui/opengl/qopengltextureblitter_p.h
index 8f7eae1c32..ebf3a4bfbb 100644
--- a/src/gui/opengl/qopengltextureblitter_p.h
+++ b/src/gui/opengl/qopengltextureblitter_p.h
@@ -68,7 +68,9 @@ public:
bool isCreated() const;
void destroy();
- void bind();
+ bool supportsExternalOESTarget() const;
+
+ void bind(GLenum target = GL_TEXTURE_2D);
void release();
void setSwizzleRB(bool swizzle);
diff --git a/src/gui/opengl/qopengltexturehelper.cpp b/src/gui/opengl/qopengltexturehelper.cpp
index bf8b514449..df2945a479 100644
--- a/src/gui/opengl/qopengltexturehelper.cpp
+++ b/src/gui/opengl/qopengltexturehelper.cpp
@@ -453,260 +453,192 @@ void QOpenGLTextureHelper::dsa_CompressedTextureImage3D(GLuint texture, GLenum t
CompressedTextureImage3DEXT(texture, target, level, internalFormat, width, height, depth, border, imageSize, bits);
}
+namespace {
+
+class TextureBinder
+{
+public:
+ TextureBinder(QOpenGLTextureHelper *textureFunctions, GLuint texture, GLenum target, GLenum bindingTarget)
+ : m_textureFunctions(textureFunctions)
+ {
+ // For cubemaps we can't use the standard DSA emulation as it is illegal to
+ // try to bind a texture to one of the cubemap face targets. So we force the
+ // target and binding target to the cubemap values in this case.
+ switch (target) {
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ bindingTarget = GL_TEXTURE_BINDING_CUBE_MAP;
+ m_target = GL_TEXTURE_CUBE_MAP;
+ break;
+
+ default:
+ m_target = target;
+ break;
+ }
+
+ m_textureFunctions->glGetIntegerv(bindingTarget, &m_oldTexture);
+ m_textureFunctions->glBindTexture(m_target, texture);
+ }
+
+ ~TextureBinder()
+ {
+ m_textureFunctions->glBindTexture(m_target, m_oldTexture);
+ }
+
+private:
+ QOpenGLTextureHelper *m_textureFunctions;
+ GLenum m_target;
+ GLint m_oldTexture;
+};
+
+} // namespace
+
void QOpenGLTextureHelper::qt_TextureParameteri(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param)
{
- GLint oldTexture;
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
+ TextureBinder binder(this, texture, target, bindingTarget);
glTexParameteri(target, pname, param);
- glBindTexture(target, oldTexture);
}
void QOpenGLTextureHelper::qt_TextureParameteriv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLint *params)
{
- GLint oldTexture;
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
+ TextureBinder binder(this, texture, target, bindingTarget);
glTexParameteriv(target, pname, params);
- glBindTexture(target, oldTexture);
}
void QOpenGLTextureHelper::qt_TextureParameterf(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLfloat param)
{
- GLint oldTexture;
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
+ TextureBinder binder(this, texture, target, bindingTarget);
glTexParameterf(target, pname, param);
- glBindTexture(target, oldTexture);
}
void QOpenGLTextureHelper::qt_TextureParameterfv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLfloat *params)
{
- GLint oldTexture;
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
+ TextureBinder binder(this, texture, target, bindingTarget);
glTexParameterfv(target, pname, params);
- glBindTexture(target, oldTexture);
}
void QOpenGLTextureHelper::qt_GenerateTextureMipmap(GLuint texture, GLenum target, GLenum bindingTarget)
{
- GLint oldTexture;
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
+ TextureBinder binder(this, texture, target, bindingTarget);
glGenerateMipmap(target);
- glBindTexture(target, oldTexture);
}
void QOpenGLTextureHelper::qt_TextureStorage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth)
{
- GLint oldTexture;
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
+ TextureBinder binder(this, texture, target, bindingTarget);
glTexStorage3D(target, levels, internalFormat, width, height, depth);
- glBindTexture(target, oldTexture);
}
void QOpenGLTextureHelper::qt_TextureStorage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height)
{
- GLint oldTexture;
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
+ TextureBinder binder(this, texture, target, bindingTarget);
glTexStorage2D(target, levels, internalFormat, width, height);
- glBindTexture(target, oldTexture);
}
void QOpenGLTextureHelper::qt_TextureStorage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width)
{
- GLint oldTexture;
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
+ TextureBinder binder(this, texture, target, bindingTarget);
glTexStorage1D(target, levels, internalFormat, width);
- glBindTexture(target, oldTexture);
}
void QOpenGLTextureHelper::qt_TextureStorage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations)
{
- GLint oldTexture;
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
+ TextureBinder binder(this, texture, target, bindingTarget);
glTexStorage3DMultisample(target, samples, internalFormat, width, height, depth, fixedSampleLocations);
- glBindTexture(target, oldTexture);
}
void QOpenGLTextureHelper::qt_TextureStorage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations)
{
- GLint oldTexture;
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
+ TextureBinder binder(this, texture, target, bindingTarget);
glTexStorage2DMultisample(target, samples, internalFormat, width, height, fixedSampleLocations);
- glBindTexture(target, oldTexture);
}
void QOpenGLTextureHelper::qt_TextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
{
- GLint oldTexture;
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
+ TextureBinder binder(this, texture, target, bindingTarget);
glTexImage3D(target, level, internalFormat, width, height, depth, border, format, type, pixels);
- glBindTexture(target, oldTexture);
}
void QOpenGLTextureHelper::qt_TextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
{
- // For cubemaps we can't use the standard DSA emulation as it is illegal to
- // try to bind a texture to one of the cubemap face targets. So we force the
- // target and binding target to the cubemap values in this case.
- GLint oldTexture;
-
- switch (target) {
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &oldTexture);
- glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
- glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels);
- glBindTexture(GL_TEXTURE_CUBE_MAP, oldTexture);
- break;
-
- default:
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
- glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels);
- glBindTexture(target, oldTexture);
- break;
- }
+ TextureBinder binder(this, texture, target, bindingTarget);
+ glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels);
}
void QOpenGLTextureHelper::qt_TextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
{
- GLint oldTexture;
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
+ TextureBinder binder(this, texture, target, bindingTarget);
glTexImage1D(target, level, internalFormat, width, border, format, type, pixels);
- glBindTexture(target, oldTexture);
}
void QOpenGLTextureHelper::qt_TextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels)
{
- GLint oldTexture;
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
+ TextureBinder binder(this, texture, target, bindingTarget);
glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
- glBindTexture(target, oldTexture);
}
void QOpenGLTextureHelper::qt_TextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
{
- // For cubemaps we can't use the standard DSA emulation as it is illegal to
- // try to bind a texture to one of the cubemap face targets. So we force the
- // target and binding target to the cubemap values in this case.
- GLint oldTexture;
-
- switch (target) {
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &oldTexture);
- glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
- glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
- glBindTexture(GL_TEXTURE_CUBE_MAP, oldTexture);
- break;
-
- default:
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
- glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
- glBindTexture(target, oldTexture);
- break;
- }
+ TextureBinder binder(this, texture, target, bindingTarget);
+ glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
}
void QOpenGLTextureHelper::qt_TextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)
{
- GLint oldTexture;
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
+ TextureBinder binder(this, texture, target, bindingTarget);
glTexSubImage1D(target, level, xoffset, width, format, type, pixels);
- glBindTexture(target, oldTexture);
}
void QOpenGLTextureHelper::qt_TextureImage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations)
{
- GLint oldTexture;
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
+ TextureBinder binder(this, texture, target, bindingTarget);
glTexImage3DMultisample(target, samples, internalFormat, width, height, depth, fixedSampleLocations);
- glBindTexture(target, oldTexture);
}
void QOpenGLTextureHelper::qt_TextureImage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations)
{
- GLint oldTexture;
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
+ TextureBinder binder(this, texture, target, bindingTarget);
glTexImage2DMultisample(target, samples, internalFormat, width, height, fixedSampleLocations);
- glBindTexture(target, oldTexture);
}
void QOpenGLTextureHelper::qt_CompressedTextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits)
{
- GLint oldTexture;
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
+ TextureBinder binder(this, texture, target, bindingTarget);
glCompressedTexSubImage1D(target, level, xoffset, width, format, imageSize, bits);
- glBindTexture(target, oldTexture);
}
void QOpenGLTextureHelper::qt_CompressedTextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits)
{
- GLint oldTexture;
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
+ TextureBinder binder(this, texture, target, bindingTarget);
glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, bits);
- glBindTexture(target, oldTexture);
}
void QOpenGLTextureHelper::qt_CompressedTextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits)
{
- GLint oldTexture;
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
+ TextureBinder binder(this, texture, target, bindingTarget);
glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits);
- glBindTexture(target, oldTexture);
}
void QOpenGLTextureHelper::qt_CompressedTextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits)
{
- GLint oldTexture;
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
+ TextureBinder binder(this, texture, target, bindingTarget);
glCompressedTexImage1D(target, level, internalFormat, width, border, imageSize, bits);
- glBindTexture(target, oldTexture);
}
void QOpenGLTextureHelper::qt_CompressedTextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits)
{
- GLint oldTexture;
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
+ TextureBinder binder(this, texture, target, bindingTarget);
glCompressedTexImage2D(target, level, internalFormat, width, height, border, imageSize, bits);
- glBindTexture(target, oldTexture);
}
void QOpenGLTextureHelper::qt_CompressedTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits)
{
- GLint oldTexture;
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
+ TextureBinder binder(this, texture, target, bindingTarget);
glCompressedTexImage3D(target, level, internalFormat, width, height, depth, border, imageSize, bits);
- glBindTexture(target, oldTexture);
}
QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopengltexturehelper_p.h b/src/gui/opengl/qopengltexturehelper_p.h
index 5a56516b49..d659fcedfb 100644
--- a/src/gui/opengl/qopengltexturehelper_p.h
+++ b/src/gui/opengl/qopengltexturehelper_p.h
@@ -253,23 +253,48 @@ public:
inline void glCompressedTextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
GLenum internalFormat, GLsizei width,
- GLint border, GLsizei imageSize, const GLvoid *bits)
+ GLint border, GLsizei imageSize, const GLvoid *bits,
+ const QOpenGLPixelTransferOptions * const options = 0)
{
- (this->*CompressedTextureImage1D)(texture, target, bindingTarget, level, internalFormat, width, border, imageSize, bits);
+ if (options) {
+ QOpenGLPixelTransferOptions oldOptions = savePixelUploadOptions();
+ setPixelUploadOptions(*options);
+ (this->*CompressedTextureImage1D)(texture, target, bindingTarget, level, internalFormat, width, border, imageSize, bits);
+ setPixelUploadOptions(oldOptions);
+ } else {
+ (this->*CompressedTextureImage1D)(texture, target, bindingTarget, level, internalFormat, width, border, imageSize, bits);
+ }
}
inline void glCompressedTextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
GLenum internalFormat, GLsizei width, GLsizei height,
- GLint border, GLsizei imageSize, const GLvoid *bits)
+ GLint border, GLsizei imageSize, const GLvoid *bits,
+ const QOpenGLPixelTransferOptions * const options = 0)
+
{
- (this->*CompressedTextureImage2D)(texture, target, bindingTarget, level, internalFormat, width, height, border, imageSize, bits);
+ if (options) {
+ QOpenGLPixelTransferOptions oldOptions = savePixelUploadOptions();
+ setPixelUploadOptions(*options);
+ (this->*CompressedTextureImage2D)(texture, target, bindingTarget, level, internalFormat, width, height, border, imageSize, bits);
+ setPixelUploadOptions(oldOptions);
+ } else {
+ (this->*CompressedTextureImage2D)(texture, target, bindingTarget, level, internalFormat, width, height, border, imageSize, bits);
+ }
}
inline void glCompressedTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth,
- GLint border, GLsizei imageSize, const GLvoid *bits)
+ GLint border, GLsizei imageSize, const GLvoid *bits,
+ const QOpenGLPixelTransferOptions * const options = 0)
{
- (this->*CompressedTextureImage3D)(texture, target, bindingTarget, level, internalFormat, width, height, depth, border, imageSize, bits);
+ if (options) {
+ QOpenGLPixelTransferOptions oldOptions = savePixelUploadOptions();
+ setPixelUploadOptions(*options);
+ (this->*CompressedTextureImage3D)(texture, target, bindingTarget, level, internalFormat, width, height, depth, border, imageSize, bits);
+ setPixelUploadOptions(oldOptions);
+ } else {
+ (this->*CompressedTextureImage3D)(texture, target, bindingTarget, level, internalFormat, width, height, depth, border, imageSize, bits);
+ }
}
private:
diff --git a/src/gui/opengl/qopengltimerquery.h b/src/gui/opengl/qopengltimerquery.h
index 7e46250546..ad111dc03c 100644
--- a/src/gui/opengl/qopengltimerquery.h
+++ b/src/gui/opengl/qopengltimerquery.h
@@ -50,7 +50,7 @@ class Q_GUI_EXPORT QOpenGLTimerQuery : public QObject
Q_OBJECT
public:
- explicit QOpenGLTimerQuery(QObject *parent = 0);
+ explicit QOpenGLTimerQuery(QObject *parent = Q_NULLPTR);
~QOpenGLTimerQuery();
bool create();
@@ -78,7 +78,7 @@ class Q_GUI_EXPORT QOpenGLTimeMonitor : public QObject
Q_OBJECT
public:
- explicit QOpenGLTimeMonitor(QObject *parent = 0);
+ explicit QOpenGLTimeMonitor(QObject *parent = Q_NULLPTR);
~QOpenGLTimeMonitor();
void setSampleCount(int sampleCount);
diff --git a/src/gui/opengl/qopenglversionfunctions.h b/src/gui/opengl/qopenglversionfunctions.h
index fcf665f97e..a5d5677938 100644
--- a/src/gui/opengl/qopenglversionfunctions.h
+++ b/src/gui/opengl/qopenglversionfunctions.h
@@ -47,7 +47,10 @@
#ifndef QT_NO_OPENGL
+#if QT_DEPRECATED_SINCE(5, 5)
#include <QtCore/qhash.h>
+#endif
+#include <QtCore/qhashfunctions.h>
#include <QtCore/qpair.h>
#include <QtGui/qopengl.h>
@@ -120,7 +123,7 @@ class QAbstractOpenGLFunctionsPrivate
{
public:
QAbstractOpenGLFunctionsPrivate()
- : owningContext(0),
+ : owningContext(Q_NULLPTR),
initialized(false)
{}
diff --git a/src/gui/opengl/qopenglvertexarrayobject.h b/src/gui/opengl/qopenglvertexarrayobject.h
index 3e01d31202..e8ebf41071 100644
--- a/src/gui/opengl/qopenglvertexarrayobject.h
+++ b/src/gui/opengl/qopenglvertexarrayobject.h
@@ -50,7 +50,7 @@ class Q_GUI_EXPORT QOpenGLVertexArrayObject : public QObject
Q_OBJECT
public:
- explicit QOpenGLVertexArrayObject(QObject* parent = 0);
+ explicit QOpenGLVertexArrayObject(QObject* parent = Q_NULLPTR);
~QOpenGLVertexArrayObject();
bool create();
diff --git a/src/gui/opengl/qtriangulatingstroker.cpp b/src/gui/opengl/qtriangulatingstroker.cpp
index cfbf8a75c5..5967bd6e89 100644
--- a/src/gui/opengl/qtriangulatingstroker.cpp
+++ b/src/gui/opengl/qtriangulatingstroker.cpp
@@ -127,7 +127,7 @@ void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen, co
m_roundness = 1;
} else if (cosmetic) {
m_curvyness_add = realWidth / 2;
- m_curvyness_mul = CURVE_FLATNESS;
+ m_curvyness_mul = float(CURVE_FLATNESS);
m_roundness = qMax<int>(4, realWidth * CURVE_FLATNESS);
} else {
m_curvyness_add = m_width;
@@ -543,7 +543,7 @@ void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen, c
curvynessMul = CURVE_FLATNESS / m_inv_scale;
} else if (cosmetic) {
curvynessAdd= width / 2;
- curvynessMul= CURVE_FLATNESS;
+ curvynessMul= float(CURVE_FLATNESS);
} else {
curvynessAdd = width * m_inv_scale;
curvynessMul = CURVE_FLATNESS / m_inv_scale;
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index a861516821..1e516e4581 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -9,6 +9,7 @@ HEADERS += \
painting/qcolor.h \
painting/qcolor_p.h \
painting/qcosmeticstroker_p.h \
+ painting/qdatabuffer_p.h \
painting/qdrawhelper_p.h \
painting/qdrawhelper_x86_p.h \
painting/qdrawingprimitive_sse2_p.h \
@@ -43,6 +44,8 @@ HEADERS += \
painting/qrasterizer_p.h \
painting/qregion.h \
painting/qrgb.h \
+ painting/qrgba64.h \
+ painting/qrgba64_p.h \
painting/qstroker_p.h \
painting/qtextureglyphcache_p.h \
painting/qtransform.h \
@@ -58,6 +61,7 @@ SOURCES += \
painting/qbrush.cpp \
painting/qcolor.cpp \
painting/qcolor_p.cpp \
+ painting/qcompositionfunctions.cpp \
painting/qcosmeticstroker.cpp \
painting/qcssutil.cpp \
painting/qdrawhelper.cpp \
@@ -97,12 +101,10 @@ SSE4_1_SOURCES += painting/qdrawhelper_sse4.cpp \
painting/qimagescale_sse4.cpp
AVX2_SOURCES += painting/qdrawhelper_avx2.cpp
-!ios {
- CONFIG += no_clang_integrated_as
- NEON_SOURCES += painting/qdrawhelper_neon.cpp
- NEON_HEADERS += painting/qdrawhelper_neon_p.h
- NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S
-}
+NEON_SOURCES += painting/qdrawhelper_neon.cpp
+NEON_HEADERS += painting/qdrawhelper_neon_p.h
+NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S
+!ios:!contains(QT_ARCH, "arm64"): DEFINES += ENABLE_PIXMAN_DRAWHELPERS
MIPS_DSP_SOURCES += painting/qdrawhelper_mips_dsp.cpp
MIPS_DSP_HEADERS += painting/qdrawhelper_mips_dsp_p.h painting/qt_mips_asm_dsp_p.h
diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp
index f2fee99b99..8a5a6d4fcf 100644
--- a/src/gui/painting/qbackingstore.cpp
+++ b/src/gui/painting/qbackingstore.cpp
@@ -38,10 +38,13 @@
#include <qpa/qplatformintegration.h>
#include <qscreen.h>
#include <qdebug.h>
+#include <qscopedpointer.h>
#include <private/qguiapplication_p.h>
#include <private/qwindow_p.h>
+#include <private/qhighdpiscaling_p.h>
+
QT_BEGIN_NAMESPACE
class QBackingStorePrivate
@@ -54,6 +57,7 @@ public:
QWindow *window;
QPlatformBackingStore *platformBackingStore;
+ QScopedPointer<QImage> highDpiBackingstore;
QRegion staticContents;
QSize size;
};
@@ -102,7 +106,7 @@ void QBackingStore::flush(const QRegion &region, QWindow *win, const QPoint &off
}
#endif
- d_ptr->platformBackingStore->flush(win, region, offset);
+ d_ptr->platformBackingStore->flush(win, QHighDpi::toNativeLocalRegion(region, d_ptr->window), offset);
}
/*!
@@ -112,7 +116,12 @@ void QBackingStore::flush(const QRegion &region, QWindow *win, const QPoint &off
*/
QPaintDevice *QBackingStore::paintDevice()
{
- return d_ptr->platformBackingStore->paintDevice();
+ QPaintDevice *device = d_ptr->platformBackingStore->paintDevice();
+
+ if (QHighDpiScaling::isActive() && device->devType() == QInternal::Image)
+ return d_ptr->highDpiBackingstore.data();
+
+ return device;
}
/*!
@@ -150,7 +159,37 @@ QWindow* QBackingStore::window() const
void QBackingStore::beginPaint(const QRegion &region)
{
- d_ptr->platformBackingStore->beginPaint(region);
+ if (d_ptr->highDpiBackingstore &&
+ d_ptr->highDpiBackingstore->devicePixelRatio() != d_ptr->window->devicePixelRatio())
+ resize(size());
+
+ d_ptr->platformBackingStore->beginPaint(QHighDpi::toNativeLocalRegion(region, d_ptr->window));
+
+ // When QtGui is applying a high-dpi scale factor the backing store
+ // creates a "large" backing store image. This image needs to be
+ // painted on as a high-dpi image, which is done by setting
+ // devicePixelRatio. Do this on a separate image instance that shares
+ // the image data to avoid having the new devicePixelRatio be propagated
+ // back to the platform plugin.
+ QPaintDevice *device = d_ptr->platformBackingStore->paintDevice();
+ if (QHighDpiScaling::isActive() && device->devType() == QInternal::Image) {
+ QImage *source = static_cast<QImage *>(device);
+ const bool needsNewImage = d_ptr->highDpiBackingstore.isNull()
+ || source->data_ptr() != d_ptr->highDpiBackingstore->data_ptr()
+ || source->size() != d_ptr->highDpiBackingstore->size()
+ || source->devicePixelRatio() != d_ptr->highDpiBackingstore->devicePixelRatio();
+ if (needsNewImage) {
+ qCDebug(lcScaling) << "QBackingStore::beginPaint new backingstore for" << d_ptr->window;
+ qCDebug(lcScaling) << " source size" << source->size() << "dpr" << source->devicePixelRatio();
+ d_ptr->highDpiBackingstore.reset(
+ new QImage(source->bits(), source->width(), source->height(), source->bytesPerLine(), source->format()));
+
+ qreal targetDevicePixelRatio = d_ptr->window->devicePixelRatio();
+ d_ptr->highDpiBackingstore->setDevicePixelRatio(targetDevicePixelRatio);
+ qCDebug(lcScaling) <<" destination size" << d_ptr->highDpiBackingstore->size()
+ << "dpr" << targetDevicePixelRatio;
+ }
+ }
}
/*!
@@ -171,7 +210,7 @@ void QBackingStore::endPaint()
void QBackingStore::resize(const QSize &size)
{
d_ptr->size = size;
- d_ptr->platformBackingStore->resize(size, d_ptr->staticContents);
+ d_ptr->platformBackingStore->resize(QHighDpi::toNativePixels(size, d_ptr->window), d_ptr->staticContents);
}
/*!
@@ -194,7 +233,7 @@ bool QBackingStore::scroll(const QRegion &area, int dx, int dy)
Q_UNUSED(dx);
Q_UNUSED(dy);
- return d_ptr->platformBackingStore->scroll(area, dx, dy);
+ return d_ptr->platformBackingStore->scroll(QHighDpi::toNativeLocalRegion(area, d_ptr->window), QHighDpi::toNativePixels(dx, d_ptr->window), QHighDpi::toNativePixels(dy, d_ptr->window));
}
/*!
diff --git a/src/gui/painting/qbackingstore.h b/src/gui/painting/qbackingstore.h
index ee3c05f7a9..331fa8c534 100644
--- a/src/gui/painting/qbackingstore.h
+++ b/src/gui/painting/qbackingstore.h
@@ -61,7 +61,7 @@ public:
// 'window' can be a child window, in which case 'region' is in child window coordinates and
// offset is the (child) window's offset in relation to the window surface.
- void flush(const QRegion &region, QWindow *window = 0, const QPoint &offset = QPoint());
+ void flush(const QRegion &region, QWindow *window = Q_NULLPTR, const QPoint &offset = QPoint());
void resize(const QSize &size);
QSize size() const;
diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp
index dbdd82e432..0898a20998 100644
--- a/src/gui/painting/qblendfunctions.cpp
+++ b/src/gui/painting/qblendfunctions.cpp
@@ -395,169 +395,6 @@ void qt_blend_rgb32_on_rgb32(uchar *destPixels, int dbpl,
}
}
-template<QtPixelOrder PixelOrder>
-static void qt_blend_argb32pm_on_a2rgb30pm(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- int w, int h,
- int const_alpha)
-{
-#ifdef QT_DEBUG_DRAW
- fprintf(stdout, "qt_blend_argb32pm_on_a2rgb30pm: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
- destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
- fflush(stdout);
-#endif
-
- const uint *src = (const uint *) srcPixels;
- uint *dst = (uint *) destPixels;
- if (const_alpha == 256) {
- for (int y=0; y<h; ++y) {
- for (int x=0; x<w; ++x) {
- uint s = src[x];
- dst[x] = qConvertArgb32ToA2rgb30<PixelOrder>(s) + BYTE_MUL_RGB30(dst[x], 255 - qAlpha(s));
- }
- dst = (quint32 *)(((uchar *) dst) + dbpl);
- src = (const quint32 *)(((const uchar *) src) + sbpl);
- }
- } else if (const_alpha != 0) {
- const_alpha = (const_alpha * 255) >> 8;
- for (int y=0; y<h; ++y) {
- for (int x=0; x<w; ++x) {
- uint s = src[x];
- dst[x] = BYTE_MUL_RGB30(qConvertArgb32ToA2rgb30<PixelOrder>(s), const_alpha) + BYTE_MUL_RGB30(dst[x], 255 - qt_div_255(qAlpha(s) * const_alpha));
- }
- dst = (quint32 *)(((uchar *) dst) + dbpl);
- src = (const quint32 *)(((const uchar *) src) + sbpl);
- }
- }
-}
-
-template<QtPixelOrder PixelOrder>
-static void qt_blend_rgb32_on_rgb30(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- int w, int h,
- int const_alpha)
-{
-#ifdef QT_DEBUG_DRAW
- fprintf(stdout, "qt_blend_rgb32_on_rgb30: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
- destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
- fflush(stdout);
-#endif
-
- if (const_alpha != 256) {
- qt_blend_argb32pm_on_a2rgb30pm<PixelOrder>(destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
- return;
- }
-
- const uint *src = (const uint *) srcPixels;
- uint *dst = (uint *) destPixels;
- for (int y = 0; y < h; ++y) {
- for (int x = 0; x < w; ++x) {
- dst[x] = qConvertRgb32ToRgb30<PixelOrder>(src[x]);
- }
- dst = (quint32 *)(((uchar *) dst) + dbpl);
- src = (const quint32 *)(((const uchar *) src) + sbpl);
- }
-}
-
-static void qt_blend_a2rgb30pm_on_a2rgb30pm(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- int w, int h,
- int const_alpha)
-{
-#ifdef QT_DEBUG_DRAW
- fprintf(stdout, "qt_blend_a2rgb30pm_on_a2rgb30pm: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
- destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
- fflush(stdout);
-#endif
-
- const uint *src = (const uint *) srcPixels;
- uint *dst = (uint *) destPixels;
- if (const_alpha == 256) {
- for (int y=0; y<h; ++y) {
- for (int x=0; x<w; ++x) {
- uint s = src[x];
- dst[x] = s + BYTE_MUL_RGB30(dst[x], 255 - qAlphaRgb30(s));
- }
- dst = (quint32 *)(((uchar *) dst) + dbpl);
- src = (const quint32 *)(((const uchar *) src) + sbpl);
- }
- } else if (const_alpha != 0) {
- const uint const_alpha255 = (const_alpha * 255) >> 8;
- for (int y=0; y<h; ++y) {
- for (int x=0; x<w; ++x) {
- uint a = (qAlphaRgb30(src[x]) * const_alpha) >> 8;
- uint s = BYTE_MUL_RGB30(src[x], const_alpha255);
- dst[x] = s + BYTE_MUL_RGB30(dst[x], 255 - a);
- }
- dst = (quint32 *)(((uchar *) dst) + dbpl);
- src = (const quint32 *)(((const uchar *) src) + sbpl);
- }
- }
-}
-
-
-static void qt_blend_rgb30_on_rgb30(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- int w, int h,
- int const_alpha)
-{
-#ifdef QT_DEBUG_DRAW
- fprintf(stdout, "qt_blend_rgb30_on_rgb30: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
- destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
- fflush(stdout);
-#endif
-
- if (const_alpha != 256) {
- qt_blend_a2rgb30pm_on_a2rgb30pm(destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
- return;
- }
-
- const uint *src = (const uint *) srcPixels;
- uint *dst = (uint *) destPixels;
- int len = w * 4;
- for (int y=0; y<h; ++y) {
- memcpy(dst, src, len);
- dst = (quint32 *)(((uchar *) dst) + dbpl);
- src = (const quint32 *)(((const uchar *) src) + sbpl);
- }
-}
-
-static void qt_blend_a2bgr30pm_on_a2rgb30pm(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- int w, int h,
- int const_alpha)
-{
-#ifdef QT_DEBUG_DRAW
- fprintf(stdout, "qt_blend_a2bgr30pm_on_a2rgb32pm: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
- destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
- fflush(stdout);
-#endif
-
- const uint *src = (const uint *) srcPixels;
- uint *dst = (uint *) destPixels;
- if (const_alpha == 256) {
- for (int y=0; y<h; ++y) {
- for (int x=0; x<w; ++x) {
- uint s = qRgbSwapRgb30(src[x]);
- dst[x] = s + BYTE_MUL_RGB30(dst[x], 255 - qAlphaRgb30(s));
- }
- dst = (quint32 *)(((uchar *) dst) + dbpl);
- src = (const quint32 *)(((const uchar *) src) + sbpl);
- }
- } else if (const_alpha != 0) {
- const uint const_alpha255 = (const_alpha * 255) >> 8;
- for (int y=0; y<h; ++y) {
- for (int x=0; x<w; ++x) {
- uint a = (qAlphaRgb30(src[x]) * const_alpha) >> 8;
- uint s = BYTE_MUL_RGB30(src[x], const_alpha255);
- dst[x] = qRgbSwapRgb30(s) + BYTE_MUL_RGB30(dst[x], 255 - a);
- }
- dst = (quint32 *)(((uchar *) dst) + dbpl);
- src = (const quint32 *)(((const uchar *) src) + sbpl);
- }
- }
-}
-
struct Blend_RGB32_on_RGB32_NoAlpha {
inline void write(quint32 *dst, quint32 src) { *dst = src; }
@@ -772,30 +609,6 @@ void qInitBlendFunctions()
qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32;
qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32;
#endif
- qBlendFunctions[QImage::Format_BGR30][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb30<PixelOrderBGR>;
- qBlendFunctions[QImage::Format_BGR30][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32pm_on_a2rgb30pm<PixelOrderBGR>;
- qBlendFunctions[QImage::Format_BGR30][QImage::Format_BGR30] = qt_blend_rgb30_on_rgb30;
- qBlendFunctions[QImage::Format_BGR30][QImage::Format_A2BGR30_Premultiplied] = qt_blend_a2rgb30pm_on_a2rgb30pm;
- qBlendFunctions[QImage::Format_BGR30][QImage::Format_RGB30] = qt_blend_a2bgr30pm_on_a2rgb30pm;
- qBlendFunctions[QImage::Format_BGR30][QImage::Format_A2RGB30_Premultiplied] = qt_blend_a2bgr30pm_on_a2rgb30pm;
- qBlendFunctions[QImage::Format_A2BGR30_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb30<PixelOrderBGR>;
- qBlendFunctions[QImage::Format_A2BGR30_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32pm_on_a2rgb30pm<PixelOrderBGR>;
- qBlendFunctions[QImage::Format_A2BGR30_Premultiplied][QImage::Format_BGR30] = qt_blend_rgb30_on_rgb30;
- qBlendFunctions[QImage::Format_A2BGR30_Premultiplied][QImage::Format_A2BGR30_Premultiplied] = qt_blend_a2rgb30pm_on_a2rgb30pm;
- qBlendFunctions[QImage::Format_A2BGR30_Premultiplied][QImage::Format_RGB30] = qt_blend_a2bgr30pm_on_a2rgb30pm;
- qBlendFunctions[QImage::Format_A2BGR30_Premultiplied][QImage::Format_A2RGB30_Premultiplied] = qt_blend_a2bgr30pm_on_a2rgb30pm;
- qBlendFunctions[QImage::Format_RGB30][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb30<PixelOrderRGB>;
- qBlendFunctions[QImage::Format_RGB30][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32pm_on_a2rgb30pm<PixelOrderRGB>;
- qBlendFunctions[QImage::Format_RGB30][QImage::Format_BGR30] = qt_blend_a2bgr30pm_on_a2rgb30pm;
- qBlendFunctions[QImage::Format_RGB30][QImage::Format_A2BGR30_Premultiplied] = qt_blend_a2bgr30pm_on_a2rgb30pm;
- qBlendFunctions[QImage::Format_RGB30][QImage::Format_RGB30] = qt_blend_rgb30_on_rgb30;
- qBlendFunctions[QImage::Format_RGB30][QImage::Format_A2RGB30_Premultiplied] = qt_blend_a2rgb30pm_on_a2rgb30pm;
- qBlendFunctions[QImage::Format_A2RGB30_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb30<PixelOrderRGB>;
- qBlendFunctions[QImage::Format_A2RGB30_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32pm_on_a2rgb30pm<PixelOrderRGB>;
- qBlendFunctions[QImage::Format_A2RGB30_Premultiplied][QImage::Format_BGR30] = qt_blend_a2bgr30pm_on_a2rgb30pm;
- qBlendFunctions[QImage::Format_A2RGB30_Premultiplied][QImage::Format_A2BGR30_Premultiplied] = qt_blend_a2bgr30pm_on_a2rgb30pm;
- qBlendFunctions[QImage::Format_A2RGB30_Premultiplied][QImage::Format_RGB30] = qt_blend_rgb30_on_rgb30;
- qBlendFunctions[QImage::Format_A2RGB30_Premultiplied][QImage::Format_A2RGB30_Premultiplied] = qt_blend_a2rgb30pm_on_a2rgb30pm;
qTransformFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_transform_image_rgb32_on_rgb32;
qTransformFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_argb32;
diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp
index c3a0f5c615..9e039b7ae4 100644
--- a/src/gui/painting/qbrush.cpp
+++ b/src/gui/painting/qbrush.cpp
@@ -1163,6 +1163,7 @@ QDataStream &operator>>(QDataStream &s, QBrush &b)
QColor c;
s >> numStops;
+ stops.reserve(numStops);
for (quint32 i = 0; i < numStops; ++i) {
s >> n >> c;
stops << QPair<qreal, QColor>(n, c);
diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index d50c42f1ee..3f30c061dc 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -416,6 +416,18 @@ QColor::QColor(QRgb color)
ct.argb.pad = 0;
}
+/*!
+ \since 5.6
+
+ Constructs a color with the value \a rgba64.
+
+ \sa fromRgba64()
+*/
+
+QColor::QColor(QRgba64 rgba64)
+{
+ setRgba64(rgba64);
+}
/*!
\internal
@@ -469,6 +481,7 @@ QColor::QColor(Spec spec)
\sa setNamedColor(), name(), isValid()
*/
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
/*!
\fn QColor::QColor(const QColor &color)
@@ -476,6 +489,7 @@ QColor::QColor(Spec spec)
\sa isValid()
*/
+#endif
/*!
\fn bool QColor::isValid() const
@@ -941,7 +955,7 @@ void QColor::setRgb(int r, int g, int b, int a)
For an invalid color, the alpha value of the returned color is unspecified.
- \sa setRgba(), rgb()
+ \sa setRgba(), rgb(), rgba64()
*/
QRgb QColor::rgba() const
@@ -954,7 +968,7 @@ QRgb QColor::rgba() const
/*!
Sets the RGB value to \a rgba, including its alpha.
- \sa rgba(), rgb()
+ \sa rgba(), rgb(), setRgba64()
*/
void QColor::setRgba(QRgb rgba)
{
@@ -967,6 +981,40 @@ void QColor::setRgba(QRgb rgba)
}
/*!
+ \since 5.6
+
+ Returns the RGB64 value of the color, including its alpha.
+
+ For an invalid color, the alpha value of the returned color is unspecified.
+
+ \sa setRgba64(), rgba(), rgb()
+*/
+
+QRgba64 QColor::rgba64() const
+{
+ if (cspec != Invalid && cspec != Rgb)
+ return toRgb().rgba64();
+ return qRgba64(ct.argb.red, ct.argb.green, ct.argb.blue, ct.argb.alpha);
+}
+
+/*!
+ \since 5.6
+
+ Sets the RGB64 value to \a rgba, including its alpha.
+
+ \sa \setRgba(), rgba64()
+*/
+void QColor::setRgba64(QRgba64 rgba)
+{
+ cspec = Rgb;
+ ct.argb.alpha = rgba.alpha();
+ ct.argb.red = rgba.red();
+ ct.argb.green = rgba.green();
+ ct.argb.blue = rgba.blue();
+ ct.argb.pad = 0;
+}
+
+/*!
\fn QRgb QColor::rgb() const
Returns the RGB value of the color. The alpha value is opaque.
@@ -1850,7 +1898,7 @@ QColor QColor::fromRgb(QRgb rgb)
Unlike the fromRgb() function, the alpha-channel specified by the given
QRgb value is included.
- \sa fromRgb(), isValid()
+ \sa fromRgb(), fromRgba64(), isValid()
*/
QColor QColor::fromRgba(QRgb rgba)
@@ -1865,7 +1913,7 @@ QColor QColor::fromRgba(QRgb rgba)
All the values must be in the range 0-255.
- \sa toRgb(), fromRgbF(), isValid()
+ \sa toRgb(), fromRgba64(), fromRgbF(), isValid()
*/
QColor QColor::fromRgb(int r, int g, int b, int a)
{
@@ -1894,7 +1942,7 @@ QColor QColor::fromRgb(int r, int g, int b, int a)
All the values must be in the range 0.0-1.0.
- \sa fromRgb(), toRgb(), isValid()
+ \sa fromRgb(), fromRgba64(), toRgb(), isValid()
*/
QColor QColor::fromRgbF(qreal r, qreal g, qreal b, qreal a)
{
@@ -1916,6 +1964,38 @@ QColor QColor::fromRgbF(qreal r, qreal g, qreal b, qreal a)
return color;
}
+
+/*!
+ \since 5.6
+
+ Static convenience function that returns a QColor constructed from the RGBA64
+ color values, \a r (red), \a g (green), \a b (blue), and \a a
+ (alpha-channel, i.e. transparency).
+
+ \sa fromRgb(), fromRgbF(), toRgb(), isValid()
+*/
+QColor QColor::fromRgba64(ushort r, ushort g, ushort b, ushort a)
+{
+ QColor color;
+ color.setRgba64(qRgba64(r, g, b, a));
+ return color;
+}
+
+/*!
+ \since 5.6
+
+ Static convenience function that returns a QColor constructed from the
+ given QRgba64 value \a rgba64.
+
+ \sa fromRgb(), fromRgbF(), toRgb(), isValid()
+*/
+QColor QColor::fromRgba64(QRgba64 rgba64)
+{
+ QColor color;
+ color.setRgba64(rgba64);
+ return color;
+}
+
/*!
Static convenience function that returns a QColor constructed from the HSV
color values, \a h (hue), \a s (saturation), \a v (value), and \a a
@@ -1995,7 +2075,7 @@ QColor QColor::fromHsl(int h, int s, int l, int a)
|| s < 0 || s > 255
|| l < 0 || l > 255
|| a < 0 || a > 255) {
- qWarning("QColor::fromHsv: HSV parameters out of range");
+ qWarning("QColor::fromHsl: HSL parameters out of range");
return QColor();
}
@@ -2027,7 +2107,7 @@ QColor QColor::fromHslF(qreal h, qreal s, qreal l, qreal a)
|| (s < qreal(0.0) || s > qreal(1.0))
|| (l < qreal(0.0) || l > qreal(1.0))
|| (a < qreal(0.0) || a > qreal(1.0))) {
- qWarning("QColor::fromHsvF: HSV parameters out of range");
+ qWarning("QColor::fromHslF: HSL parameters out of range");
return QColor();
}
@@ -2307,6 +2387,7 @@ QColor QColor::dark(int factor) const
return hsv.convertTo(cspec);
}
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
/*!
Assigns a copy of \a color to this color, and returns a reference to it.
*/
@@ -2316,6 +2397,7 @@ QColor &QColor::operator=(const QColor &color)
ct.argb = color.ct.argb;
return *this;
}
+#endif
/*! \overload
Assigns a copy of \a color and returns a reference to this color.
diff --git a/src/gui/painting/qcolor.h b/src/gui/painting/qcolor.h
index 06c218365b..b0192662cc 100644
--- a/src/gui/painting/qcolor.h
+++ b/src/gui/painting/qcolor.h
@@ -37,6 +37,7 @@
#include <QtGui/qrgb.h>
#include <QtCore/qnamespace.h>
#include <QtCore/qstringlist.h>
+#include <QtGui/qrgba64.h>
QT_BEGIN_NAMESPACE
@@ -63,11 +64,23 @@ public:
QColor(Qt::GlobalColor color);
QColor(int r, int g, int b, int a = 255);
QColor(QRgb rgb);
+ QColor(QRgba64 rgba64);
QColor(const QString& name);
QColor(const char *name);
- QColor(const QColor &color); // ### Qt 6: remove, the trivial one is fine.
QColor(Spec spec);
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
+ QColor(const QColor &color); // ### Qt 6: remove all of these, the trivial ones are fine.
+# ifdef Q_COMPILER_RVALUE_REFS
+ QColor(QColor &&other) Q_DECL_NOTHROW : cspec(other.cspec), ct(other.ct) {}
+ QColor &operator=(QColor &&other) Q_DECL_NOTHROW
+ { cspec = other.cspec; ct = other.ct; return *this; }
+# endif
+ QColor &operator=(const QColor &);
+#endif // Qt < 6
+
+ QColor &operator=(Qt::GlobalColor color);
+
bool isValid() const;
// ### Qt 6: merge overloads
@@ -100,15 +113,18 @@ public:
void setGreenF(qreal green);
void setBlueF(qreal blue);
- void getRgb(int *r, int *g, int *b, int *a = 0) const;
+ void getRgb(int *r, int *g, int *b, int *a = Q_NULLPTR) const;
void setRgb(int r, int g, int b, int a = 255);
- void getRgbF(qreal *r, qreal *g, qreal *b, qreal *a = 0) const;
+ void getRgbF(qreal *r, qreal *g, qreal *b, qreal *a = Q_NULLPTR) const;
void setRgbF(qreal r, qreal g, qreal b, qreal a = 1.0);
QRgb rgba() const;
void setRgba(QRgb rgba);
+ QRgba64 rgba64() const;
+ void setRgba64(QRgba64 rgba);
+
QRgb rgb() const;
void setRgb(QRgb rgb);
@@ -124,10 +140,10 @@ public:
qreal hsvSaturationF() const;
qreal valueF() const;
- void getHsv(int *h, int *s, int *v, int *a = 0) const;
+ void getHsv(int *h, int *s, int *v, int *a = Q_NULLPTR) const;
void setHsv(int h, int s, int v, int a = 255);
- void getHsvF(qreal *h, qreal *s, qreal *v, qreal *a = 0) const;
+ void getHsvF(qreal *h, qreal *s, qreal *v, qreal *a = Q_NULLPTR) const;
void setHsvF(qreal h, qreal s, qreal v, qreal a = 1.0);
int cyan() const;
@@ -140,10 +156,10 @@ public:
qreal yellowF() const;
qreal blackF() const;
- void getCmyk(int *c, int *m, int *y, int *k, int *a = 0);
+ void getCmyk(int *c, int *m, int *y, int *k, int *a = Q_NULLPTR);
void setCmyk(int c, int m, int y, int k, int a = 255);
- void getCmykF(qreal *c, qreal *m, qreal *y, qreal *k, qreal *a = 0);
+ void getCmykF(qreal *c, qreal *m, qreal *y, qreal *k, qreal *a = Q_NULLPTR);
void setCmykF(qreal c, qreal m, qreal y, qreal k, qreal a = 1.0);
int hslHue() const; // 0 <= hue < 360
@@ -154,10 +170,10 @@ public:
qreal hslSaturationF() const;
qreal lightnessF() const;
- void getHsl(int *h, int *s, int *l, int *a = 0) const;
+ void getHsl(int *h, int *s, int *l, int *a = Q_NULLPTR) const;
void setHsl(int h, int s, int l, int a = 255);
- void getHslF(qreal *h, qreal *s, qreal *l, qreal *a = 0) const;
+ void getHslF(qreal *h, qreal *s, qreal *l, qreal *a = Q_NULLPTR) const;
void setHslF(qreal h, qreal s, qreal l, qreal a = 1.0);
QColor toRgb() const;
@@ -173,6 +189,9 @@ public:
static QColor fromRgb(int r, int g, int b, int a = 255);
static QColor fromRgbF(qreal r, qreal g, qreal b, qreal a = 1.0);
+ static QColor fromRgba64(ushort r, ushort g, ushort b, ushort a = USHRT_MAX);
+ static QColor fromRgba64(QRgba64 rgba);
+
static QColor fromHsv(int h, int s, int v, int a = 255);
static QColor fromHsvF(qreal h, qreal s, qreal v, qreal a = 1.0);
@@ -187,9 +206,6 @@ public:
QColor dark(int f = 200) const Q_REQUIRED_RESULT;
QColor darker(int f = 200) const Q_REQUIRED_RESULT;
- QColor &operator=(const QColor &);
- QColor &operator=(Qt::GlobalColor color);
-
bool operator==(const QColor &c) const;
bool operator!=(const QColor &c) const;
@@ -254,9 +270,11 @@ inline QColor::QColor(const char *aname)
inline QColor::QColor(const QString& aname)
{ setNamedColor(aname); }
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
inline QColor::QColor(const QColor &acolor)
: cspec(acolor.cspec)
{ ct.argb = acolor.ct.argb; }
+#endif
inline bool QColor::isValid() const
{ return cspec != Invalid; }
diff --git a/src/gui/painting/qcompositionfunctions.cpp b/src/gui/painting/qcompositionfunctions.cpp
new file mode 100644
index 0000000000..ba428a7938
--- /dev/null
+++ b/src/gui/painting/qcompositionfunctions.cpp
@@ -0,0 +1,2197 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qglobal.h>
+#include <private/qdrawhelper_p.h>
+#include <private/qrgba64_p.h>
+
+QT_BEGIN_NAMESPACE
+
+# define PRELOAD_INIT(x)
+# define PRELOAD_INIT2(x,y)
+# define PRELOAD_COND(x)
+# define PRELOAD_COND2(x,y)
+
+/* The constant alpha factor describes an alpha factor that gets applied
+ to the result of the composition operation combining it with the destination.
+
+ The intent is that if const_alpha == 0. we get back dest, and if const_alpha == 1.
+ we get the unmodified operation
+
+ result = src op dest
+ dest = result * const_alpha + dest * (1. - const_alpha)
+
+ This means that in the comments below, the first line is the const_alpha==255 case, the
+ second line the general one.
+
+ In the lines below:
+ s == src, sa == alpha(src), sia = 1 - alpha(src)
+ d == dest, da == alpha(dest), dia = 1 - alpha(dest)
+ ca = const_alpha, cia = 1 - const_alpha
+
+ The methods exist in two variants. One where we have a constant source, the other
+ where the source is an array of pixels.
+*/
+
+/*
+ result = 0
+ d = d * cia
+*/
+#define comp_func_Clear_impl(dest, length, const_alpha)\
+{\
+ if (const_alpha == 255) {\
+ QT_MEMFILL_UINT(dest, length, 0);\
+ } else {\
+ int ialpha = 255 - const_alpha;\
+ PRELOAD_INIT(dest)\
+ for (int i = 0; i < length; ++i) {\
+ PRELOAD_COND(dest)\
+ dest[i] = BYTE_MUL(dest[i], ialpha);\
+ }\
+ }\
+}
+
+void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha)
+{
+ comp_func_Clear_impl(dest, length, const_alpha);
+}
+
+void QT_FASTCALL comp_func_solid_Clear_rgb64(QRgba64 *dest, int length, QRgba64, uint const_alpha)
+{
+ if (const_alpha == 255)
+ qt_memfill64((quint64*)dest, 0, length);
+ else {
+ int ialpha = 255 - const_alpha;
+ for (int i = 0; i < length; ++i) {
+ dest[i] = multiplyAlpha255(dest[i], ialpha);
+ }
+ }
+}
+
+void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha)
+{
+ comp_func_Clear_impl(dest, length, const_alpha);
+}
+
+void QT_FASTCALL comp_func_Clear_rgb64(QRgba64 *dest, const QRgba64 *, int length, uint const_alpha)
+{
+ if (const_alpha == 255)
+ qt_memfill64((quint64*)dest, 0, length);
+ else {
+ int ialpha = 255 - const_alpha;
+ for (int i = 0; i < length; ++i) {
+ dest[i] = multiplyAlpha255(dest[i], ialpha);
+ }
+ }
+}
+
+/*
+ result = s
+ dest = s * ca + d * cia
+*/
+void QT_FASTCALL comp_func_solid_Source(uint *dest, int length, uint color, uint const_alpha)
+{
+ if (const_alpha == 255) {
+ QT_MEMFILL_UINT(dest, length, color);
+ } else {
+ int ialpha = 255 - const_alpha;
+ color = BYTE_MUL(color, const_alpha);
+ PRELOAD_INIT(dest)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND(dest)
+ dest[i] = color + BYTE_MUL(dest[i], ialpha);
+ }
+ }
+}
+
+void QT_FASTCALL comp_func_solid_Source_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+{
+ if (const_alpha == 255)
+ qt_memfill64((quint64*)dest, color, length);
+ else {
+ int ialpha = 255 - const_alpha;
+ color = multiplyAlpha255(color, const_alpha);
+ for (int i = 0; i < length; ++i) {
+ dest[i] = color + multiplyAlpha255(dest[i], ialpha);
+ }
+ }
+}
+
+void QT_FASTCALL comp_func_Source(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ if (const_alpha == 255) {
+ ::memcpy(dest, src, length * sizeof(uint));
+ } else {
+ int ialpha = 255 - const_alpha;
+ PRELOAD_INIT2(dest, src)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ dest[i] = INTERPOLATE_PIXEL_255(src[i], const_alpha, dest[i], ialpha);
+ }
+ }
+}
+
+void QT_FASTCALL comp_func_Source_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ if (const_alpha == 255)
+ ::memcpy(dest, src, length * sizeof(quint64));
+ else {
+ int ialpha = 255 - const_alpha;
+ for (int i = 0; i < length; ++i) {
+ dest[i] = interpolate255(src[i], const_alpha, dest[i], ialpha);
+ }
+ }
+}
+
+void QT_FASTCALL comp_func_solid_Destination(uint *, int, uint, uint)
+{
+}
+
+void QT_FASTCALL comp_func_solid_Destination_rgb64(QRgba64 *, int, QRgba64, uint)
+{
+}
+
+void QT_FASTCALL comp_func_Destination(uint *, const uint *, int, uint)
+{
+}
+
+void QT_FASTCALL comp_func_Destination_rgb64(QRgba64 *, const QRgba64 *, int, uint)
+{
+}
+
+/*
+ result = s + d * sia
+ dest = (s + d * sia) * ca + d * cia
+ = s * ca + d * (sia * ca + cia)
+ = s * ca + d * (1 - sa*ca)
+*/
+void QT_FASTCALL comp_func_solid_SourceOver(uint *dest, int length, uint color, uint const_alpha)
+{
+ if ((const_alpha & qAlpha(color)) == 255) {
+ QT_MEMFILL_UINT(dest, length, color);
+ } else {
+ if (const_alpha != 255)
+ color = BYTE_MUL(color, const_alpha);
+ PRELOAD_INIT(dest)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND(dest)
+ dest[i] = color + BYTE_MUL(dest[i], qAlpha(~color));
+ }
+ }
+}
+
+void QT_FASTCALL comp_func_solid_SourceOver_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+{
+ if (const_alpha == 255 && color.isOpaque()) {
+ qt_memfill64((quint64*)dest, color, length);
+ } else {
+ if (const_alpha != 255)
+ color = multiplyAlpha255(color, const_alpha);
+ for (int i = 0; i < length; ++i) {
+ dest[i] = color + multiplyAlpha65535(dest[i], 65535 - color.alpha());
+ }
+ }
+}
+
+void QT_FASTCALL comp_func_SourceOver(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ PRELOAD_INIT2(dest, src)
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint s = src[i];
+ if (s >= 0xff000000)
+ dest[i] = s;
+ else if (s != 0)
+ dest[i] = s + BYTE_MUL(dest[i], qAlpha(~s));
+ }
+ } else {
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint s = BYTE_MUL(src[i], const_alpha);
+ dest[i] = s + BYTE_MUL(dest[i], qAlpha(~s));
+ }
+ }
+}
+
+void QT_FASTCALL comp_func_SourceOver_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ QRgba64 s = src[i];
+ if (s.isOpaque())
+ dest[i] = s;
+ else if (!s.isTransparent())
+ dest[i] = s + multiplyAlpha65535(dest[i], 65535 - s.alpha());
+ }
+ } else {
+ for (int i = 0; i < length; ++i) {
+ QRgba64 s = multiplyAlpha255(src[i], const_alpha);
+ dest[i] = s + multiplyAlpha65535(dest[i], 65535 - s.alpha());
+ }
+ }
+}
+
+/*
+ result = d + s * dia
+ dest = (d + s * dia) * ca + d * cia
+ = d + s * dia * ca
+*/
+void QT_FASTCALL comp_func_solid_DestinationOver(uint *dest, int length, uint color, uint const_alpha)
+{
+ if (const_alpha != 255)
+ color = BYTE_MUL(color, const_alpha);
+ PRELOAD_INIT(dest)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND(dest)
+ uint d = dest[i];
+ dest[i] = d + BYTE_MUL(color, qAlpha(~d));
+ }
+}
+
+void QT_FASTCALL comp_func_solid_DestinationOver_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+{
+ if (const_alpha != 255)
+ color = multiplyAlpha255(color, const_alpha);
+ for (int i = 0; i < length; ++i) {
+ QRgba64 d = dest[i];
+ dest[i] = d + multiplyAlpha65535(color, 65535 - d.alpha());
+ }
+}
+
+void QT_FASTCALL comp_func_DestinationOver(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ PRELOAD_INIT2(dest, src)
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint d = dest[i];
+ dest[i] = d + BYTE_MUL(src[i], qAlpha(~d));
+ }
+ } else {
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint d = dest[i];
+ uint s = BYTE_MUL(src[i], const_alpha);
+ dest[i] = d + BYTE_MUL(s, qAlpha(~d));
+ }
+ }
+}
+
+void QT_FASTCALL comp_func_DestinationOver_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ QRgba64 d = dest[i];
+ dest[i] = d + multiplyAlpha65535(src[i], 65535 - d.alpha());
+ }
+ } else {
+ for (int i = 0; i < length; ++i) {
+ QRgba64 d = dest[i];
+ QRgba64 s = multiplyAlpha255(src[i], const_alpha);
+ dest[i] = d + multiplyAlpha65535(s, 65535 - d.alpha());
+ }
+ }
+}
+
+/*
+ result = s * da
+ dest = s * da * ca + d * cia
+*/
+void QT_FASTCALL comp_func_solid_SourceIn(uint *dest, int length, uint color, uint const_alpha)
+{
+ PRELOAD_INIT(dest)
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND(dest)
+ dest[i] = BYTE_MUL(color, qAlpha(dest[i]));
+ }
+ } else {
+ color = BYTE_MUL(color, const_alpha);
+ uint cia = 255 - const_alpha;
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND(dest)
+ uint d = dest[i];
+ dest[i] = INTERPOLATE_PIXEL_255(color, qAlpha(d), d, cia);
+ }
+ }
+}
+
+void QT_FASTCALL comp_func_solid_SourceIn_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+{
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ dest[i] = multiplyAlpha65535(color, dest[i].alpha());
+ }
+ } else {
+ uint ca = const_alpha * 257;
+ uint cia = 65535 - ca;
+ color = multiplyAlpha65535(color, ca);
+ for (int i = 0; i < length; ++i) {
+ QRgba64 d = dest[i];
+ dest[i] = interpolate65535(color, d.alpha(), d, cia);
+ }
+ }
+}
+
+void QT_FASTCALL comp_func_SourceIn(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ PRELOAD_INIT2(dest, src)
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ dest[i] = BYTE_MUL(src[i], qAlpha(dest[i]));
+ }
+ } else {
+ uint cia = 255 - const_alpha;
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint d = dest[i];
+ uint s = BYTE_MUL(src[i], const_alpha);
+ dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(d), d, cia);
+ }
+ }
+}
+
+void QT_FASTCALL comp_func_SourceIn_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ dest[i] = multiplyAlpha65535(src[i], dest[i].alpha());
+ }
+ } else {
+ uint ca = const_alpha * 257;
+ uint cia = 65535 - ca;
+ for (int i = 0; i < length; ++i) {
+ QRgba64 d = dest[i];
+ QRgba64 s = multiplyAlpha65535(src[i], ca);
+ dest[i] = interpolate65535(s, d.alpha(), d, cia);
+ }
+ }
+}
+
+/*
+ result = d * sa
+ dest = d * sa * ca + d * cia
+ = d * (sa * ca + cia)
+*/
+void QT_FASTCALL comp_func_solid_DestinationIn(uint *dest, int length, uint color, uint const_alpha)
+{
+ uint a = qAlpha(color);
+ if (const_alpha != 255) {
+ a = BYTE_MUL(a, const_alpha) + 255 - const_alpha;
+ }
+ PRELOAD_INIT(dest)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND(dest)
+ dest[i] = BYTE_MUL(dest[i], a);
+ }
+}
+
+void QT_FASTCALL comp_func_solid_DestinationIn_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+{
+ uint a = color.alpha();
+ uint ca64k = const_alpha * 257;
+ if (const_alpha != 255)
+ a = qt_div_65535(a * ca64k) + 65535 - ca64k;
+ for (int i = 0; i < length; ++i) {
+ dest[i] = multiplyAlpha65535(dest[i], a);
+ }
+}
+
+void QT_FASTCALL comp_func_DestinationIn(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ PRELOAD_INIT2(dest, src)
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ dest[i] = BYTE_MUL(dest[i], qAlpha(src[i]));
+ }
+ } else {
+ int cia = 255 - const_alpha;
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint a = BYTE_MUL(qAlpha(src[i]), const_alpha) + cia;
+ dest[i] = BYTE_MUL(dest[i], a);
+ }
+ }
+}
+
+void QT_FASTCALL comp_func_DestinationIn_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ dest[i] = multiplyAlpha65535(dest[i], src[i].alpha());
+ }
+ } else {
+ uint ca = const_alpha * 257;
+ uint cia = 65535 - ca;
+ for (int i = 0; i < length; ++i) {
+ uint a = qt_div_65535(src[i].alpha() * ca) + cia;
+ dest[i] = multiplyAlpha65535(dest[i], a);
+ }
+ }
+}
+
+/*
+ result = s * dia
+ dest = s * dia * ca + d * cia
+*/
+
+void QT_FASTCALL comp_func_solid_SourceOut(uint *dest, int length, uint color, uint const_alpha)
+{
+ PRELOAD_INIT(dest)
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND(dest)
+ dest[i] = BYTE_MUL(color, qAlpha(~dest[i]));
+ }
+ } else {
+ color = BYTE_MUL(color, const_alpha);
+ int cia = 255 - const_alpha;
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND(dest)
+ uint d = dest[i];
+ dest[i] = INTERPOLATE_PIXEL_255(color, qAlpha(~d), d, cia);
+ }
+ }
+}
+
+void QT_FASTCALL comp_func_solid_SourceOut_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+{
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ dest[i] = multiplyAlpha65535(color, 65535 - dest[i].alpha());
+ }
+ } else {
+ uint ca = const_alpha * 257;
+ uint cia = 65535 - ca;
+ color = multiplyAlpha65535(color, ca);
+ for (int i = 0; i < length; ++i) {
+ QRgba64 d = dest[i];
+ dest[i] = interpolate65535(color, 65535 - d.alpha(), d, cia);
+ }
+ }
+}
+
+void QT_FASTCALL comp_func_SourceOut(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ PRELOAD_INIT2(dest, src)
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ dest[i] = BYTE_MUL(src[i], qAlpha(~dest[i]));
+ }
+ } else {
+ int cia = 255 - const_alpha;
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint s = BYTE_MUL(src[i], const_alpha);
+ uint d = dest[i];
+ dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(~d), d, cia);
+ }
+ }
+}
+
+void QT_FASTCALL comp_func_SourceOut_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ dest[i] = multiplyAlpha65535(src[i], 65535 - dest[i].alpha());
+ }
+ } else {
+ uint ca = const_alpha * 257;
+ uint cia = 65535 - ca;
+ for (int i = 0; i < length; ++i) {
+ QRgba64 d = dest[i];
+ QRgba64 s = multiplyAlpha65535(src[i], ca);
+ dest[i] = interpolate65535(s, 65535 - d.alpha(), d, cia);
+ }
+ }
+}
+
+/*
+ result = d * sia
+ dest = d * sia * ca + d * cia
+ = d * (sia * ca + cia)
+*/
+void QT_FASTCALL comp_func_solid_DestinationOut(uint *dest, int length, uint color, uint const_alpha)
+{
+ uint a = qAlpha(~color);
+ if (const_alpha != 255)
+ a = BYTE_MUL(a, const_alpha) + 255 - const_alpha;
+ PRELOAD_INIT(dest)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND(dest)
+ dest[i] = BYTE_MUL(dest[i], a);
+ }
+}
+
+void QT_FASTCALL comp_func_solid_DestinationOut_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+{
+ uint a = 65535 - color.alpha();
+ uint ca64k = const_alpha * 257;
+ if (const_alpha != 255)
+ a = qt_div_65535(a * ca64k) + 65535 - ca64k;
+ for (int i = 0; i < length; ++i) {
+ dest[i] = multiplyAlpha65535(dest[i], a);
+ }
+}
+
+void QT_FASTCALL comp_func_DestinationOut(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ PRELOAD_INIT2(dest, src)
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ dest[i] = BYTE_MUL(dest[i], qAlpha(~src[i]));
+ }
+ } else {
+ int cia = 255 - const_alpha;
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint sia = BYTE_MUL(qAlpha(~src[i]), const_alpha) + cia;
+ dest[i] = BYTE_MUL(dest[i], sia);
+ }
+ }
+}
+
+void QT_FASTCALL comp_func_DestinationOut_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ dest[i] = multiplyAlpha65535(dest[i], 65535 - src[i].alpha());
+ }
+ } else {
+ uint ca = const_alpha * 257;
+ uint cia = 65535 - ca;
+ for (int i = 0; i < length; ++i) {
+ uint a = qt_div_65535((65535 - src[i].alpha()) * ca) + cia;
+ dest[i] = multiplyAlpha65535(dest[i], a);
+ }
+ }
+}
+
+/*
+ result = s*da + d*sia
+ dest = s*da*ca + d*sia*ca + d *cia
+ = s*ca * da + d * (sia*ca + cia)
+ = s*ca * da + d * (1 - sa*ca)
+*/
+void QT_FASTCALL comp_func_solid_SourceAtop(uint *dest, int length, uint color, uint const_alpha)
+{
+ if (const_alpha != 255) {
+ color = BYTE_MUL(color, const_alpha);
+ }
+ uint sia = qAlpha(~color);
+ PRELOAD_INIT(dest)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND(dest)
+ dest[i] = INTERPOLATE_PIXEL_255(color, qAlpha(dest[i]), dest[i], sia);
+ }
+}
+
+void QT_FASTCALL comp_func_solid_SourceAtop_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+{
+ if (const_alpha != 255)
+ color = multiplyAlpha255(color, const_alpha);
+ uint sia = 65535 - color.alpha();
+ for (int i = 0; i < length; ++i) {
+ dest[i] = interpolate65535(color, dest[i].alpha(), dest[i], sia);
+ }
+}
+
+void QT_FASTCALL comp_func_SourceAtop(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ PRELOAD_INIT2(dest, src)
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint s = src[i];
+ uint d = dest[i];
+ dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(d), d, qAlpha(~s));
+ }
+ } else {
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint s = BYTE_MUL(src[i], const_alpha);
+ uint d = dest[i];
+ dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(d), d, qAlpha(~s));
+ }
+ }
+}
+
+void QT_FASTCALL comp_func_SourceAtop_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ QRgba64 s = src[i];
+ QRgba64 d = dest[i];
+ dest[i] = interpolate65535(s, d.alpha(), d, 65535 - s.alpha());
+ }
+ } else {
+ for (int i = 0; i < length; ++i) {
+ QRgba64 s = multiplyAlpha255(src[i], const_alpha);
+ QRgba64 d = dest[i];
+ dest[i] = interpolate65535(s, d.alpha(), d, 65535 - s.alpha());
+ }
+ }
+}
+
+/*
+ result = d*sa + s*dia
+ dest = d*sa*ca + s*dia*ca + d *cia
+ = s*ca * dia + d * (sa*ca + cia)
+*/
+void QT_FASTCALL comp_func_solid_DestinationAtop(uint *dest, int length, uint color, uint const_alpha)
+{
+ uint a = qAlpha(color);
+ if (const_alpha != 255) {
+ color = BYTE_MUL(color, const_alpha);
+ a = qAlpha(color) + 255 - const_alpha;
+ }
+ PRELOAD_INIT(dest)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND(dest)
+ uint d = dest[i];
+ dest[i] = INTERPOLATE_PIXEL_255(d, a, color, qAlpha(~d));
+ }
+}
+
+void QT_FASTCALL comp_func_solid_DestinationAtop_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+{
+ uint a = color.alpha();
+ if (const_alpha != 255) {
+ color = multiplyAlpha255(color, const_alpha);
+ a = color.alpha() + 65535 - (const_alpha * 257);
+ }
+ for (int i = 0; i < length; ++i) {
+ QRgba64 d = dest[i];
+ dest[i] = interpolate65535(d, a, color, 65535 - d.alpha());
+ }
+}
+
+void QT_FASTCALL comp_func_DestinationAtop(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ PRELOAD_INIT2(dest, src)
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint s = src[i];
+ uint d = dest[i];
+ dest[i] = INTERPOLATE_PIXEL_255(d, qAlpha(s), s, qAlpha(~d));
+ }
+ } else {
+ int cia = 255 - const_alpha;
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint s = BYTE_MUL(src[i], const_alpha);
+ uint d = dest[i];
+ uint a = qAlpha(s) + cia;
+ dest[i] = INTERPOLATE_PIXEL_255(d, a, s, qAlpha(~d));
+ }
+ }
+}
+
+void QT_FASTCALL comp_func_DestinationAtop_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ QRgba64 s = src[i];
+ QRgba64 d = dest[i];
+ dest[i] = interpolate65535(d, s.alpha(), s, 65535 - d.alpha());
+ }
+ } else {
+ int ca = const_alpha * 257;
+ int cia = 65535 - ca;
+ for (int i = 0; i < length; ++i) {
+ QRgba64 s = multiplyAlpha65535(src[i], ca);
+ QRgba64 d = dest[i];
+ uint a = s.alpha() + cia;
+ dest[i] = interpolate65535(d, a, s, 65535 - d.alpha());
+ }
+ }
+}
+
+/*
+ result = d*sia + s*dia
+ dest = d*sia*ca + s*dia*ca + d *cia
+ = s*ca * dia + d * (sia*ca + cia)
+ = s*ca * dia + d * (1 - sa*ca)
+*/
+void QT_FASTCALL comp_func_solid_XOR(uint *dest, int length, uint color, uint const_alpha)
+{
+ if (const_alpha != 255)
+ color = BYTE_MUL(color, const_alpha);
+ uint sia = qAlpha(~color);
+
+ PRELOAD_INIT(dest)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND(dest)
+ uint d = dest[i];
+ dest[i] = INTERPOLATE_PIXEL_255(color, qAlpha(~d), d, sia);
+ }
+}
+
+void QT_FASTCALL comp_func_solid_XOR_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+{
+ if (const_alpha != 255)
+ color = multiplyAlpha255(color, const_alpha);
+ uint sia = 65535 - color.alpha();
+ for (int i = 0; i < length; ++i) {
+ QRgba64 d = dest[i];
+ dest[i] = interpolate65535(color, 65535 - d.alpha(), d, sia);
+ }
+}
+
+void QT_FASTCALL comp_func_XOR(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ PRELOAD_INIT2(dest, src)
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint d = dest[i];
+ uint s = src[i];
+ dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(~d), d, qAlpha(~s));
+ }
+ } else {
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint d = dest[i];
+ uint s = BYTE_MUL(src[i], const_alpha);
+ dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(~d), d, qAlpha(~s));
+ }
+ }
+}
+
+void QT_FASTCALL comp_func_XOR_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ QRgba64 d = dest[i];
+ QRgba64 s = src[i];
+ dest[i] = interpolate65535(s, 65535 - d.alpha(), d, 65535 - s.alpha());
+ }
+ } else {
+ for (int i = 0; i < length; ++i) {
+ QRgba64 d = dest[i];
+ QRgba64 s = multiplyAlpha255(src[i], const_alpha);
+ dest[i] = interpolate65535(s, 65535 - d.alpha(), d, 65535 - s.alpha());
+ }
+ }
+}
+
+struct QFullCoverage {
+ inline void store(uint *dest, const uint src) const
+ {
+ *dest = src;
+ }
+};
+
+struct QPartialCoverage {
+ inline QPartialCoverage(uint const_alpha)
+ : ca(const_alpha)
+ , ica(255 - const_alpha)
+ {
+ }
+
+ inline void store(uint *dest, const uint src) const
+ {
+ *dest = INTERPOLATE_PIXEL_255(src, ca, *dest, ica);
+ }
+
+private:
+ const uint ca;
+ const uint ica;
+};
+
+static inline int mix_alpha(int da, int sa)
+{
+ return 255 - ((255 - sa) * (255 - da) >> 8);
+}
+
+/*
+ Dca' = Sca.Da + Dca.Sa + Sca.(1 - Da) + Dca.(1 - Sa)
+ = Sca + Dca
+*/
+template <typename T>
+Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Plus_impl(uint *dest, int length, uint color, const T &coverage)
+{
+ uint s = color;
+
+ PRELOAD_INIT(dest)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND(dest)
+ uint d = dest[i];
+ d = comp_func_Plus_one_pixel(d, s);
+ coverage.store(&dest[i], d);
+ }
+}
+
+template <typename T>
+Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Plus_impl_rgb64(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
+{
+ QRgba64 s = color;
+ for (int i = 0; i < length; ++i) {
+ QRgba64 d = dest[i];
+ d = comp_func_Plus_one_pixel(d, s);
+ coverage.store(&dest[i], d);
+ }
+}
+
+void QT_FASTCALL comp_func_solid_Plus(uint *dest, int length, uint color, uint const_alpha)
+{
+ if (const_alpha == 255)
+ comp_func_solid_Plus_impl(dest, length, color, QFullCoverage());
+ else
+ comp_func_solid_Plus_impl(dest, length, color, QPartialCoverage(const_alpha));
+}
+
+void QT_FASTCALL comp_func_solid_Plus_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+{
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ dest[i] = addWithSaturation(dest[i], color);
+ }
+ } else {
+ for (int i = 0; i < length; ++i) {
+ QRgba64 d = addWithSaturation(dest[i], color);
+ dest[i] = interpolate255(d, const_alpha, dest[i], 255 - const_alpha);
+ }
+ }
+}
+
+template <typename T>
+Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Plus_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
+{
+ PRELOAD_INIT2(dest, src)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint d = dest[i];
+ uint s = src[i];
+
+ d = comp_func_Plus_one_pixel(d, s);
+
+ coverage.store(&dest[i], d);
+ }
+}
+
+void QT_FASTCALL comp_func_Plus(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ if (const_alpha == 255)
+ comp_func_Plus_impl(dest, src, length, QFullCoverage());
+ else
+ comp_func_Plus_impl(dest, src, length, QPartialCoverage(const_alpha));
+}
+
+void QT_FASTCALL comp_func_Plus_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ dest[i] = addWithSaturation(dest[i], src[i]);
+ }
+ } else {
+ for (int i = 0; i < length; ++i) {
+ QRgba64 d = addWithSaturation(dest[i], src[i]);
+ dest[i] = interpolate255(d, const_alpha, dest[i], 255 - const_alpha);
+ }
+ }
+}
+
+/*
+ Dca' = Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa)
+*/
+static inline int multiply_op(int dst, int src, int da, int sa)
+{
+ return qt_div_255(src * dst + src * (255 - da) + dst * (255 - sa));
+}
+
+template <typename T>
+Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Multiply_impl(uint *dest, int length, uint color, const T &coverage)
+{
+ int sa = qAlpha(color);
+ int sr = qRed(color);
+ int sg = qGreen(color);
+ int sb = qBlue(color);
+
+ PRELOAD_INIT(dest)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND(dest)
+ uint d = dest[i];
+ int da = qAlpha(d);
+
+#define OP(a, b) multiply_op(a, b, da, sa)
+ int r = OP( qRed(d), sr);
+ int b = OP( qBlue(d), sb);
+ int g = OP(qGreen(d), sg);
+ int a = mix_alpha(da, sa);
+#undef OP
+
+ coverage.store(&dest[i], qRgba(r, g, b, a));
+ }
+}
+
+void QT_FASTCALL comp_func_solid_Multiply(uint *dest, int length, uint color, uint const_alpha)
+{
+ if (const_alpha == 255)
+ comp_func_solid_Multiply_impl(dest, length, color, QFullCoverage());
+ else
+ comp_func_solid_Multiply_impl(dest, length, color, QPartialCoverage(const_alpha));
+}
+
+template <typename T>
+Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Multiply_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
+{
+ PRELOAD_INIT2(dest, src)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint d = dest[i];
+ uint s = src[i];
+
+ int da = qAlpha(d);
+ int sa = qAlpha(s);
+
+#define OP(a, b) multiply_op(a, b, da, sa)
+ int r = OP( qRed(d), qRed(s));
+ int b = OP( qBlue(d), qBlue(s));
+ int g = OP(qGreen(d), qGreen(s));
+ int a = mix_alpha(da, sa);
+#undef OP
+
+ coverage.store(&dest[i], qRgba(r, g, b, a));
+ }
+}
+
+void QT_FASTCALL comp_func_Multiply(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ if (const_alpha == 255)
+ comp_func_Multiply_impl(dest, src, length, QFullCoverage());
+ else
+ comp_func_Multiply_impl(dest, src, length, QPartialCoverage(const_alpha));
+}
+
+/*
+ Dca' = (Sca.Da + Dca.Sa - Sca.Dca) + Sca.(1 - Da) + Dca.(1 - Sa)
+ = Sca + Dca - Sca.Dca
+*/
+template <typename T>
+Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Screen_impl(uint *dest, int length, uint color, const T &coverage)
+{
+ int sa = qAlpha(color);
+ int sr = qRed(color);
+ int sg = qGreen(color);
+ int sb = qBlue(color);
+
+ PRELOAD_INIT(dest)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND(dest)
+ uint d = dest[i];
+ int da = qAlpha(d);
+
+#define OP(a, b) 255 - qt_div_255((255-a) * (255-b))
+ int r = OP( qRed(d), sr);
+ int b = OP( qBlue(d), sb);
+ int g = OP(qGreen(d), sg);
+ int a = mix_alpha(da, sa);
+#undef OP
+
+ coverage.store(&dest[i], qRgba(r, g, b, a));
+ }
+}
+
+void QT_FASTCALL comp_func_solid_Screen(uint *dest, int length, uint color, uint const_alpha)
+{
+ if (const_alpha == 255)
+ comp_func_solid_Screen_impl(dest, length, color, QFullCoverage());
+ else
+ comp_func_solid_Screen_impl(dest, length, color, QPartialCoverage(const_alpha));
+}
+
+template <typename T>
+Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Screen_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
+{
+ PRELOAD_INIT2(dest, src)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint d = dest[i];
+ uint s = src[i];
+
+ int da = qAlpha(d);
+ int sa = qAlpha(s);
+
+#define OP(a, b) 255 - (((255-a) * (255-b)) >> 8)
+ int r = OP( qRed(d), qRed(s));
+ int b = OP( qBlue(d), qBlue(s));
+ int g = OP(qGreen(d), qGreen(s));
+ int a = mix_alpha(da, sa);
+#undef OP
+
+ coverage.store(&dest[i], qRgba(r, g, b, a));
+ }
+}
+
+void QT_FASTCALL comp_func_Screen(uint *dest, const uint *src, int length, uint const_alpha)
+{
+ if (const_alpha == 255)
+ comp_func_Screen_impl(dest, src, length, QFullCoverage());
+ else
+ comp_func_Screen_impl(dest, src, length, QPartialCoverage(const_alpha));
+}
+
+/*
+ if 2.Dca < Da
+ Dca' = 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa)
+ otherwise
+ Dca' = Sa.Da - 2.(Da - Dca).(Sa - Sca) + Sca.(1 - Da) + Dca.(1 - Sa)
+*/
+static inline int overlay_op(int dst, int src, int da, int sa)
+{
+ const int temp = src * (255 - da) + dst * (255 - sa);
+ if (2 * dst < da)
+ return qt_div_255(2 * src * dst + temp);
+ else
+ return qt_div_255(sa * da - 2 * (da - dst) * (sa - src) + temp);
+}
+
+template <typename T>
+Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Overlay_impl(uint *dest, int length, uint color, const T &coverage)
+{
+ int sa = qAlpha(color);
+ int sr = qRed(color);
+ int sg = qGreen(color);
+ int sb = qBlue(color);
+
+ PRELOAD_INIT(dest)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND(dest)
+ uint d = dest[i];
+ int da = qAlpha(d);
+
+#define OP(a, b) overlay_op(a, b, da, sa)
+ int r = OP( qRed(d), sr);
+ int b = OP( qBlue(d), sb);
+ int g = OP(qGreen(d), sg);
+ int a = mix_alpha(da, sa);
+#undef OP
+
+ coverage.store(&dest[i], qRgba(r, g, b, a));
+ }
+}
+
+void QT_FASTCALL comp_func_solid_Overlay(uint *dest, int length, uint color, uint const_alpha)
+{
+ if (const_alpha == 255)
+ comp_func_solid_Overlay_impl(dest, length, color, QFullCoverage());
+ else
+ comp_func_solid_Overlay_impl(dest, length, color, QPartialCoverage(const_alpha));
+}
+
+template <typename T>
+Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Overlay_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
+{
+ PRELOAD_INIT2(dest, src)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint d = dest[i];
+ uint s = src[i];
+
+ int da = qAlpha(d);
+ int sa = qAlpha(s);
+
+#define OP(a, b) overlay_op(a, b, da, sa)
+ int r = OP( qRed(d), qRed(s));
+ int b = OP( qBlue(d), qBlue(s));
+ int g = OP(qGreen(d), qGreen(s));
+ int a = mix_alpha(da, sa);
+#undef OP
+
+ coverage.store(&dest[i], qRgba(r, g, b, a));
+ }
+}
+
+void QT_FASTCALL comp_func_Overlay(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ if (const_alpha == 255)
+ comp_func_Overlay_impl(dest, src, length, QFullCoverage());
+ else
+ comp_func_Overlay_impl(dest, src, length, QPartialCoverage(const_alpha));
+}
+
+/*
+ Dca' = min(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa)
+ Da' = Sa + Da - Sa.Da
+*/
+static inline int darken_op(int dst, int src, int da, int sa)
+{
+ return qt_div_255(qMin(src * da, dst * sa) + src * (255 - da) + dst * (255 - sa));
+}
+
+template <typename T>
+Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Darken_impl(uint *dest, int length, uint color, const T &coverage)
+{
+ int sa = qAlpha(color);
+ int sr = qRed(color);
+ int sg = qGreen(color);
+ int sb = qBlue(color);
+
+ PRELOAD_INIT(dest)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND(dest)
+ uint d = dest[i];
+ int da = qAlpha(d);
+
+#define OP(a, b) darken_op(a, b, da, sa)
+ int r = OP( qRed(d), sr);
+ int b = OP( qBlue(d), sb);
+ int g = OP(qGreen(d), sg);
+ int a = mix_alpha(da, sa);
+#undef OP
+
+ coverage.store(&dest[i], qRgba(r, g, b, a));
+ }
+}
+
+void QT_FASTCALL comp_func_solid_Darken(uint *dest, int length, uint color, uint const_alpha)
+{
+ if (const_alpha == 255)
+ comp_func_solid_Darken_impl(dest, length, color, QFullCoverage());
+ else
+ comp_func_solid_Darken_impl(dest, length, color, QPartialCoverage(const_alpha));
+}
+
+template <typename T>
+Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Darken_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
+{
+ PRELOAD_INIT2(dest, src)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint d = dest[i];
+ uint s = src[i];
+
+ int da = qAlpha(d);
+ int sa = qAlpha(s);
+
+#define OP(a, b) darken_op(a, b, da, sa)
+ int r = OP( qRed(d), qRed(s));
+ int b = OP( qBlue(d), qBlue(s));
+ int g = OP(qGreen(d), qGreen(s));
+ int a = mix_alpha(da, sa);
+#undef OP
+
+ coverage.store(&dest[i], qRgba(r, g, b, a));
+ }
+}
+
+void QT_FASTCALL comp_func_Darken(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ if (const_alpha == 255)
+ comp_func_Darken_impl(dest, src, length, QFullCoverage());
+ else
+ comp_func_Darken_impl(dest, src, length, QPartialCoverage(const_alpha));
+}
+
+/*
+ Dca' = max(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa)
+ Da' = Sa + Da - Sa.Da
+*/
+static inline int lighten_op(int dst, int src, int da, int sa)
+{
+ return qt_div_255(qMax(src * da, dst * sa) + src * (255 - da) + dst * (255 - sa));
+}
+
+template <typename T>
+Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Lighten_impl(uint *dest, int length, uint color, const T &coverage)
+{
+ int sa = qAlpha(color);
+ int sr = qRed(color);
+ int sg = qGreen(color);
+ int sb = qBlue(color);
+
+ PRELOAD_INIT(dest)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND(dest)
+ uint d = dest[i];
+ int da = qAlpha(d);
+
+#define OP(a, b) lighten_op(a, b, da, sa)
+ int r = OP( qRed(d), sr);
+ int b = OP( qBlue(d), sb);
+ int g = OP(qGreen(d), sg);
+ int a = mix_alpha(da, sa);
+#undef OP
+
+ coverage.store(&dest[i], qRgba(r, g, b, a));
+ }
+}
+
+void QT_FASTCALL comp_func_solid_Lighten(uint *dest, int length, uint color, uint const_alpha)
+{
+ if (const_alpha == 255)
+ comp_func_solid_Lighten_impl(dest, length, color, QFullCoverage());
+ else
+ comp_func_solid_Lighten_impl(dest, length, color, QPartialCoverage(const_alpha));
+}
+
+template <typename T>
+Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Lighten_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
+{
+ PRELOAD_INIT2(dest, src)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint d = dest[i];
+ uint s = src[i];
+
+ int da = qAlpha(d);
+ int sa = qAlpha(s);
+
+#define OP(a, b) lighten_op(a, b, da, sa)
+ int r = OP( qRed(d), qRed(s));
+ int b = OP( qBlue(d), qBlue(s));
+ int g = OP(qGreen(d), qGreen(s));
+ int a = mix_alpha(da, sa);
+#undef OP
+
+ coverage.store(&dest[i], qRgba(r, g, b, a));
+ }
+}
+
+void QT_FASTCALL comp_func_Lighten(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ if (const_alpha == 255)
+ comp_func_Lighten_impl(dest, src, length, QFullCoverage());
+ else
+ comp_func_Lighten_impl(dest, src, length, QPartialCoverage(const_alpha));
+}
+
+/*
+ if Sca.Da + Dca.Sa >= Sa.Da
+ Dca' = Sa.Da + Sca.(1 - Da) + Dca.(1 - Sa)
+ otherwise
+ Dca' = Dca.Sa/(1-Sca/Sa) + Sca.(1 - Da) + Dca.(1 - Sa)
+*/
+static inline int color_dodge_op(int dst, int src, int da, int sa)
+{
+ const int sa_da = sa * da;
+ const int dst_sa = dst * sa;
+ const int src_da = src * da;
+
+ const int temp = src * (255 - da) + dst * (255 - sa);
+ if (src_da + dst_sa >= sa_da)
+ return qt_div_255(sa_da + temp);
+ else
+ return qt_div_255(255 * dst_sa / (255 - 255 * src / sa) + temp);
+}
+
+template <typename T>
+Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_ColorDodge_impl(uint *dest, int length, uint color, const T &coverage)
+{
+ int sa = qAlpha(color);
+ int sr = qRed(color);
+ int sg = qGreen(color);
+ int sb = qBlue(color);
+
+ PRELOAD_INIT(dest)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND(dest)
+ uint d = dest[i];
+ int da = qAlpha(d);
+
+#define OP(a,b) color_dodge_op(a, b, da, sa)
+ int r = OP( qRed(d), sr);
+ int b = OP( qBlue(d), sb);
+ int g = OP(qGreen(d), sg);
+ int a = mix_alpha(da, sa);
+#undef OP
+
+ coverage.store(&dest[i], qRgba(r, g, b, a));
+ }
+}
+
+void QT_FASTCALL comp_func_solid_ColorDodge(uint *dest, int length, uint color, uint const_alpha)
+{
+ if (const_alpha == 255)
+ comp_func_solid_ColorDodge_impl(dest, length, color, QFullCoverage());
+ else
+ comp_func_solid_ColorDodge_impl(dest, length, color, QPartialCoverage(const_alpha));
+}
+
+template <typename T>
+Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorDodge_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
+{
+ PRELOAD_INIT2(dest, src)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint d = dest[i];
+ uint s = src[i];
+
+ int da = qAlpha(d);
+ int sa = qAlpha(s);
+
+#define OP(a, b) color_dodge_op(a, b, da, sa)
+ int r = OP( qRed(d), qRed(s));
+ int b = OP( qBlue(d), qBlue(s));
+ int g = OP(qGreen(d), qGreen(s));
+ int a = mix_alpha(da, sa);
+#undef OP
+
+ coverage.store(&dest[i], qRgba(r, g, b, a));
+ }
+}
+
+void QT_FASTCALL comp_func_ColorDodge(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ if (const_alpha == 255)
+ comp_func_ColorDodge_impl(dest, src, length, QFullCoverage());
+ else
+ comp_func_ColorDodge_impl(dest, src, length, QPartialCoverage(const_alpha));
+}
+
+/*
+ if Sca.Da + Dca.Sa <= Sa.Da
+ Dca' = Sca.(1 - Da) + Dca.(1 - Sa)
+ otherwise
+ Dca' = Sa.(Sca.Da + Dca.Sa - Sa.Da)/Sca + Sca.(1 - Da) + Dca.(1 - Sa)
+*/
+static inline int color_burn_op(int dst, int src, int da, int sa)
+{
+ const int src_da = src * da;
+ const int dst_sa = dst * sa;
+ const int sa_da = sa * da;
+
+ const int temp = src * (255 - da) + dst * (255 - sa);
+
+ if (src == 0 || src_da + dst_sa <= sa_da)
+ return qt_div_255(temp);
+ return qt_div_255(sa * (src_da + dst_sa - sa_da) / src + temp);
+}
+
+template <typename T>
+Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_ColorBurn_impl(uint *dest, int length, uint color, const T &coverage)
+{
+ int sa = qAlpha(color);
+ int sr = qRed(color);
+ int sg = qGreen(color);
+ int sb = qBlue(color);
+
+ PRELOAD_INIT(dest)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND(dest)
+ uint d = dest[i];
+ int da = qAlpha(d);
+
+#define OP(a, b) color_burn_op(a, b, da, sa)
+ int r = OP( qRed(d), sr);
+ int b = OP( qBlue(d), sb);
+ int g = OP(qGreen(d), sg);
+ int a = mix_alpha(da, sa);
+#undef OP
+
+ coverage.store(&dest[i], qRgba(r, g, b, a));
+ }
+}
+
+void QT_FASTCALL comp_func_solid_ColorBurn(uint *dest, int length, uint color, uint const_alpha)
+{
+ if (const_alpha == 255)
+ comp_func_solid_ColorBurn_impl(dest, length, color, QFullCoverage());
+ else
+ comp_func_solid_ColorBurn_impl(dest, length, color, QPartialCoverage(const_alpha));
+}
+
+template <typename T>
+Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorBurn_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
+{
+ PRELOAD_INIT2(dest, src)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint d = dest[i];
+ uint s = src[i];
+
+ int da = qAlpha(d);
+ int sa = qAlpha(s);
+
+#define OP(a, b) color_burn_op(a, b, da, sa)
+ int r = OP( qRed(d), qRed(s));
+ int b = OP( qBlue(d), qBlue(s));
+ int g = OP(qGreen(d), qGreen(s));
+ int a = mix_alpha(da, sa);
+#undef OP
+
+ coverage.store(&dest[i], qRgba(r, g, b, a));
+ }
+}
+
+void QT_FASTCALL comp_func_ColorBurn(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ if (const_alpha == 255)
+ comp_func_ColorBurn_impl(dest, src, length, QFullCoverage());
+ else
+ comp_func_ColorBurn_impl(dest, src, length, QPartialCoverage(const_alpha));
+}
+
+/*
+ if 2.Sca < Sa
+ Dca' = 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa)
+ otherwise
+ Dca' = Sa.Da - 2.(Da - Dca).(Sa - Sca) + Sca.(1 - Da) + Dca.(1 - Sa)
+*/
+static inline uint hardlight_op(int dst, int src, int da, int sa)
+{
+ const uint temp = src * (255 - da) + dst * (255 - sa);
+
+ if (2 * src < sa)
+ return qt_div_255(2 * src * dst + temp);
+ else
+ return qt_div_255(sa * da - 2 * (da - dst) * (sa - src) + temp);
+}
+
+template <typename T>
+Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_HardLight_impl(uint *dest, int length, uint color, const T &coverage)
+{
+ int sa = qAlpha(color);
+ int sr = qRed(color);
+ int sg = qGreen(color);
+ int sb = qBlue(color);
+
+ PRELOAD_INIT(dest)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND(dest)
+ uint d = dest[i];
+ int da = qAlpha(d);
+
+#define OP(a, b) hardlight_op(a, b, da, sa)
+ int r = OP( qRed(d), sr);
+ int b = OP( qBlue(d), sb);
+ int g = OP(qGreen(d), sg);
+ int a = mix_alpha(da, sa);
+#undef OP
+
+ coverage.store(&dest[i], qRgba(r, g, b, a));
+ }
+}
+
+void QT_FASTCALL comp_func_solid_HardLight(uint *dest, int length, uint color, uint const_alpha)
+{
+ if (const_alpha == 255)
+ comp_func_solid_HardLight_impl(dest, length, color, QFullCoverage());
+ else
+ comp_func_solid_HardLight_impl(dest, length, color, QPartialCoverage(const_alpha));
+}
+
+template <typename T>
+Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_HardLight_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
+{
+ PRELOAD_INIT2(dest, src)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint d = dest[i];
+ uint s = src[i];
+
+ int da = qAlpha(d);
+ int sa = qAlpha(s);
+
+#define OP(a, b) hardlight_op(a, b, da, sa)
+ int r = OP( qRed(d), qRed(s));
+ int b = OP( qBlue(d), qBlue(s));
+ int g = OP(qGreen(d), qGreen(s));
+ int a = mix_alpha(da, sa);
+#undef OP
+
+ coverage.store(&dest[i], qRgba(r, g, b, a));
+ }
+}
+
+void QT_FASTCALL comp_func_HardLight(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ if (const_alpha == 255)
+ comp_func_HardLight_impl(dest, src, length, QFullCoverage());
+ else
+ comp_func_HardLight_impl(dest, src, length, QPartialCoverage(const_alpha));
+}
+
+/*
+ if 2.Sca <= Sa
+ Dca' = Dca.(Sa + (2.Sca - Sa).(1 - Dca/Da)) + Sca.(1 - Da) + Dca.(1 - Sa)
+ otherwise if 2.Sca > Sa and 4.Dca <= Da
+ Dca' = Dca.Sa + Da.(2.Sca - Sa).(4.Dca/Da.(4.Dca/Da + 1).(Dca/Da - 1) + 7.Dca/Da) + Sca.(1 - Da) + Dca.(1 - Sa)
+ otherwise if 2.Sca > Sa and 4.Dca > Da
+ Dca' = Dca.Sa + Da.(2.Sca - Sa).((Dca/Da)^0.5 - Dca/Da) + Sca.(1 - Da) + Dca.(1 - Sa)
+*/
+static inline int soft_light_op(int dst, int src, int da, int sa)
+{
+ const int src2 = src << 1;
+ const int dst_np = da != 0 ? (255 * dst) / da : 0;
+ const int temp = (src * (255 - da) + dst * (255 - sa)) * 255;
+
+ if (src2 < sa)
+ return (dst * (sa * 255 + (src2 - sa) * (255 - dst_np)) + temp) / 65025;
+ else if (4 * dst <= da)
+ return (dst * sa * 255 + da * (src2 - sa) * ((((16 * dst_np - 12 * 255) * dst_np + 3 * 65025) * dst_np) / 65025) + temp) / 65025;
+ else {
+ return (dst * sa * 255 + da * (src2 - sa) * (int(qSqrt(qreal(dst_np * 255))) - dst_np) + temp) / 65025;
+ }
+}
+
+template <typename T>
+Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_SoftLight_impl(uint *dest, int length, uint color, const T &coverage)
+{
+ int sa = qAlpha(color);
+ int sr = qRed(color);
+ int sg = qGreen(color);
+ int sb = qBlue(color);
+
+ PRELOAD_INIT(dest)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND(dest)
+ uint d = dest[i];
+ int da = qAlpha(d);
+
+#define OP(a, b) soft_light_op(a, b, da, sa)
+ int r = OP( qRed(d), sr);
+ int b = OP( qBlue(d), sb);
+ int g = OP(qGreen(d), sg);
+ int a = mix_alpha(da, sa);
+#undef OP
+
+ coverage.store(&dest[i], qRgba(r, g, b, a));
+ }
+}
+
+void QT_FASTCALL comp_func_solid_SoftLight(uint *dest, int length, uint color, uint const_alpha)
+{
+ if (const_alpha == 255)
+ comp_func_solid_SoftLight_impl(dest, length, color, QFullCoverage());
+ else
+ comp_func_solid_SoftLight_impl(dest, length, color, QPartialCoverage(const_alpha));
+}
+
+template <typename T>
+Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_SoftLight_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
+{
+ PRELOAD_INIT2(dest, src)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint d = dest[i];
+ uint s = src[i];
+
+ int da = qAlpha(d);
+ int sa = qAlpha(s);
+
+#define OP(a, b) soft_light_op(a, b, da, sa)
+ int r = OP( qRed(d), qRed(s));
+ int b = OP( qBlue(d), qBlue(s));
+ int g = OP(qGreen(d), qGreen(s));
+ int a = mix_alpha(da, sa);
+#undef OP
+
+ coverage.store(&dest[i], qRgba(r, g, b, a));
+ }
+}
+
+void QT_FASTCALL comp_func_SoftLight(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ if (const_alpha == 255)
+ comp_func_SoftLight_impl(dest, src, length, QFullCoverage());
+ else
+ comp_func_SoftLight_impl(dest, src, length, QPartialCoverage(const_alpha));
+}
+
+/*
+ Dca' = abs(Dca.Sa - Sca.Da) + Sca.(1 - Da) + Dca.(1 - Sa)
+ = Sca + Dca - 2.min(Sca.Da, Dca.Sa)
+*/
+static inline int difference_op(int dst, int src, int da, int sa)
+{
+ return src + dst - qt_div_255(2 * qMin(src * da, dst * sa));
+}
+
+template <typename T>
+Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Difference_impl(uint *dest, int length, uint color, const T &coverage)
+{
+ int sa = qAlpha(color);
+ int sr = qRed(color);
+ int sg = qGreen(color);
+ int sb = qBlue(color);
+
+ PRELOAD_INIT(dest)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND(dest)
+ uint d = dest[i];
+ int da = qAlpha(d);
+
+#define OP(a, b) difference_op(a, b, da, sa)
+ int r = OP( qRed(d), sr);
+ int b = OP( qBlue(d), sb);
+ int g = OP(qGreen(d), sg);
+ int a = mix_alpha(da, sa);
+#undef OP
+
+ coverage.store(&dest[i], qRgba(r, g, b, a));
+ }
+}
+
+void QT_FASTCALL comp_func_solid_Difference(uint *dest, int length, uint color, uint const_alpha)
+{
+ if (const_alpha == 255)
+ comp_func_solid_Difference_impl(dest, length, color, QFullCoverage());
+ else
+ comp_func_solid_Difference_impl(dest, length, color, QPartialCoverage(const_alpha));
+}
+
+template <typename T>
+Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Difference_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
+{
+ PRELOAD_INIT2(dest, src)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint d = dest[i];
+ uint s = src[i];
+
+ int da = qAlpha(d);
+ int sa = qAlpha(s);
+
+#define OP(a, b) difference_op(a, b, da, sa)
+ int r = OP( qRed(d), qRed(s));
+ int b = OP( qBlue(d), qBlue(s));
+ int g = OP(qGreen(d), qGreen(s));
+ int a = mix_alpha(da, sa);
+#undef OP
+
+ coverage.store(&dest[i], qRgba(r, g, b, a));
+ }
+}
+
+void QT_FASTCALL comp_func_Difference(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ if (const_alpha == 255)
+ comp_func_Difference_impl(dest, src, length, QFullCoverage());
+ else
+ comp_func_Difference_impl(dest, src, length, QPartialCoverage(const_alpha));
+}
+
+/*
+ Dca' = (Sca.Da + Dca.Sa - 2.Sca.Dca) + Sca.(1 - Da) + Dca.(1 - Sa)
+*/
+template <typename T>
+Q_STATIC_TEMPLATE_FUNCTION inline void QT_FASTCALL comp_func_solid_Exclusion_impl(uint *dest, int length, uint color, const T &coverage)
+{
+ int sa = qAlpha(color);
+ int sr = qRed(color);
+ int sg = qGreen(color);
+ int sb = qBlue(color);
+
+ PRELOAD_INIT(dest)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND(dest)
+ uint d = dest[i];
+ int da = qAlpha(d);
+
+#define OP(a, b) (a + b - qt_div_255(2*(a*b)))
+ int r = OP( qRed(d), sr);
+ int b = OP( qBlue(d), sb);
+ int g = OP(qGreen(d), sg);
+ int a = mix_alpha(da, sa);
+#undef OP
+
+ coverage.store(&dest[i], qRgba(r, g, b, a));
+ }
+}
+
+void QT_FASTCALL comp_func_solid_Exclusion(uint *dest, int length, uint color, uint const_alpha)
+{
+ if (const_alpha == 255)
+ comp_func_solid_Exclusion_impl(dest, length, color, QFullCoverage());
+ else
+ comp_func_solid_Exclusion_impl(dest, length, color, QPartialCoverage(const_alpha));
+}
+
+template <typename T>
+Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Exclusion_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
+{
+ PRELOAD_INIT2(dest, src)
+ for (int i = 0; i < length; ++i) {
+ PRELOAD_COND2(dest, src)
+ uint d = dest[i];
+ uint s = src[i];
+
+ int da = qAlpha(d);
+ int sa = qAlpha(s);
+
+#define OP(a, b) (a + b - ((a*b) >> 7))
+ int r = OP( qRed(d), qRed(s));
+ int b = OP( qBlue(d), qBlue(s));
+ int g = OP(qGreen(d), qGreen(s));
+ int a = mix_alpha(da, sa);
+#undef OP
+
+ coverage.store(&dest[i], qRgba(r, g, b, a));
+ }
+}
+
+void QT_FASTCALL comp_func_Exclusion(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ if (const_alpha == 255)
+ comp_func_Exclusion_impl(dest, src, length, QFullCoverage());
+ else
+ comp_func_Exclusion_impl(dest, src, length, QPartialCoverage(const_alpha));
+}
+
+void QT_FASTCALL rasterop_solid_SourceOrDestination(uint *dest,
+ int length,
+ uint color,
+ uint const_alpha)
+{
+ Q_UNUSED(const_alpha);
+ while (length--)
+ *dest++ |= color;
+}
+
+void QT_FASTCALL rasterop_SourceOrDestination(uint *Q_DECL_RESTRICT dest,
+ const uint *Q_DECL_RESTRICT src,
+ int length,
+ uint const_alpha)
+{
+ Q_UNUSED(const_alpha);
+ while (length--)
+ *dest++ |= *src++;
+}
+
+void QT_FASTCALL rasterop_solid_SourceAndDestination(uint *dest,
+ int length,
+ uint color,
+ uint const_alpha)
+{
+ Q_UNUSED(const_alpha);
+ color |= 0xff000000;
+ while (length--)
+ *dest++ &= color;
+}
+
+void QT_FASTCALL rasterop_SourceAndDestination(uint *Q_DECL_RESTRICT dest,
+ const uint *Q_DECL_RESTRICT src,
+ int length,
+ uint const_alpha)
+{
+ Q_UNUSED(const_alpha);
+ while (length--) {
+ *dest = (*src & *dest) | 0xff000000;
+ ++dest; ++src;
+ }
+}
+
+void QT_FASTCALL rasterop_solid_SourceXorDestination(uint *dest,
+ int length,
+ uint color,
+ uint const_alpha)
+{
+ Q_UNUSED(const_alpha);
+ color &= 0x00ffffff;
+ while (length--)
+ *dest++ ^= color;
+}
+
+void QT_FASTCALL rasterop_SourceXorDestination(uint *Q_DECL_RESTRICT dest,
+ const uint *Q_DECL_RESTRICT src,
+ int length,
+ uint const_alpha)
+{
+ Q_UNUSED(const_alpha);
+ while (length--) {
+ *dest = (*src ^ *dest) | 0xff000000;
+ ++dest; ++src;
+ }
+}
+
+void QT_FASTCALL rasterop_solid_NotSourceAndNotDestination(uint *dest,
+ int length,
+ uint color,
+ uint const_alpha)
+{
+ Q_UNUSED(const_alpha);
+ color = ~color;
+ while (length--) {
+ *dest = (color & ~(*dest)) | 0xff000000;
+ ++dest;
+ }
+}
+
+void QT_FASTCALL rasterop_NotSourceAndNotDestination(uint *Q_DECL_RESTRICT dest,
+ const uint *Q_DECL_RESTRICT src,
+ int length,
+ uint const_alpha)
+{
+ Q_UNUSED(const_alpha);
+ while (length--) {
+ *dest = (~(*src) & ~(*dest)) | 0xff000000;
+ ++dest; ++src;
+ }
+}
+
+void QT_FASTCALL rasterop_solid_NotSourceOrNotDestination(uint *dest,
+ int length,
+ uint color,
+ uint const_alpha)
+{
+ Q_UNUSED(const_alpha);
+ color = ~color | 0xff000000;
+ while (length--) {
+ *dest = color | ~(*dest);
+ ++dest;
+ }
+}
+
+void QT_FASTCALL rasterop_NotSourceOrNotDestination(uint *Q_DECL_RESTRICT dest,
+ const uint *Q_DECL_RESTRICT src,
+ int length,
+ uint const_alpha)
+{
+ Q_UNUSED(const_alpha);
+ while (length--) {
+ *dest = ~(*src) | ~(*dest) | 0xff000000;
+ ++dest; ++src;
+ }
+}
+
+void QT_FASTCALL rasterop_solid_NotSourceXorDestination(uint *dest,
+ int length,
+ uint color,
+ uint const_alpha)
+{
+ Q_UNUSED(const_alpha);
+ color = ~color & 0x00ffffff;
+ while (length--) {
+ *dest = color ^ (*dest);
+ ++dest;
+ }
+}
+
+void QT_FASTCALL rasterop_NotSourceXorDestination(uint *Q_DECL_RESTRICT dest,
+ const uint *Q_DECL_RESTRICT src,
+ int length,
+ uint const_alpha)
+{
+ Q_UNUSED(const_alpha);
+ while (length--) {
+ *dest = ((~(*src)) ^ (*dest)) | 0xff000000;
+ ++dest; ++src;
+ }
+}
+
+void QT_FASTCALL rasterop_solid_NotSource(uint *dest, int length,
+ uint color, uint const_alpha)
+{
+ Q_UNUSED(const_alpha);
+ qt_memfill(dest, ~color | 0xff000000, length);
+}
+
+void QT_FASTCALL rasterop_NotSource(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src,
+ int length, uint const_alpha)
+{
+ Q_UNUSED(const_alpha);
+ while (length--)
+ *dest++ = ~(*src++) | 0xff000000;
+}
+
+void QT_FASTCALL rasterop_solid_NotSourceAndDestination(uint *dest,
+ int length,
+ uint color,
+ uint const_alpha)
+{
+ Q_UNUSED(const_alpha);
+ color = ~color | 0xff000000;
+ while (length--) {
+ *dest = color & *dest;
+ ++dest;
+ }
+}
+
+void QT_FASTCALL rasterop_NotSourceAndDestination(uint *Q_DECL_RESTRICT dest,
+ const uint *Q_DECL_RESTRICT src,
+ int length,
+ uint const_alpha)
+{
+ Q_UNUSED(const_alpha);
+ while (length--) {
+ *dest = (~(*src) & *dest) | 0xff000000;
+ ++dest; ++src;
+ }
+}
+
+void QT_FASTCALL rasterop_solid_SourceAndNotDestination(uint *dest,
+ int length,
+ uint color,
+ uint const_alpha)
+{
+ Q_UNUSED(const_alpha);
+ while (length--) {
+ *dest = (color & ~(*dest)) | 0xff000000;
+ ++dest;
+ }
+}
+
+void QT_FASTCALL rasterop_SourceAndNotDestination(uint *Q_DECL_RESTRICT dest,
+ const uint *Q_DECL_RESTRICT src,
+ int length,
+ uint const_alpha)
+{
+ Q_UNUSED(const_alpha);
+ while (length--) {
+ *dest = (*src & ~(*dest)) | 0xff000000;
+ ++dest; ++src;
+ }
+}
+
+void QT_FASTCALL rasterop_NotSourceOrDestination(uint *Q_DECL_RESTRICT dest,
+ const uint *Q_DECL_RESTRICT src,
+ int length,
+ uint const_alpha)
+{
+ Q_UNUSED(const_alpha);
+ while (length--) {
+ *dest = (~(*src) | *dest) | 0xff000000;
+ ++dest; ++src;
+ }
+}
+
+void QT_FASTCALL rasterop_solid_NotSourceOrDestination(uint *Q_DECL_RESTRICT dest,
+ int length,
+ uint color,
+ uint const_alpha)
+{
+ Q_UNUSED(const_alpha);
+ color = ~color | 0xff000000;
+ while (length--)
+ *dest++ |= color;
+}
+
+void QT_FASTCALL rasterop_SourceOrNotDestination(uint *Q_DECL_RESTRICT dest,
+ const uint *Q_DECL_RESTRICT src,
+ int length,
+ uint const_alpha)
+{
+ Q_UNUSED(const_alpha);
+ while (length--) {
+ *dest = (*src | ~(*dest)) | 0xff000000;
+ ++dest; ++src;
+ }
+}
+
+void QT_FASTCALL rasterop_solid_SourceOrNotDestination(uint *Q_DECL_RESTRICT dest,
+ int length,
+ uint color,
+ uint const_alpha)
+{
+ Q_UNUSED(const_alpha);
+ while (length--) {
+ *dest = (color | ~(*dest)) | 0xff000000;
+ ++dest;
+ }
+}
+
+void QT_FASTCALL rasterop_ClearDestination(uint *Q_DECL_RESTRICT dest,
+ const uint *Q_DECL_RESTRICT src,
+ int length,
+ uint const_alpha)
+{
+ Q_UNUSED(src);
+ comp_func_solid_SourceOver (dest, length, 0xff000000, const_alpha);
+}
+
+void QT_FASTCALL rasterop_solid_ClearDestination(uint *Q_DECL_RESTRICT dest,
+ int length,
+ uint color,
+ uint const_alpha)
+{
+ Q_UNUSED(color);
+ comp_func_solid_SourceOver (dest, length, 0xff000000, const_alpha);
+}
+
+void QT_FASTCALL rasterop_SetDestination(uint *Q_DECL_RESTRICT dest,
+ const uint *Q_DECL_RESTRICT src,
+ int length,
+ uint const_alpha)
+{
+ Q_UNUSED(src);
+ comp_func_solid_SourceOver (dest, length, 0xffffffff, const_alpha);
+}
+
+void QT_FASTCALL rasterop_solid_SetDestination(uint *Q_DECL_RESTRICT dest,
+ int length,
+ uint color,
+ uint const_alpha)
+{
+ Q_UNUSED(color);
+ comp_func_solid_SourceOver (dest, length, 0xffffffff, const_alpha);
+}
+
+void QT_FASTCALL rasterop_NotDestination(uint *Q_DECL_RESTRICT dest,
+ const uint *Q_DECL_RESTRICT src,
+ int length,
+ uint const_alpha)
+{
+ Q_UNUSED(src);
+ rasterop_solid_SourceXorDestination (dest, length, 0x00ffffff, const_alpha);
+}
+
+void QT_FASTCALL rasterop_solid_NotDestination(uint *Q_DECL_RESTRICT dest,
+ int length,
+ uint color,
+ uint const_alpha)
+{
+ Q_UNUSED(color);
+ rasterop_solid_SourceXorDestination (dest, length, 0x00ffffff, const_alpha);
+}
+
+CompositionFunctionSolid qt_functionForModeSolid_C[] = {
+ comp_func_solid_SourceOver,
+ comp_func_solid_DestinationOver,
+ comp_func_solid_Clear,
+ comp_func_solid_Source,
+ comp_func_solid_Destination,
+ comp_func_solid_SourceIn,
+ comp_func_solid_DestinationIn,
+ comp_func_solid_SourceOut,
+ comp_func_solid_DestinationOut,
+ comp_func_solid_SourceAtop,
+ comp_func_solid_DestinationAtop,
+ comp_func_solid_XOR,
+ comp_func_solid_Plus,
+ comp_func_solid_Multiply,
+ comp_func_solid_Screen,
+ comp_func_solid_Overlay,
+ comp_func_solid_Darken,
+ comp_func_solid_Lighten,
+ comp_func_solid_ColorDodge,
+ comp_func_solid_ColorBurn,
+ comp_func_solid_HardLight,
+ comp_func_solid_SoftLight,
+ comp_func_solid_Difference,
+ comp_func_solid_Exclusion,
+ rasterop_solid_SourceOrDestination,
+ rasterop_solid_SourceAndDestination,
+ rasterop_solid_SourceXorDestination,
+ rasterop_solid_NotSourceAndNotDestination,
+ rasterop_solid_NotSourceOrNotDestination,
+ rasterop_solid_NotSourceXorDestination,
+ rasterop_solid_NotSource,
+ rasterop_solid_NotSourceAndDestination,
+ rasterop_solid_SourceAndNotDestination,
+ rasterop_solid_NotSourceOrDestination,
+ rasterop_solid_SourceOrNotDestination,
+ rasterop_solid_ClearDestination,
+ rasterop_solid_SetDestination,
+ rasterop_solid_NotDestination
+};
+
+CompositionFunctionSolid64 qt_functionForModeSolid64_C[] = {
+ comp_func_solid_SourceOver_rgb64,
+ comp_func_solid_DestinationOver_rgb64,
+ comp_func_solid_Clear_rgb64,
+ comp_func_solid_Source_rgb64,
+ comp_func_solid_Destination_rgb64,
+ comp_func_solid_SourceIn_rgb64,
+ comp_func_solid_DestinationIn_rgb64,
+ comp_func_solid_SourceOut_rgb64,
+ comp_func_solid_DestinationOut_rgb64,
+ comp_func_solid_SourceAtop_rgb64,
+ comp_func_solid_DestinationAtop_rgb64,
+ comp_func_solid_XOR_rgb64,
+ comp_func_solid_Plus_rgb64,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+CompositionFunction qt_functionForMode_C[] = {
+ comp_func_SourceOver,
+ comp_func_DestinationOver,
+ comp_func_Clear,
+ comp_func_Source,
+ comp_func_Destination,
+ comp_func_SourceIn,
+ comp_func_DestinationIn,
+ comp_func_SourceOut,
+ comp_func_DestinationOut,
+ comp_func_SourceAtop,
+ comp_func_DestinationAtop,
+ comp_func_XOR,
+ comp_func_Plus,
+ comp_func_Multiply,
+ comp_func_Screen,
+ comp_func_Overlay,
+ comp_func_Darken,
+ comp_func_Lighten,
+ comp_func_ColorDodge,
+ comp_func_ColorBurn,
+ comp_func_HardLight,
+ comp_func_SoftLight,
+ comp_func_Difference,
+ comp_func_Exclusion,
+ rasterop_SourceOrDestination,
+ rasterop_SourceAndDestination,
+ rasterop_SourceXorDestination,
+ rasterop_NotSourceAndNotDestination,
+ rasterop_NotSourceOrNotDestination,
+ rasterop_NotSourceXorDestination,
+ rasterop_NotSource,
+ rasterop_NotSourceAndDestination,
+ rasterop_SourceAndNotDestination,
+ rasterop_NotSourceOrDestination,
+ rasterop_SourceOrNotDestination,
+ rasterop_ClearDestination,
+ rasterop_SetDestination,
+ rasterop_NotDestination
+};
+
+CompositionFunction64 qt_functionForMode64_C[] = {
+ comp_func_SourceOver_rgb64,
+ comp_func_DestinationOver_rgb64,
+ comp_func_Clear_rgb64,
+ comp_func_Source_rgb64,
+ comp_func_Destination_rgb64,
+ comp_func_SourceIn_rgb64,
+ comp_func_DestinationIn_rgb64,
+ comp_func_SourceOut_rgb64,
+ comp_func_DestinationOut_rgb64,
+ comp_func_SourceAtop_rgb64,
+ comp_func_DestinationAtop_rgb64,
+ comp_func_XOR_rgb64,
+ comp_func_Plus_rgb64,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+QT_END_NAMESPACE
diff --git a/src/gui/painting/qcosmeticstroker.cpp b/src/gui/painting/qcosmeticstroker.cpp
index e9fada10a5..8c3fd2ce4f 100644
--- a/src/gui/painting/qcosmeticstroker.cpp
+++ b/src/gui/painting/qcosmeticstroker.cpp
@@ -33,6 +33,7 @@
#include "qcosmeticstroker_p.h"
#include "private/qpainterpath_p.h"
+#include "private/qrgba64_p.h"
#include <qdebug.h>
QT_BEGIN_NAMESPACE
@@ -280,7 +281,7 @@ void QCosmeticStroker::setup()
drawCaps = state->lastPen.capStyle() != Qt::FlatCap;
if (strokeSelection & FastDraw) {
- color = INTERPOLATE_PIXEL_256(state->penData.solid.color, opacity, 0, 0);
+ color = multiplyAlpha256(state->penData.solid.color, opacity).toArgb32();
QRasterBuffer *buffer = state->penData.rasterBuffer;
pixels = (uint *)buffer->buffer();
ppl = buffer->bytesPerLine()>>2;
diff --git a/src/gui/painting/qdatabuffer_p.h b/src/gui/painting/qdatabuffer_p.h
index 0a4a3d5c9e..3fe39efdde 100644
--- a/src/gui/painting/qdatabuffer_p.h
+++ b/src/gui/painting/qdatabuffer_p.h
@@ -53,6 +53,7 @@ QT_BEGIN_NAMESPACE
template <typename Type> class QDataBuffer
{
+ Q_DISABLE_COPY(QDataBuffer);
public:
QDataBuffer(int res)
{
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index d74b48a3ca..87ceb9a89d 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -32,11 +32,6 @@
****************************************************************************/
#include <qglobal.h>
-#ifdef Q_OS_IOS
-// We don't build the NEON drawhelpers as they are implemented partly
-// in GAS syntax assembly, which is not supported by the iOS toolchain.
-#undef __ARM_NEON__
-#endif
#include <qstylehints.h>
#include <qguiapplication.h>
@@ -51,6 +46,7 @@
#include <private/qdrawhelper_mips_dsp_p.h>
#endif
#include <private/qguiapplication_p.h>
+#include <private/qrgba64_p.h>
#include <qmath.h>
QT_BEGIN_NAMESPACE
@@ -184,6 +180,36 @@ static const uint *QT_FASTCALL convertToRGB32(uint *buffer, const uint *src, int
}
template<QImage::Format Format>
+static const QRgba64 *QT_FASTCALL convertToRGB64(QRgba64 *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ Q_CONSTEXPR uint redMask = ((1 << redWidth<Format>()) - 1);
+ Q_CONSTEXPR uint greenMask = ((1 << greenWidth<Format>()) - 1);
+ Q_CONSTEXPR uint blueMask = ((1 << blueWidth<Format>()) - 1);
+
+ Q_CONSTEXPR uchar redLeftShift = 8 - redWidth<Format>();
+ Q_CONSTEXPR uchar greenLeftShift = 8 - greenWidth<Format>();
+ Q_CONSTEXPR uchar blueLeftShift = 8 - blueWidth<Format>();
+
+ Q_CONSTEXPR uchar redRightShift = 2 * redWidth<Format>() - 8;
+ Q_CONSTEXPR uchar greenRightShift = 2 * greenWidth<Format>() - 8;
+ Q_CONSTEXPR uchar blueRightShift = 2 * blueWidth<Format>() - 8;
+
+ for (int i = 0; i < count; ++i) {
+ uint red = (src[i] >> redShift<Format>()) & redMask;
+ uint green = (src[i] >> greenShift<Format>()) & greenMask;
+ uint blue = (src[i] >> blueShift<Format>()) & blueMask;
+
+ red = ((red << redLeftShift) | (red >> redRightShift)) << 16;
+ green = ((green << greenLeftShift) | (green >> greenRightShift)) << 8;
+ blue = (blue << blueLeftShift) | (blue >> blueRightShift);
+ buffer[i] = QRgba64::fromRgba(red, green, blue, 255);
+ }
+
+ return buffer;
+}
+
+template<QImage::Format Format>
static const uint *QT_FASTCALL convertARGBPMToARGB32PM(uint *buffer, const uint *src, int count,
const QPixelLayout *, const QRgb *)
{
@@ -219,6 +245,41 @@ static const uint *QT_FASTCALL convertARGBPMToARGB32PM(uint *buffer, const uint
}
template<QImage::Format Format>
+static const QRgba64 *QT_FASTCALL convertARGBPMToARGB64PM(QRgba64 *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ Q_CONSTEXPR uint alphaMask = ((1 << alphaWidth<Format>()) - 1);
+ Q_CONSTEXPR uint redMask = ((1 << redWidth<Format>()) - 1);
+ Q_CONSTEXPR uint greenMask = ((1 << greenWidth<Format>()) - 1);
+ Q_CONSTEXPR uint blueMask = ((1 << blueWidth<Format>()) - 1);
+
+ Q_CONSTEXPR uchar alphaLeftShift = 8 - alphaWidth<Format>();
+ Q_CONSTEXPR uchar redLeftShift = 8 - redWidth<Format>();
+ Q_CONSTEXPR uchar greenLeftShift = 8 - greenWidth<Format>();
+ Q_CONSTEXPR uchar blueLeftShift = 8 - blueWidth<Format>();
+
+ Q_CONSTEXPR uchar alphaRightShift = 2 * alphaWidth<Format>() - 8;
+ Q_CONSTEXPR uchar redRightShift = 2 * redWidth<Format>() - 8;
+ Q_CONSTEXPR uchar greenRightShift = 2 * greenWidth<Format>() - 8;
+ Q_CONSTEXPR uchar blueRightShift = 2 * blueWidth<Format>() - 8;
+
+ for (int i = 0; i < count; ++i) {
+ uint alpha = (src[i] >> alphaShift<Format>()) & alphaMask;
+ uint red = (src[i] >> redShift<Format>()) & redMask;
+ uint green = (src[i] >> greenShift<Format>()) & greenMask;
+ uint blue = (src[i] >> blueShift<Format>()) & blueMask;
+
+ alpha = (alpha << alphaLeftShift) | (alpha >> alphaRightShift);
+ red = qMin(alpha, (red << redLeftShift) | (red >> redRightShift));
+ green = qMin(alpha, (green << greenLeftShift) | (green >> greenRightShift));
+ blue = qMin(alpha, (blue << blueLeftShift) | (blue >> blueRightShift));
+ buffer[i] = QRgba64::fromRgba(red, green, blue, alpha);
+ }
+
+ return buffer;
+}
+
+template<QImage::Format Format>
static const uint *QT_FASTCALL convertRGBFromARGB32PM(uint *buffer, const uint *src, int count,
const QPixelLayout *, const QRgb *)
{
@@ -313,28 +374,30 @@ static const uint *QT_FASTCALL convertARGBPMFromARGB32PM(uint *buffer, const uin
template<QImage::Format Format> Q_DECL_CONSTEXPR static inline QPixelLayout pixelLayoutRGB()
{
return QPixelLayout{
- redWidth<Format>(), redShift<Format>(),
- greenWidth<Format>(), greenShift<Format>(),
- blueWidth<Format>(), blueShift<Format>(),
+ uchar(redWidth<Format>()), uchar(redShift<Format>()),
+ uchar(greenWidth<Format>()), uchar(greenShift<Format>()),
+ uchar(blueWidth<Format>()), uchar(blueShift<Format>()),
0, 0,
false, bitsPerPixel<Format>(),
convertToRGB32<Format>,
convertRGBFromARGB32PM<Format>,
- convertRGBFromRGB32<Format>
+ convertRGBFromRGB32<Format>,
+ convertToRGB64<Format>
};
}
template<QImage::Format Format> Q_DECL_CONSTEXPR static inline QPixelLayout pixelLayoutARGBPM()
{
return QPixelLayout{
- redWidth<Format>(), redShift<Format>(),
- greenWidth<Format>(), greenShift<Format>(),
- blueWidth<Format>(), blueShift<Format>(),
- alphaWidth<Format>(), alphaShift<Format>(),
+ uchar(redWidth<Format>()), uchar(redShift<Format>()),
+ uchar(greenWidth<Format>()), uchar(greenShift<Format>()),
+ uchar(blueWidth<Format>()), uchar(blueShift<Format>()),
+ uchar(alphaWidth<Format>()), uchar(alphaShift<Format>()),
true, bitsPerPixel<Format>(),
convertARGBPMToARGB32PM<Format>,
convertARGBPMFromARGB32PM<Format>,
- convertARGBPMFromRGB32<Format>
+ convertARGBPMFromRGB32<Format>,
+ convertARGBPMToARGB64PM<Format>
};
}
@@ -349,6 +412,14 @@ static const uint *QT_FASTCALL convertIndexedToARGB32PM(uint *buffer, const uint
return buffer;
}
+static const QRgba64 *QT_FASTCALL convertIndexedToARGB64PM(QRgba64 *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *clut)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = QRgba64::fromArgb32(clut[src[i]]).premultiplied();
+ return buffer;
+}
+
static const uint *QT_FASTCALL convertPassThrough(uint *, const uint *src, int,
const QPixelLayout *, const QRgb *)
{
@@ -391,6 +462,22 @@ static const uint *QT_FASTCALL convertGrayscale8ToRGB32(uint *buffer, const uint
return buffer;
}
+static const QRgba64 *QT_FASTCALL convertAlpha8ToRGB64(QRgba64 *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = QRgba64::fromRgba(0, 0, 0, src[i]);
+ return buffer;
+}
+
+static const QRgba64 *QT_FASTCALL convertGrayscale8ToRGB64(QRgba64 *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = QRgba64::fromRgba(src[i], src[i], src[i], 255);
+ return buffer;
+}
+
static const uint *QT_FASTCALL convertARGB32FromARGB32PM(uint *buffer, const uint *src, int count,
const QPixelLayout *, const QRgb *)
{
@@ -407,6 +494,113 @@ static const uint *QT_FASTCALL convertRGBA8888PMFromARGB32PM(uint *buffer, const
return buffer;
}
+#ifdef __SSE2__
+template<bool RGBA, bool maskAlpha>
+static inline void qConvertARGB32PMToARGB64PM_sse2(QRgba64 *buffer, const uint *src, int count)
+{
+ if (count <= 0)
+ return;
+
+ const __m128i amask = _mm_set1_epi32(0xff000000);
+ int i = 0;
+ for (; ((uintptr_t)buffer & 0xf) && i < count; ++i) {
+ uint s = *src++;
+ if (RGBA)
+ s = RGBA2ARGB(s);
+ *buffer++ = QRgba64::fromArgb32(s);
+ }
+ for (; i < count-3; i += 4) {
+ __m128i vs = _mm_loadu_si128((const __m128i*)src);
+ if (maskAlpha)
+ vs = _mm_or_si128(vs, amask);
+ src += 4;
+ __m128i v1 = _mm_unpacklo_epi8(vs, vs);
+ __m128i v2 = _mm_unpackhi_epi8(vs, vs);
+ if (!RGBA) {
+ v1 = _mm_shufflelo_epi16(v1, _MM_SHUFFLE(3, 0, 1, 2));
+ v2 = _mm_shufflelo_epi16(v2, _MM_SHUFFLE(3, 0, 1, 2));
+ v1 = _mm_shufflehi_epi16(v1, _MM_SHUFFLE(3, 0, 1, 2));
+ v2 = _mm_shufflehi_epi16(v2, _MM_SHUFFLE(3, 0, 1, 2));
+ }
+ _mm_store_si128((__m128i*)(buffer), v1);
+ buffer += 2;
+ _mm_store_si128((__m128i*)(buffer), v2);
+ buffer += 2;
+ }
+
+ for (; i < count; ++i) {
+ uint s = *src++;
+ if (RGBA)
+ s = RGBA2ARGB(s);
+ *buffer++ = QRgba64::fromArgb32(s);
+ }
+}
+#endif
+
+static const QRgba64 *QT_FASTCALL convertRGB32ToRGB64(QRgba64 *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+#ifdef __SSE2__
+ qConvertARGB32PMToARGB64PM_sse2<false, true>(buffer, src, count);
+#else
+ for (int i = 0; i < count; ++i)
+ buffer[i] = QRgba64::fromArgb32(0xff000000 | src[i]);
+#endif
+ return buffer;
+}
+
+static const QRgba64 *QT_FASTCALL convertARGB32ToARGB64PM(QRgba64 *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+#ifdef __SSE2__
+ qConvertARGB32PMToARGB64PM_sse2<false, false>(buffer, src, count);
+ for (int i = 0; i < count; ++i)
+ buffer[i] = buffer[i].premultiplied();
+#else
+ for (int i = 0; i < count; ++i)
+ buffer[i] = QRgba64::fromArgb32(src[i]).premultiplied();
+#endif
+ return buffer;
+}
+
+static const QRgba64 *QT_FASTCALL convertARGB32PMToARGB64PM(QRgba64 *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+#ifdef __SSE2__
+ qConvertARGB32PMToARGB64PM_sse2<false, false>(buffer, src, count);
+#else
+ for (int i = 0; i < count; ++i)
+ buffer[i] = QRgba64::fromArgb32(src[i]);
+#endif
+ return buffer;
+}
+
+static const QRgba64 *QT_FASTCALL convertRGBA8888ToARGB64PM(QRgba64 *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+#ifdef __SSE2__
+ qConvertARGB32PMToARGB64PM_sse2<true, false>(buffer, src, count);
+ for (int i = 0; i < count; ++i)
+ buffer[i] = buffer[i].premultiplied();
+#else
+ for (int i = 0; i < count; ++i)
+ buffer[i] = QRgba64::fromArgb32(RGBA2ARGB(src[i])).premultiplied();
+#endif
+ return buffer;
+}
+
+static const QRgba64 *QT_FASTCALL convertRGBA8888PMToARGB64PM(QRgba64 *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+#ifdef __SSE2__
+ qConvertARGB32PMToARGB64PM_sse2<true, false>(buffer, src, count);
+#else
+ for (int i = 0; i < count; ++i)
+ buffer[i] = QRgba64::fromArgb32(RGBA2ARGB(src[i]));
+#endif
+ return buffer;
+}
+
static const uint *QT_FASTCALL convertRGBA8888FromARGB32PM(uint *buffer, const uint *src, int count,
const QPixelLayout *, const QRgb *)
{
@@ -440,6 +634,63 @@ static const uint *QT_FASTCALL convertA2RGB30PMToARGB32PM(uint *buffer, const ui
return buffer;
}
+#ifdef __SSE2__
+template<QtPixelOrder PixelOrder>
+static inline void qConvertA2RGB30PMToARGB64PM_sse2(QRgba64 *buffer, const uint *src, int count)
+{
+ if (count <= 0)
+ return;
+
+ const __m128i rmask = _mm_set1_epi32(0x3ff00000);
+ const __m128i gmask = _mm_set1_epi32(0x000ffc00);
+ const __m128i bmask = _mm_set1_epi32(0x000003ff);
+ const __m128i afactor = _mm_set1_epi16(0x5555);
+ int i = 0;
+
+ for (; ((uintptr_t)buffer & 0xf) && i < count; ++i)
+ *buffer++ = qConvertA2rgb30ToRgb64<PixelOrder>(*src++);
+
+ for (; i < count-3; i += 4) {
+ __m128i vs = _mm_loadu_si128((const __m128i*)src);
+ src += 4;
+ __m128i va = _mm_srli_epi32(vs, 30);
+ __m128i vr = _mm_and_si128(vs, rmask);
+ __m128i vb = _mm_and_si128(vs, bmask);
+ __m128i vg = _mm_and_si128(vs, gmask);
+ va = _mm_mullo_epi16(va, afactor);
+ vr = _mm_or_si128(_mm_srli_epi32(vr, 14), _mm_srli_epi32(vr, 24));
+ vg = _mm_or_si128(_mm_srli_epi32(vg, 4), _mm_srli_epi32(vg, 14));
+ vb = _mm_or_si128(_mm_slli_epi32(vb, 6), _mm_srli_epi32(vb, 4));
+ __m128i vrb;
+ if (PixelOrder == PixelOrderRGB)
+ vrb = _mm_or_si128(vr, _mm_slli_si128(vb, 2));
+ else
+ vrb = _mm_or_si128(vb, _mm_slli_si128(vr, 2));
+ __m128i vga = _mm_or_si128(vg, _mm_slli_si128(va, 2));
+ _mm_store_si128((__m128i*)(buffer), _mm_unpacklo_epi16(vrb, vga));
+ buffer += 2;
+ _mm_store_si128((__m128i*)(buffer), _mm_unpackhi_epi16(vrb, vga));
+ buffer += 2;
+ }
+
+ for (; i < count; ++i)
+ *buffer++ = qConvertA2rgb30ToRgb64<PixelOrder>(*src++);
+}
+#endif
+
+template<QtPixelOrder PixelOrder>
+static const QRgba64 *QT_FASTCALL convertA2RGB30PMToARGB64PM(QRgba64 *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+#ifdef __SSE2__
+ qConvertA2RGB30PMToARGB64PM_sse2<PixelOrder>(buffer, src, count);
+#else
+ for (int i = 0; i < count; ++i)
+ buffer[i] = qConvertA2rgb30ToRgb64<PixelOrder>(src[i]);
+#endif
+ return buffer;
+}
+
template<QtPixelOrder PixelOrder>
static const uint *QT_FASTCALL convertA2RGB30PMFromARGB32PM(uint *buffer, const uint *src, int count,
const QPixelLayout *, const QRgb *)
@@ -601,15 +852,15 @@ inline void QT_FASTCALL storePixels<QPixelLayout::BPP32>(uchar *dest, const uint
// convertFromArgb32() assumes that no color channel is more than 8 bits.
// QImage::rgbSwapped() assumes that the red and blue color channels have the same number of bits.
QPixelLayout qPixelLayouts[QImage::NImageFormats] = {
- { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPPNone, 0, 0, 0 }, // Format_Invalid
- { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1MSB, convertIndexedToARGB32PM, 0, 0 }, // Format_Mono
- { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1LSB, convertIndexedToARGB32PM, 0, 0 }, // Format_MonoLSB
- { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP8, convertIndexedToARGB32PM, 0, 0 }, // Format_Indexed8
+ { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPPNone, 0, 0, 0, 0 }, // Format_Invalid
+ { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1MSB, convertIndexedToARGB32PM, 0, 0, convertIndexedToARGB64PM }, // Format_Mono
+ { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1LSB, convertIndexedToARGB32PM, 0, 0, convertIndexedToARGB64PM }, // Format_MonoLSB
+ { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP8, convertIndexedToARGB32PM, 0, 0, convertIndexedToARGB64PM }, // Format_Indexed8
// Technically using convertPassThrough to convert from ARGB32PM to RGB32 is wrong,
// but everywhere this generic conversion would be wrong is currently overloaded.
- { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP32, convertPassThrough, convertPassThrough, convertPassThrough }, // Format_RGB32
- { 8, 16, 8, 8, 8, 0, 8, 24, false, QPixelLayout::BPP32, convertARGB32ToARGB32PM, convertARGB32FromARGB32PM, convertPassThrough }, // Format_ARGB32
- { 8, 16, 8, 8, 8, 0, 8, 24, true, QPixelLayout::BPP32, convertPassThrough, convertPassThrough, convertPassThrough }, // Format_ARGB32_Premultiplied
+ { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP32, convertPassThrough, convertPassThrough, convertPassThrough, convertRGB32ToRGB64 }, // Format_RGB32
+ { 8, 16, 8, 8, 8, 0, 8, 24, false, QPixelLayout::BPP32, convertARGB32ToARGB32PM, convertARGB32FromARGB32PM, convertPassThrough, convertARGB32ToARGB64PM }, // Format_ARGB32
+ { 8, 16, 8, 8, 8, 0, 8, 24, true, QPixelLayout::BPP32, convertPassThrough, convertPassThrough, convertPassThrough, convertARGB32PMToARGB64PM }, // Format_ARGB32_Premultiplied
#ifdef Q_COMPILER_CONSTEXPR
pixelLayoutRGB<QImage::Format_RGB16>(),
pixelLayoutARGBPM<QImage::Format_ARGB8565_Premultiplied>(),
@@ -624,55 +875,73 @@ QPixelLayout qPixelLayouts[QImage::NImageFormats] = {
{ 5, 11, 6, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16,
convertToRGB32<QImage::Format_RGB16>,
convertRGBFromARGB32PM<QImage::Format_RGB16>,
- convertRGBFromRGB32<QImage::Format_RGB16>},
+ convertRGBFromRGB32<QImage::Format_RGB16>,
+ convertToRGB64<QImage::Format_RGB16>,
+ },
{ 5, 19, 6, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24,
convertARGBPMToARGB32PM<QImage::Format_ARGB8565_Premultiplied>,
convertARGBPMFromARGB32PM<QImage::Format_ARGB8565_Premultiplied>,
- convertARGBPMFromRGB32<QImage::Format_ARGB8565_Premultiplied>},
+ convertARGBPMFromRGB32<QImage::Format_ARGB8565_Premultiplied>,
+ convertARGBPMToARGB64PM<QImage::Format_ARGB8565_Premultiplied>,
+ },
{ 6, 12, 6, 6, 6, 0, 0, 0, false, QPixelLayout::BPP24,
convertToRGB32<QImage::Format_RGB666>,
convertRGBFromARGB32PM<QImage::Format_RGB666>,
- convertRGBFromRGB32<QImage::Format_RGB666>},
+ convertRGBFromRGB32<QImage::Format_RGB666>,
+ convertToRGB64<QImage::Format_RGB666>,
+ },
{ 6, 12, 6, 6, 6, 0, 6, 18, true, QPixelLayout::BPP24,
convertARGBPMToARGB32PM<QImage::Format_ARGB6666_Premultiplied>,
convertARGBPMFromARGB32PM<QImage::Format_ARGB6666_Premultiplied>,
- convertARGBPMFromRGB32<QImage::Format_ARGB6666_Premultiplied>},
+ convertARGBPMFromRGB32<QImage::Format_ARGB6666_Premultiplied>,
+ convertARGBPMToARGB64PM<QImage::Format_ARGB6666_Premultiplied>,
+ },
{ 5, 10, 5, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16,
convertToRGB32<QImage::Format_RGB555>,
convertRGBFromARGB32PM<QImage::Format_RGB555>,
- convertRGBFromRGB32<QImage::Format_RGB555> },
+ convertRGBFromRGB32<QImage::Format_RGB555>,
+ convertToRGB64<QImage::Format_RGB555>,
+ },
{ 5, 18, 5, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24,
convertARGBPMToARGB32PM<QImage::Format_ARGB8555_Premultiplied>,
convertARGBPMFromARGB32PM<QImage::Format_ARGB8555_Premultiplied>,
- convertARGBPMFromRGB32<QImage::Format_ARGB8555_Premultiplied>},
+ convertARGBPMFromRGB32<QImage::Format_ARGB8555_Premultiplied>,
+ convertARGBPMToARGB64PM<QImage::Format_ARGB8555_Premultiplied>,
+ },
{ 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP24,
convertToRGB32<QImage::Format_RGB888>,
convertRGBFromARGB32PM<QImage::Format_RGB888>,
- convertRGBFromRGB32<QImage::Format_RGB888>},
+ convertRGBFromRGB32<QImage::Format_RGB888>,
+ convertToRGB64<QImage::Format_RGB888>,
+ },
{ 4, 8, 4, 4, 4, 0, 0, 0, false, QPixelLayout::BPP16,
convertToRGB32<QImage::Format_RGB444>,
convertRGBFromARGB32PM<QImage::Format_RGB444>,
- convertRGBFromRGB32<QImage::Format_RGB444>},
+ convertRGBFromRGB32<QImage::Format_RGB444>,
+ convertToRGB64<QImage::Format_RGB444>,
+ },
{ 4, 8, 4, 4, 4, 0, 4, 12, true, QPixelLayout::BPP16,
convertARGBPMToARGB32PM<QImage::Format_ARGB4444_Premultiplied>,
convertARGBPMFromARGB32PM<QImage::Format_ARGB4444_Premultiplied>,
- convertARGBPMFromRGB32<QImage::Format_ARGB4444_Premultiplied>},
+ convertARGBPMFromRGB32<QImage::Format_ARGB4444_Premultiplied>,
+ convertARGBPMToARGB64PM<QImage::Format_ARGB4444_Premultiplied>,
+ },
#endif
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- { 8, 24, 8, 16, 8, 8, 0, 0, false, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBXFromARGB32PM, convertRGBXFromRGB32 }, // Format_RGBX8888
- { 8, 24, 8, 16, 8, 8, 8, 0, false, QPixelLayout::BPP32, convertRGBA8888ToARGB32PM, convertRGBA8888FromARGB32PM, convertRGBXFromRGB32 }, // Format_RGBA8888
- { 8, 24, 8, 16, 8, 8, 8, 0, true, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBA8888PMFromARGB32PM, convertRGBXFromRGB32}, // Format_RGBA8888_Premultiplied
+ { 8, 24, 8, 16, 8, 8, 0, 0, false, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBXFromARGB32PM, convertRGBXFromRGB32, convertRGBA8888PMToARGB64PM }, // Format_RGBX8888
+ { 8, 24, 8, 16, 8, 8, 8, 0, false, QPixelLayout::BPP32, convertRGBA8888ToARGB32PM, convertRGBA8888FromARGB32PM, convertRGBXFromRGB32, convertRGBA8888ToARGB64PM }, // Format_RGBA8888
+ { 8, 24, 8, 16, 8, 8, 8, 0, true, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBA8888PMFromARGB32PM, convertRGBXFromRGB32, convertRGBA8888PMToARGB64PM}, // Format_RGBA8888_Premultiplied
#else
- { 8, 0, 8, 8, 8, 16, 0, 24, false, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBXFromARGB32PM, convertRGBXFromRGB32 }, // Format_RGBX8888
- { 8, 0, 8, 8, 8, 16, 8, 24, false, QPixelLayout::BPP32, convertRGBA8888ToARGB32PM, convertRGBA8888FromARGB32PM, convertRGBXFromRGB32 }, // Format_RGBA8888 (ABGR32)
- { 8, 0, 8, 8, 8, 16, 8, 24, true, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBA8888PMFromARGB32PM, convertRGBXFromRGB32 }, // Format_RGBA8888_Premultiplied
+ { 8, 0, 8, 8, 8, 16, 0, 24, false, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBXFromARGB32PM, convertRGBXFromRGB32, convertRGBA8888PMToARGB64PM }, // Format_RGBX8888
+ { 8, 0, 8, 8, 8, 16, 8, 24, false, QPixelLayout::BPP32, convertRGBA8888ToARGB32PM, convertRGBA8888FromARGB32PM, convertRGBXFromRGB32, convertRGBA8888ToARGB64PM }, // Format_RGBA8888 (ABGR32)
+ { 8, 0, 8, 8, 8, 16, 8, 24, true, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBA8888PMFromARGB32PM, convertRGBXFromRGB32, convertRGBA8888PMToARGB64PM }, // Format_RGBA8888_Premultiplied
#endif
- { 10, 20, 10, 10, 10, 0, 0, 30, false, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderBGR>, convertRGB30FromARGB32PM<PixelOrderBGR>, convertRGB30FromRGB32<PixelOrderBGR> }, // Format_BGR30
- { 10, 20, 10, 10, 10, 0, 2, 30, true, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderBGR>, convertA2RGB30PMFromARGB32PM<PixelOrderBGR>, convertRGB30FromRGB32<PixelOrderBGR> }, // Format_A2BGR30_Premultiplied
- { 10, 0, 10, 10, 10, 20, 0, 30, false, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderRGB>, convertRGB30FromARGB32PM<PixelOrderRGB>, convertRGB30FromRGB32<PixelOrderRGB> }, // Format_RGB30
- { 10, 0, 10, 10, 10, 20, 2, 30, true, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderRGB>, convertA2RGB30PMFromARGB32PM<PixelOrderRGB>, convertRGB30FromRGB32<PixelOrderRGB> }, // Format_A2RGB30_Premultiplied
- { 0, 0, 0, 0, 0, 0, 8, 0, false, QPixelLayout::BPP8, convertAlpha8ToRGB32, convertAlpha8FromARGB32PM, 0 }, // Format_Alpha8
- { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP8, convertGrayscale8ToRGB32, convertGrayscale8FromARGB32PM, convertGrayscale8FromRGB32 } // Format_Grayscale8
+ { 10, 20, 10, 10, 10, 0, 0, 30, false, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderBGR>, convertRGB30FromARGB32PM<PixelOrderBGR>, convertRGB30FromRGB32<PixelOrderBGR>, convertA2RGB30PMToARGB64PM<PixelOrderBGR> }, // Format_BGR30
+ { 10, 20, 10, 10, 10, 0, 2, 30, true, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderBGR>, convertA2RGB30PMFromARGB32PM<PixelOrderBGR>, convertRGB30FromRGB32<PixelOrderBGR>, convertA2RGB30PMToARGB64PM<PixelOrderBGR> }, // Format_A2BGR30_Premultiplied
+ { 10, 0, 10, 10, 10, 20, 0, 30, false, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderRGB>, convertRGB30FromARGB32PM<PixelOrderRGB>, convertRGB30FromRGB32<PixelOrderRGB>, convertA2RGB30PMToARGB64PM<PixelOrderRGB> }, // Format_RGB30
+ { 10, 0, 10, 10, 10, 20, 2, 30, true, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderRGB>, convertA2RGB30PMFromARGB32PM<PixelOrderRGB>, convertRGB30FromRGB32<PixelOrderRGB>, convertA2RGB30PMToARGB64PM<PixelOrderRGB> }, // Format_A2RGB30_Premultiplied
+ { 0, 0, 0, 0, 0, 0, 8, 0, false, QPixelLayout::BPP8, convertAlpha8ToRGB32, convertAlpha8FromARGB32PM, 0, convertAlpha8ToRGB64 }, // Format_Alpha8
+ { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP8, convertGrayscale8ToRGB32, convertGrayscale8FromARGB32PM, convertGrayscale8FromRGB32, convertGrayscale8ToRGB64 } // Format_Grayscale8
};
const FetchPixelsFunc qFetchPixels[QPixelLayout::BPPCount] = {
@@ -758,6 +1027,20 @@ static uint *QT_FASTCALL destFetch(uint *buffer, QRasterBuffer *rasterBuffer, in
return const_cast<uint *>(layout->convertToARGB32PM(buffer, ptr, length, layout, 0));
}
+static QRgba64 *QT_FASTCALL destFetch64(QRgba64 *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length)
+{
+ const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format];
+ uint buffer32[buffer_size];
+ const uint *ptr = qFetchPixels[layout->bpp](buffer32, rasterBuffer->scanLine(y), x, length);
+ return const_cast<QRgba64 *>(layout->convertToARGB64PM(buffer, ptr, length, layout, 0));
+}
+
+static QRgba64 *QT_FASTCALL destFetch64uint32(QRgba64 *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length)
+{
+ const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format];
+ const uint *src = ((const uint *)rasterBuffer->scanLine(y)) + x;
+ return const_cast<QRgba64 *>(layout->convertToARGB64PM(buffer, src, length, layout, 0));
+}
static DestFetchProc destFetchProc[QImage::NImageFormats] =
{
@@ -788,6 +1071,35 @@ static DestFetchProc destFetchProc[QImage::NImageFormats] =
destFetch, // Format_Grayscale8
};
+static DestFetchProc64 destFetchProc64[QImage::NImageFormats] =
+{
+ 0, // Format_Invalid
+ destFetch64, // Format_Mono,
+ destFetch64, // Format_MonoLSB
+ 0, // Format_Indexed8
+ destFetch64uint32, // Format_RGB32
+ destFetch64uint32, // Format_ARGB32,
+ destFetch64uint32, // Format_ARGB32_Premultiplied
+ destFetch64, // Format_RGB16
+ destFetch64, // Format_ARGB8565_Premultiplied
+ destFetch64, // Format_RGB666
+ destFetch64, // Format_ARGB6666_Premultiplied
+ destFetch64, // Format_RGB555
+ destFetch64, // Format_ARGB8555_Premultiplied
+ destFetch64, // Format_RGB888
+ destFetch64, // Format_RGB444
+ destFetch64, // Format_ARGB4444_Premultiplied
+ destFetch64uint32, // Format_RGBX8888
+ destFetch64uint32, // Format_RGBA8888
+ destFetch64uint32, // Format_RGBA8888_Premultiplied
+ destFetch64uint32, // Format_BGR30
+ destFetch64uint32, // Format_A2BGR30_Premultiplied
+ destFetch64uint32, // Format_RGB30
+ destFetch64uint32, // Format_A2RGB30_Premultiplied
+ destFetch64, // Format_Alpha8
+ destFetch64, // Format_Grayscale8
+};
+
/*
Returns the color in the mono destination color table
that is the "nearest" to /color/.
@@ -904,6 +1216,125 @@ static void QT_FASTCALL destStore(QRasterBuffer *rasterBuffer, int x, int y, con
}
}
+static void QT_FASTCALL convertFromRgb64(uint *dest, const QRgba64 *src, int length)
+{
+ for (int i = 0; i < length; ++i) {
+ dest[i] = src[i].toArgb32();
+ }
+}
+
+static void QT_FASTCALL destStore64(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length)
+{
+ uint buf[buffer_size];
+ const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format];
+ StorePixelsFunc store = qStorePixels[layout->bpp];
+ uchar *dest = rasterBuffer->scanLine(y);
+ while (length) {
+ int l = qMin(length, buffer_size);
+ const uint *ptr = 0;
+ convertFromRgb64(buf, buffer, l);
+ if (!layout->premultiplied && !layout->alphaWidth)
+ ptr = layout->convertFromRGB32(buf, buf, l, layout, 0);
+ else
+ ptr = layout->convertFromARGB32PM(buf, buf, l, layout, 0);
+ store(dest, ptr, x, l);
+ length -= l;
+ buffer += l;
+ x += l;
+ }
+}
+
+#ifdef __SSE2__
+template<QtPixelOrder PixelOrder>
+static inline void qConvertARGB64PMToA2RGB30PM_sse2(uint *dest, const QRgba64 *buffer, int count)
+{
+ const __m128i gmask = _mm_set1_epi32(0x000ffc00);
+ const __m128i cmask = _mm_set1_epi32(0x000003ff);
+ int i = 0;
+ __m128i vr, vg, vb, va;
+ for (; i < count && (const uintptr_t)buffer & 0xF; ++i) {
+ *dest++ = qConvertRgb64ToRgb30<PixelOrder>(*buffer++);
+ }
+
+ for (; i < count-15; i += 16) {
+ // Repremultiplying is really expensive and hard to do in SIMD without AVX2,
+ // so we try to avoid it by checking if it is needed 16 samples at a time.
+ __m128i vOr = _mm_set1_epi32(0);
+ __m128i vAnd = _mm_set1_epi32(0xffffffff);
+ for (int j = 0; j < 16; j += 2) {
+ __m128i vs = _mm_load_si128((const __m128i*)(buffer + j));
+ vOr = _mm_or_si128(vOr, vs);
+ vAnd = _mm_and_si128(vAnd, vs);
+ }
+ const quint16 orAlpha = ((uint)_mm_extract_epi16(vOr, 3)) | ((uint)_mm_extract_epi16(vOr, 7));
+ const quint16 andAlpha = ((uint)_mm_extract_epi16(vAnd, 3)) & ((uint)_mm_extract_epi16(vAnd, 7));
+
+ if (andAlpha == 0xffff) {
+ for (int j = 0; j < 16; j += 2) {
+ __m128i vs = _mm_load_si128((const __m128i*)buffer);
+ buffer += 2;
+ vr = _mm_srli_epi64(vs, 6);
+ vg = _mm_srli_epi64(vs, 16 + 6 - 10);
+ vb = _mm_srli_epi64(vs, 32 + 6);
+ vr = _mm_and_si128(vr, cmask);
+ vg = _mm_and_si128(vg, gmask);
+ vb = _mm_and_si128(vb, cmask);
+ va = _mm_srli_epi64(vs, 48 + 14);
+ if (PixelOrder == PixelOrderRGB)
+ vr = _mm_slli_epi32(vr, 20);
+ else
+ vb = _mm_slli_epi32(vb, 20);
+ va = _mm_slli_epi32(va, 30);
+ __m128i vd = _mm_or_si128(_mm_or_si128(vr, vg), _mm_or_si128(vb, va));
+ vd = _mm_shuffle_epi32(vd, _MM_SHUFFLE(3, 1, 2, 0));
+ _mm_storel_epi64((__m128i*)dest, vd);
+ dest += 2;
+ }
+ } else if (orAlpha == 0) {
+ for (int j = 0; j < 16; ++j) {
+ *dest++ = 0;
+ buffer++;
+ }
+ } else {
+ for (int j = 0; j < 16; ++j)
+ *dest++ = qConvertRgb64ToRgb30<PixelOrder>(*buffer++);
+ }
+ }
+
+ for (; i < count; ++i)
+ *dest++ = qConvertRgb64ToRgb30<PixelOrder>(*buffer++);
+}
+#endif
+
+static void QT_FASTCALL destStore64ARGB32(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length)
+{
+ uint *dest = (uint*)rasterBuffer->scanLine(y) + x;
+ for (int i = 0; i < length; ++i) {
+ dest[i] = buffer[i].unpremultiplied().toArgb32();
+ }
+}
+
+static void QT_FASTCALL destStore64RGBA8888(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length)
+{
+ uint *dest = (uint*)rasterBuffer->scanLine(y) + x;
+ for (int i = 0; i < length; ++i) {
+ dest[i] = ARGB2RGBA(buffer[i].unpremultiplied().toArgb32());
+ }
+}
+
+template<QtPixelOrder PixelOrder>
+static void QT_FASTCALL destStore64RGB30(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length)
+{
+ uint *dest = (uint*)rasterBuffer->scanLine(y) + x;
+#ifdef __SSE2__
+ qConvertARGB64PMToA2RGB30PM_sse2<PixelOrder>(dest, buffer, length);
+#else
+ for (int i = 0; i < length; ++i) {
+ dest[i] = qConvertRgb64ToRgb30<PixelOrder>(buffer[i]);
+ }
+#endif
+}
+
static DestStoreProc destStoreProc[QImage::NImageFormats] =
{
0, // Format_Invalid
@@ -933,6 +1364,35 @@ static DestStoreProc destStoreProc[QImage::NImageFormats] =
destStore, // Format_Grayscale8
};
+static DestStoreProc64 destStoreProc64[QImage::NImageFormats] =
+{
+ 0, // Format_Invalid
+ destStore64, // Format_Mono,
+ destStore64, // Format_MonoLSB
+ 0, // Format_Indexed8
+ destStore64, // Format_RGB32
+ destStore64ARGB32, // Format_ARGB32,
+ destStore64, // Format_ARGB32_Premultiplied
+ destStore64, // Format_RGB16
+ destStore64, // Format_ARGB8565_Premultiplied
+ destStore64, // Format_RGB666
+ destStore64, // Format_ARGB6666_Premultiplied
+ destStore64, // Format_RGB555
+ destStore64, // Format_ARGB8555_Premultiplied
+ destStore64, // Format_RGB888
+ destStore64, // Format_RGB444
+ destStore64, // Format_ARGB4444_Premultiplied
+ destStore64, // Format_RGBX8888
+ destStore64RGBA8888, // Format_RGBA8888
+ destStore64, // Format_RGBA8888_Premultiplied
+ destStore64RGB30<PixelOrderBGR>, // Format_BGR30
+ destStore64RGB30<PixelOrderBGR>, // Format_A2BGR30_Premultiplied
+ destStore64RGB30<PixelOrderRGB>, // Format_RGB30
+ destStore64RGB30<PixelOrderRGB>, // Format_A2RGB30_Premultiplied
+ destStore64, // Format_Alpha8
+ destStore64, // Format_Grayscale8
+};
+
/*
Source fetches
@@ -988,6 +1448,21 @@ static const uint *QT_FASTCALL fetchUntransformedRGB16(uint *buffer, const Opera
return buffer;
}
+static const QRgba64 *QT_FASTCALL fetchUntransformed64(QRgba64 *buffer, const Operator *,
+ const QSpanData *data, int y, int x, int length)
+{
+ const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
+ const QRgb *clut = data->texture.colorTable ? data->texture.colorTable->constData() : 0;
+ if (layout->bpp != QPixelLayout::BPP32) {
+ uint buffer32[buffer_size];
+ const uint *ptr = qFetchPixels[layout->bpp](buffer32, data->texture.scanLine(y), x, length);
+ return layout->convertToARGB64PM(buffer, ptr, length, layout, clut);
+ } else {
+ const uint *src = (const uint *)data->texture.scanLine(y) + x;
+ return layout->convertToARGB64PM(buffer, src, length, layout, clut);
+ }
+}
+
// blendType is either BlendTransformed or BlendTransformedTiled
template<TextureBlendType blendType>
static const uint *QT_FASTCALL fetchTransformedARGB32PM(uint *buffer, const Operator *, const QSpanData *data,
@@ -1155,6 +1630,111 @@ static const uint *QT_FASTCALL fetchTransformed(uint *buffer, const Operator *,
return layout->convertToARGB32PM(buffer, buffer, length, layout, clut);
}
+template<TextureBlendType blendType> /* either BlendTransformed or BlendTransformedTiled */
+static const QRgba64 *QT_FASTCALL fetchTransformed64(QRgba64 *buffer, const Operator *, const QSpanData *data,
+ int y, int x, int length)
+{
+ int image_width = data->texture.width;
+ int image_height = data->texture.height;
+
+ const qreal cx = x + qreal(0.5);
+ const qreal cy = y + qreal(0.5);
+
+ const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
+ FetchPixelFunc fetch = qFetchPixel[layout->bpp];
+ const QRgb *clut = data->texture.colorTable ? data->texture.colorTable->constData() : 0;
+
+ uint buffer32[buffer_size];
+ QRgba64 *b = buffer;
+ if (data->fast_matrix) {
+ // The increment pr x in the scanline
+ int fdx = (int)(data->m11 * fixed_scale);
+ int fdy = (int)(data->m12 * fixed_scale);
+
+ int fx = int((data->m21 * cy
+ + data->m11 * cx + data->dx) * fixed_scale);
+ int fy = int((data->m22 * cy
+ + data->m12 * cx + data->dy) * fixed_scale);
+
+ int i = 0, j = 0;
+ while (i < length) {
+ if (j == buffer_size) {
+ layout->convertToARGB64PM(b, buffer32, buffer_size, layout, clut);
+ b += buffer_size;
+ j = 0;
+ }
+ int px = fx >> 16;
+ int py = fy >> 16;
+
+ if (blendType == BlendTransformedTiled) {
+ px %= image_width;
+ py %= image_height;
+ if (px < 0) px += image_width;
+ if (py < 0) py += image_height;
+ } else {
+ px = qBound(0, px, image_width - 1);
+ py = qBound(0, py, image_height - 1);
+ }
+ buffer32[j] = fetch(data->texture.scanLine(py), px);
+
+ fx += fdx;
+ fy += fdy;
+ ++i; ++j;
+ }
+ if (j > 0) {
+ layout->convertToARGB64PM(b, buffer32, j, layout, clut);
+ b += j;
+ }
+ } else {
+ const qreal fdx = data->m11;
+ const qreal fdy = data->m12;
+ const qreal fdw = data->m13;
+
+ qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
+ qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
+ qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
+
+ int i = 0, j = 0;
+ while (i < length) {
+ if (j == buffer_size) {
+ layout->convertToARGB64PM(b, buffer32, buffer_size, layout, clut);
+ b += buffer_size;
+ j = 0;
+ }
+ const qreal iw = fw == 0 ? 1 : 1 / fw;
+ const qreal tx = fx * iw;
+ const qreal ty = fy * iw;
+ int px = int(tx) - (tx < 0);
+ int py = int(ty) - (ty < 0);
+
+ if (blendType == BlendTransformedTiled) {
+ px %= image_width;
+ py %= image_height;
+ if (px < 0) px += image_width;
+ if (py < 0) py += image_height;
+ } else {
+ px = qBound(0, px, image_width - 1);
+ py = qBound(0, py, image_height - 1);
+ }
+ buffer32[j] = fetch(data->texture.scanLine(py), px);
+
+ fx += fdx;
+ fy += fdy;
+ fw += fdw;
+ //force increment to avoid /0
+ if (!fw) {
+ fw += fdw;
+ }
+ ++i; ++j;
+ }
+ if (j > 0) {
+ layout->convertToARGB64PM(b, buffer32, j, layout, clut);
+ b += j;
+ }
+ }
+ return buffer;
+}
+
/** \internal
interpolate 4 argb pixels with the distx and disty factor.
distx and disty bust be between 0 and 16
@@ -1245,6 +1825,42 @@ static inline uint interpolate_4_pixels_16(uint tl, uint tr, uint bl, uint br, i
}
#endif
+#if defined(__SSE2__)
+static inline QRgba64 interpolate_4_pixels_rgb64(QRgba64 t[], QRgba64 b[], uint distx, uint disty)
+{
+ const __m128i vdistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(distx), _MM_SHUFFLE(0, 0, 0, 0));
+ const __m128i vidistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(0x10000 - distx), _MM_SHUFFLE(0, 0, 0, 0));
+
+ __m128i vt = _mm_loadu_si128((const __m128i*)t);
+ if (disty) {
+ __m128i vb = _mm_loadu_si128((const __m128i*)b);
+ vt = _mm_mulhi_epu16(vt, _mm_set1_epi16(0x10000 - disty));
+ vb = _mm_mulhi_epu16(vb, _mm_set1_epi16(disty));
+ vt = _mm_add_epi16(vt, vb);
+ }
+ vt = _mm_mulhi_epu16(vt, _mm_unpacklo_epi64(vidistx, vdistx));
+ vt = _mm_add_epi16(vt, _mm_srli_si128(vt, 8));
+#ifdef Q_PROCESSOR_X86_64
+ return QRgba64::fromRgba64(_mm_cvtsi128_si64(vt));
+#else
+ QRgba64 out;
+ _mm_storel_epi64((__m128i*)&out, vt);
+ return out;
+#endif
+}
+#else
+static inline QRgba64 interpolate_4_pixels_rgb64(QRgba64 t[], QRgba64 b[], uint distx, uint disty)
+{
+ const uint dx = distx>>8;
+ const uint dy = disty>>8;
+ const uint idx = 256 - dx;
+ const uint idy = 256 - dy;
+ QRgba64 xtop = interpolate256(t[0], idx, t[1], dx);
+ QRgba64 xbot = interpolate256(b[0], idx, b[1], dx);
+ return interpolate256(xtop, idy, xbot, dy);
+}
+#endif
+
template<TextureBlendType blendType>
void fetchTransformedBilinear_pixelBounds(int max, int l1, int l2, int &v1, int &v2);
@@ -2130,6 +2746,349 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
return buffer;
}
+template<TextureBlendType blendType>
+static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, const Operator *,
+ const QSpanData *data, int y, int x, int length)
+{
+ const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
+ const QRgb *clut = data->texture.colorTable ? data->texture.colorTable->constData() : 0;
+
+ int image_width = data->texture.width;
+ int image_height = data->texture.height;
+
+ int image_x1 = data->texture.x1;
+ int image_y1 = data->texture.y1;
+ int image_x2 = data->texture.x2 - 1;
+ int image_y2 = data->texture.y2 - 1;
+
+ const qreal cx = x + qreal(0.5);
+ const qreal cy = y + qreal(0.5);
+
+ const qreal fdx = data->m11;
+ const qreal fdy = data->m12;
+ const qreal fdw = data->m13;
+
+ if (data->fast_matrix) {
+ // The increment pr x in the scanline
+ int fdx = (int)(data->m11 * fixed_scale);
+ int fdy = (int)(data->m12 * fixed_scale);
+
+ int fx = int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
+ int fy = int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
+
+ fx -= half_point;
+ fy -= half_point;
+
+ if (fdy == 0) { //simple scale, no rotation
+ int y1 = (fy >> 16);
+ int y2;
+ fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
+ const uchar *s1 = data->texture.scanLine(y1);
+ const uchar *s2 = data->texture.scanLine(y2);
+
+ FetchPixelFunc fetch = qFetchPixel[layout->bpp];
+ uint sbuf1[buffer_size];
+ uint sbuf2[buffer_size];
+ QRgba64 buf1[buffer_size];
+ QRgba64 buf2[buffer_size];
+ QRgba64 *b = buffer;
+ while (length) {
+ int len = qMin(length, buffer_size / 2);
+ int fracX = fx;
+ int i = 0;
+ int disty = (fy & 0x0000ffff);
+#if defined(__SSE2__)
+ const __m128i vdy = _mm_set1_epi16(disty);
+ const __m128i vidy = _mm_set1_epi16(0x10000 - disty);
+ if (blendType != BlendTransformedBilinearTiled && layout->bpp == QPixelLayout::BPP32) {
+ for (; i < len; ++i) {
+ int x1 = (fx >> 16);
+ int x2;
+ fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
+ if (x1 != x2)
+ break;
+ sbuf1[i * 2 + 0] = ((const uint*)s1)[x1];
+ sbuf1[i * 2 + 1] = ((const uint*)s1)[x2];
+ sbuf2[i * 2 + 0] = ((const uint*)s2)[x1];
+ sbuf2[i * 2 + 1] = ((const uint*)s2)[x2];
+ fx += fdx;
+ }
+
+ const __m128i v_fdx = _mm_set1_epi32(fdx*4);
+ __m128i v_fx = _mm_setr_epi32(fx, fx + fdx, fx + fdx + fdx, fx + fdx + fdx + fdx);
+ for (; i < len-3; i+=4) {
+ int offset = _mm_extract_epi16(v_fx, 1);
+ sbuf1[i * 2 + 0] = ((const uint*)s1)[offset];
+ sbuf1[i * 2 + 1] = ((const uint*)s1)[offset + 1];
+ sbuf2[i * 2 + 0] = ((const uint*)s2)[offset];
+ sbuf2[i * 2 + 1] = ((const uint*)s2)[offset + 1];
+ offset = _mm_extract_epi16(v_fx, 3);
+ sbuf1[i * 2 + 2] = ((const uint*)s1)[offset];
+ sbuf1[i * 2 + 3] = ((const uint*)s1)[offset + 1];
+ sbuf2[i * 2 + 2] = ((const uint*)s2)[offset];
+ sbuf2[i * 2 + 3] = ((const uint*)s2)[offset + 1];
+ offset = _mm_extract_epi16(v_fx, 5);
+ sbuf1[i * 2 + 4] = ((const uint*)s1)[offset];
+ sbuf1[i * 2 + 5] = ((const uint*)s1)[offset + 1];
+ sbuf2[i * 2 + 4] = ((const uint*)s2)[offset];
+ sbuf2[i * 2 + 5] = ((const uint*)s2)[offset + 1];
+ offset = _mm_extract_epi16(v_fx, 7);
+ sbuf1[i * 2 + 6] = ((const uint*)s1)[offset];
+ sbuf1[i * 2 + 7] = ((const uint*)s1)[offset + 1];
+ sbuf2[i * 2 + 6] = ((const uint*)s2)[offset];
+ sbuf2[i * 2 + 7] = ((const uint*)s2)[offset + 1];
+ v_fx = _mm_add_epi32(v_fx, v_fdx);
+ }
+ fx = _mm_cvtsi128_si32(v_fx);
+ }
+#endif
+ for (; i < len; ++i) {
+ int x1 = (fx >> 16);
+ int x2;
+ fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
+
+ if (layout->bpp == QPixelLayout::BPP32) {
+ sbuf1[i * 2 + 0] = ((const uint*)s1)[x1];
+ sbuf1[i * 2 + 1] = ((const uint*)s1)[x2];
+ sbuf2[i * 2 + 0] = ((const uint*)s2)[x1];
+ sbuf2[i * 2 + 1] = ((const uint*)s2)[x2];
+
+ } else {
+ sbuf1[i * 2 + 0] = fetch(s1, x1);
+ sbuf1[i * 2 + 1] = fetch(s1, x2);
+ sbuf2[i * 2 + 0] = fetch(s2, x1);
+ sbuf2[i * 2 + 1] = fetch(s2, x2);
+ }
+
+ fx += fdx;
+ }
+ layout->convertToARGB64PM(buf1, sbuf1, len * 2, layout, clut);
+ if (disty)
+ layout->convertToARGB64PM(buf2, sbuf2, len * 2, layout, clut);
+
+ for (int i = 0; i < len; ++i) {
+ int distx = (fracX & 0x0000ffff);
+#if defined(__SSE2__)
+ const __m128i vdistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(distx), _MM_SHUFFLE(0, 0, 0, 0));
+ const __m128i vidistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(0x10000 - distx), _MM_SHUFFLE(0, 0, 0, 0));
+ __m128i vt = _mm_loadu_si128((const __m128i*)(buf1 + i*2));
+ if (disty) {
+ __m128i vb = _mm_loadu_si128((const __m128i*)(buf2 + i*2));
+ vt = _mm_mulhi_epu16(vt, vidy);
+ vb = _mm_mulhi_epu16(vb, vdy);
+ vt = _mm_add_epi16(vt, vb);
+ }
+ vt = _mm_mulhi_epu16(vt, _mm_unpacklo_epi64(vidistx, vdistx));
+ vt = _mm_add_epi16(vt, _mm_srli_si128(vt, 8));
+ _mm_storel_epi64((__m128i*)(b+i), vt);
+#else
+ b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
+#endif
+ fracX += fdx;
+ }
+ length -= len;
+ b += len;
+ }
+ } else { //rotation
+ FetchPixelFunc fetch = qFetchPixel[layout->bpp];
+ uint sbuf1[buffer_size];
+ uint sbuf2[buffer_size];
+ QRgba64 buf1[buffer_size];
+ QRgba64 buf2[buffer_size];
+ QRgba64 *end = buffer + length;
+ QRgba64 *b = buffer;
+
+ while (b < end) {
+ int len = qMin(length, buffer_size / 2);
+ int fracX = fx;
+ int fracY = fy;
+ int i = 0;
+#if defined(__SSE2__)
+ if (blendType != BlendTransformedBilinearTiled && layout->bpp == QPixelLayout::BPP32) {
+ for (; i < len; ++i) {
+ int x1 = (fx >> 16);
+ int x2;
+ int y1 = (fy >> 16);
+ int y2;
+ fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
+ fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
+ if (x1 != x2 && y1 != y2)
+ break;
+ const uchar *s1 = data->texture.scanLine(y1);
+ const uchar *s2 = data->texture.scanLine(y2);
+ sbuf1[i * 2 + 0] = ((const uint*)s1)[x1];
+ sbuf1[i * 2 + 1] = ((const uint*)s1)[x2];
+ sbuf2[i * 2 + 0] = ((const uint*)s2)[x1];
+ sbuf2[i * 2 + 1] = ((const uint*)s2)[x2];
+ fx += fdx;
+ fy += fdy;
+ }
+
+ const __m128i v_fdx = _mm_set1_epi32(fdx*4);
+ const __m128i v_fdy = _mm_set1_epi32(fdy*4);
+ __m128i v_fx = _mm_setr_epi32(fx, fx + fdx, fx + fdx + fdx, fx + fdx + fdx + fdx);
+ __m128i v_fy = _mm_setr_epi32(fy, fy + fdy, fy + fdy + fdy, fy + fdy + fdy + fdy);
+ const int bytesPerLine = data->texture.bytesPerLine;
+ const uchar *s1 = data->texture.imageData;
+ const uchar *s2 = s1 + bytesPerLine;
+ const __m128i vbpl = _mm_shufflelo_epi16(_mm_cvtsi32_si128(bytesPerLine/4), _MM_SHUFFLE(0, 0, 0, 0));
+ for (; i < len-3; i+=4) {
+ if (fdx > 0 && (short)_mm_extract_epi16(v_fx, 7) >= image_x2)
+ break;
+ if (fdx < 0 && (short)_mm_extract_epi16(v_fx, 7) < image_x1)
+ break;
+ if (fdy > 0 && (short)_mm_extract_epi16(v_fy, 7) >= image_y2)
+ break;
+ if (fdy < 0 && (short)_mm_extract_epi16(v_fy, 7) < image_y1)
+ break;
+ const __m128i vy = _mm_packs_epi32(_mm_srai_epi32(v_fy, 16), _mm_setzero_si128());
+ __m128i voffset = _mm_unpacklo_epi16(_mm_mullo_epi16(vy, vbpl), _mm_mulhi_epu16(vy, vbpl));
+ voffset = _mm_add_epi32(voffset, _mm_srli_epi32(v_fx, 16));
+
+ int offset = _mm_cvtsi128_si32(voffset); voffset = _mm_srli_si128(voffset, 4);
+ sbuf1[i * 2 + 0] = ((const uint*)s1)[offset];
+ sbuf1[i * 2 + 1] = ((const uint*)s1)[offset + 1];
+ sbuf2[i * 2 + 0] = ((const uint*)s2)[offset];
+ sbuf2[i * 2 + 1] = ((const uint*)s2)[offset + 1];
+ offset = _mm_cvtsi128_si32(voffset); voffset = _mm_srli_si128(voffset, 4);
+ sbuf1[i * 2 + 2] = ((const uint*)s1)[offset];
+ sbuf1[i * 2 + 3] = ((const uint*)s1)[offset + 1];
+ sbuf2[i * 2 + 2] = ((const uint*)s2)[offset];
+ sbuf2[i * 2 + 3] = ((const uint*)s2)[offset + 1];
+ offset = _mm_cvtsi128_si32(voffset); voffset = _mm_srli_si128(voffset, 4);
+ sbuf1[i * 2 + 4] = ((const uint*)s1)[offset];
+ sbuf1[i * 2 + 5] = ((const uint*)s1)[offset + 1];
+ sbuf2[i * 2 + 4] = ((const uint*)s2)[offset];
+ sbuf2[i * 2 + 5] = ((const uint*)s2)[offset + 1];
+ offset = _mm_cvtsi128_si32(voffset);
+ sbuf1[i * 2 + 6] = ((const uint*)s1)[offset];
+ sbuf1[i * 2 + 7] = ((const uint*)s1)[offset + 1];
+ sbuf2[i * 2 + 6] = ((const uint*)s2)[offset];
+ sbuf2[i * 2 + 7] = ((const uint*)s2)[offset + 1];
+
+ v_fx = _mm_add_epi32(v_fx, v_fdx);
+ v_fy = _mm_add_epi32(v_fy, v_fdy);
+ }
+ fx = _mm_cvtsi128_si32(v_fx);
+ fy = _mm_cvtsi128_si32(v_fy);
+ }
+#endif
+ for (; i < len; ++i) {
+ int x1 = (fx >> 16);
+ int x2;
+ int y1 = (fy >> 16);
+ int y2;
+ fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
+ fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
+
+ const uchar *s1 = data->texture.scanLine(y1);
+ const uchar *s2 = data->texture.scanLine(y2);
+
+ if (layout->bpp == QPixelLayout::BPP32) {
+ sbuf1[i * 2 + 0] = ((const uint*)s1)[x1];
+ sbuf1[i * 2 + 1] = ((const uint*)s1)[x2];
+ sbuf2[i * 2 + 0] = ((const uint*)s2)[x1];
+ sbuf2[i * 2 + 1] = ((const uint*)s2)[x2];
+
+ } else {
+ sbuf1[i * 2 + 0] = fetch(s1, x1);
+ sbuf1[i * 2 + 1] = fetch(s1, x2);
+ sbuf2[i * 2 + 0] = fetch(s2, x1);
+ sbuf2[i * 2 + 1] = fetch(s2, x2);
+ }
+
+ fx += fdx;
+ fy += fdy;
+ }
+ layout->convertToARGB64PM(buf1, sbuf1, len * 2, layout, clut);
+ layout->convertToARGB64PM(buf2, sbuf2, len * 2, layout, clut);
+
+ for (int i = 0; i < len; ++i) {
+ int distx = (fracX & 0x0000ffff);
+ int disty = (fracY & 0x0000ffff);
+ b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
+ fracX += fdx;
+ fracY += fdy;
+ }
+
+ length -= len;
+ b += len;
+ }
+ }
+ } else {
+ qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
+ qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
+ qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
+
+ FetchPixelFunc fetch = qFetchPixel[layout->bpp];
+ uint sbuf1[buffer_size];
+ uint sbuf2[buffer_size];
+ QRgba64 buf1[buffer_size];
+ QRgba64 buf2[buffer_size];
+ QRgba64 *b = buffer;
+
+ int distxs[buffer_size / 2];
+ int distys[buffer_size / 2];
+
+ while (length) {
+ int len = qMin(length, buffer_size / 2);
+ for (int i = 0; i < len; ++i) {
+ const qreal iw = fw == 0 ? 1 : 1 / fw;
+ const qreal px = fx * iw - qreal(0.5);
+ const qreal py = fy * iw - qreal(0.5);
+
+ int x1 = int(px) - (px < 0);
+ int x2;
+ int y1 = int(py) - (py < 0);
+ int y2;
+
+ distxs[i] = int((px - x1) * (1<<16));
+ distys[i] = int((py - y1) * (1<<16));
+
+ fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
+ fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
+
+ const uchar *s1 = data->texture.scanLine(y1);
+ const uchar *s2 = data->texture.scanLine(y2);
+
+ if (layout->bpp == QPixelLayout::BPP32) {
+ sbuf1[i * 2 + 0] = ((const uint*)s1)[x1];
+ sbuf1[i * 2 + 1] = ((const uint*)s1)[x2];
+ sbuf2[i * 2 + 0] = ((const uint*)s2)[x1];
+ sbuf2[i * 2 + 1] = ((const uint*)s2)[x2];
+
+ } else {
+ sbuf1[i * 2 + 0] = fetch(s1, x1);
+ sbuf1[i * 2 + 1] = fetch(s1, x2);
+ sbuf2[i * 2 + 0] = fetch(s2, x1);
+ sbuf2[i * 2 + 1] = fetch(s2, x2);
+ }
+
+ fx += fdx;
+ fy += fdy;
+ fw += fdw;
+ //force increment to avoid /0
+ if (!fw)
+ fw += fdw;
+ }
+
+ layout->convertToARGB64PM(buf1, sbuf1, len * 2, layout, clut);
+ layout->convertToARGB64PM(buf2, sbuf2, len * 2, layout, clut);
+
+ for (int i = 0; i < len; ++i) {
+ int distx = distxs[i];
+ int disty = distys[i];
+ b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
+ }
+
+ length -= len;
+ b += len;
+ }
+ }
+
+ return buffer;
+}
+
static SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = {
// Untransformed
{
@@ -2298,12 +3257,186 @@ static SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = {
},
};
+static SourceFetchProc64 sourceFetch64[NBlendTypes][QImage::NImageFormats] = {
+ // Untransformed
+ {
+ 0, // Invalid
+ fetchUntransformed64, // Mono
+ fetchUntransformed64, // MonoLsb
+ fetchUntransformed64, // Indexed8
+ fetchUntransformed64, // RGB32
+ fetchUntransformed64, // ARGB32
+ fetchUntransformed64, // ARGB32_Premultiplied
+ fetchUntransformed64, // RGB16
+ fetchUntransformed64, // ARGB8565_Premultiplied
+ fetchUntransformed64, // RGB666
+ fetchUntransformed64, // ARGB6666_Premultiplied
+ fetchUntransformed64, // RGB555
+ fetchUntransformed64, // ARGB8555_Premultiplied
+ fetchUntransformed64, // RGB888
+ fetchUntransformed64, // RGB444
+ fetchUntransformed64, // ARGB4444_Premultiplied
+ fetchUntransformed64, // RGBX8888
+ fetchUntransformed64, // RGBA8888
+ fetchUntransformed64, // RGBA8888_Premultiplied
+ fetchUntransformed64, // Format_BGR30
+ fetchUntransformed64, // Format_A2BGR30_Premultiplied
+ fetchUntransformed64, // Format_RGB30
+ fetchUntransformed64, // Format_A2RGB30_Premultiplied
+ fetchUntransformed64, // Alpha8
+ fetchUntransformed64, // Grayscale8
+ },
+ // Tiled
+ {
+ 0, // Invalid
+ fetchUntransformed64, // Mono
+ fetchUntransformed64, // MonoLsb
+ fetchUntransformed64, // Indexed8
+ fetchUntransformed64, // RGB32
+ fetchUntransformed64, // ARGB32
+ fetchUntransformed64, // ARGB32_Premultiplied
+ fetchUntransformed64, // RGB16
+ fetchUntransformed64, // ARGB8565_Premultiplied
+ fetchUntransformed64, // RGB666
+ fetchUntransformed64, // ARGB6666_Premultiplied
+ fetchUntransformed64, // RGB555
+ fetchUntransformed64, // ARGB8555_Premultiplied
+ fetchUntransformed64, // RGB888
+ fetchUntransformed64, // RGB444
+ fetchUntransformed64, // ARGB4444_Premultiplied
+ fetchUntransformed64, // RGBX8888
+ fetchUntransformed64, // RGBA8888
+ fetchUntransformed64, // RGBA8888_Premultiplied
+ fetchUntransformed64, // BGR30
+ fetchUntransformed64, // A2BGR30_Premultiplied
+ fetchUntransformed64, // RGB30
+ fetchUntransformed64, // A2RGB30_Premultiplied
+ fetchUntransformed64, // Alpha8
+ fetchUntransformed64, // Grayscale8
+ },
+ // Transformed
+ {
+ 0, // Invalid
+ fetchTransformed64<BlendTransformed>, // Mono
+ fetchTransformed64<BlendTransformed>, // MonoLsb
+ fetchTransformed64<BlendTransformed>, // Indexed8
+ fetchTransformed64<BlendTransformed>, // RGB32
+ fetchTransformed64<BlendTransformed>, // ARGB32
+ fetchTransformed64<BlendTransformed>, // ARGB32_Premultiplied
+ fetchTransformed64<BlendTransformed>, // RGB16
+ fetchTransformed64<BlendTransformed>, // ARGB8565_Premultiplied
+ fetchTransformed64<BlendTransformed>, // RGB666
+ fetchTransformed64<BlendTransformed>, // ARGB6666_Premultiplied
+ fetchTransformed64<BlendTransformed>, // RGB555
+ fetchTransformed64<BlendTransformed>, // ARGB8555_Premultiplied
+ fetchTransformed64<BlendTransformed>, // RGB888
+ fetchTransformed64<BlendTransformed>, // RGB444
+ fetchTransformed64<BlendTransformed>, // ARGB4444_Premultiplied
+ fetchTransformed64<BlendTransformed>, // RGBX8888
+ fetchTransformed64<BlendTransformed>, // RGBA8888
+ fetchTransformed64<BlendTransformed>, // RGBA8888_Premultiplied
+ fetchTransformed64<BlendTransformed>, // BGR30
+ fetchTransformed64<BlendTransformed>, // A2BGR30_Premultiplied
+ fetchTransformed64<BlendTransformed>, // RGB30
+ fetchTransformed64<BlendTransformed>, // A2RGB30_Premultiplied
+ fetchTransformed64<BlendTransformed>, // Alpah8
+ fetchTransformed64<BlendTransformed>, // Grayscale8
+ },
+ {
+ 0, // TransformedTiled
+ fetchTransformed64<BlendTransformedTiled>, // Mono
+ fetchTransformed64<BlendTransformedTiled>, // MonoLsb
+ fetchTransformed64<BlendTransformedTiled>, // Indexed8
+ fetchTransformed64<BlendTransformedTiled>, // RGB32
+ fetchTransformed64<BlendTransformedTiled>, // ARGB32
+ fetchTransformed64<BlendTransformedTiled>, // ARGB32_Premultiplied
+ fetchTransformed64<BlendTransformedTiled>, // RGB16
+ fetchTransformed64<BlendTransformedTiled>, // ARGB8565_Premultiplied
+ fetchTransformed64<BlendTransformedTiled>, // RGB666
+ fetchTransformed64<BlendTransformedTiled>, // ARGB6666_Premultiplied
+ fetchTransformed64<BlendTransformedTiled>, // RGB555
+ fetchTransformed64<BlendTransformedTiled>, // ARGB8555_Premultiplied
+ fetchTransformed64<BlendTransformedTiled>, // RGB888
+ fetchTransformed64<BlendTransformedTiled>, // RGB444
+ fetchTransformed64<BlendTransformedTiled>, // ARGB4444_Premultiplied
+ fetchTransformed64<BlendTransformedTiled>, // RGBX8888
+ fetchTransformed64<BlendTransformedTiled>, // RGBA8888
+ fetchTransformed64<BlendTransformedTiled>, // RGBA8888_Premultiplied
+ fetchTransformed64<BlendTransformedTiled>, // BGR30
+ fetchTransformed64<BlendTransformedTiled>, // A2BGR30_Premultiplied
+ fetchTransformed64<BlendTransformedTiled>, // RGB30
+ fetchTransformed64<BlendTransformedTiled>, // A2RGB30_Premultiplied
+ fetchTransformed64<BlendTransformedTiled>, // Alpha8
+ fetchTransformed64<BlendTransformedTiled>, // Grayscale8
+ },
+ {
+ 0, // Bilinear
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // Mono
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // MonoLsb
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // Indexed8
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // RGB32
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // ARGB32
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // ARGB32_Premultiplied
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // RGB16
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // ARGB8565_Premultiplied
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // RGB666
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // ARGB6666_Premultiplied
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // RGB555
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // ARGB8555_Premultiplied
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // RGB888
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // RGB444
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // ARGB4444_Premultiplied
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // RGBX8888
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // RGBA8888
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // RGBA8888_Premultiplied
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // BGR30
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // A2BGR30_Premultiplied
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // RGB30
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // A2RGB30_Premultiplied
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // Alpha8
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // Grayscale8
+ },
+ {
+ 0, // BilinearTiled
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // Mono
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // MonoLsb
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // Indexed8
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGB32
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // ARGB32
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // ARGB32_Premultiplied
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGB16
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // ARGB8565_Premultiplied
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGB666
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // ARGB6666_Premultiplied
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGB555
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // ARGB8555_Premultiplied
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGB888
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGB444
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // ARGB4444_Premultiplied
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGBX8888
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGBA8888
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGBA8888_Premultiplied
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // BGR30
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // A2BGR30_Premultiplied
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGB30
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // A2RGB30_Premultiplied
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // Alpha8
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // Grayscale8
+ },
+};
+
#define FIXPT_BITS 8
#define FIXPT_SIZE (1<<FIXPT_BITS)
static uint qt_gradient_pixel_fixed(const QGradientData *data, int fixed_pos)
{
int ipos = (fixed_pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS;
+ return data->colorTable[qt_gradient_clamp(data, ipos)].toArgb32();
+}
+
+static const QRgba64& qt_gradient_pixel64_fixed(const QGradientData *data, int fixed_pos)
+{
+ int ipos = (fixed_pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS;
return data->colorTable[qt_gradient_clamp(data, ipos)];
}
@@ -2320,10 +3453,50 @@ static void QT_FASTCALL getLinearGradientValues(LinearGradientValues *v, const Q
}
}
-static const uint * QT_FASTCALL qt_fetch_linear_gradient(uint *buffer, const Operator *op, const QSpanData *data,
- int y, int x, int length)
+class GradientBase32
+{
+public:
+ typedef uint Type;
+ static Type null() { return 0; }
+ static Type fetchSingle(const QGradientData& gradient, qreal v)
+ {
+ return qt_gradient_pixel(&gradient, v);
+ }
+ static Type fetchSingle(const QGradientData& gradient, int v)
+ {
+ return qt_gradient_pixel_fixed(&gradient, v);
+ }
+ static void memfill(Type *buffer, Type fill, int length)
+ {
+ qt_memfill32(buffer, fill, length);
+ }
+};
+
+class GradientBase64
+{
+public:
+ typedef QRgba64 Type;
+ static Type null() { return QRgba64::fromRgba64(0); }
+ static Type fetchSingle(const QGradientData& gradient, qreal v)
+ {
+ return qt_gradient_pixel64(&gradient, v);
+ }
+ static Type fetchSingle(const QGradientData& gradient, int v)
+ {
+ return qt_gradient_pixel64_fixed(&gradient, v);
+ }
+ static void memfill(Type *buffer, Type fill, int length)
+ {
+ qt_memfill64((quint64*)buffer, fill, length);
+ }
+};
+
+template<class GradientBase, typename BlendType>
+static inline const BlendType * QT_FASTCALL qt_fetch_linear_gradient_template(
+ BlendType *buffer, const Operator *op, const QSpanData *data,
+ int y, int x, int length)
{
- const uint *b = buffer;
+ const BlendType *b = buffer;
qreal t, inc;
bool affine = true;
@@ -2343,10 +3516,10 @@ static const uint * QT_FASTCALL qt_fetch_linear_gradient(uint *buffer, const Ope
}
}
- const uint *end = buffer + length;
+ const BlendType *end = buffer + length;
if (affine) {
if (inc > qreal(-1e-5) && inc < qreal(1e-5)) {
- QT_MEMFILL_UINT(buffer, length, qt_gradient_pixel_fixed(&data->gradient, int(t * FIXPT_SIZE)));
+ GradientBase::memfill(buffer, GradientBase::fetchSingle(data->gradient, int(t * FIXPT_SIZE)), length);
} else {
if (t+inc*length < qreal(INT_MAX >> (FIXPT_BITS + 1)) &&
t+inc*length > qreal(INT_MIN >> (FIXPT_BITS + 1))) {
@@ -2354,14 +3527,14 @@ static const uint * QT_FASTCALL qt_fetch_linear_gradient(uint *buffer, const Ope
int t_fixed = int(t * FIXPT_SIZE);
int inc_fixed = int(inc * FIXPT_SIZE);
while (buffer < end) {
- *buffer = qt_gradient_pixel_fixed(&data->gradient, t_fixed);
+ *buffer = GradientBase::fetchSingle(data->gradient, t_fixed);
t_fixed += inc_fixed;
++buffer;
}
} else {
// we have to fall back to float math
while (buffer < end) {
- *buffer = qt_gradient_pixel(&data->gradient, t/GRADIENT_STOPTABLE_SIZE);
+ *buffer = GradientBase::fetchSingle(data->gradient, t/GRADIENT_STOPTABLE_SIZE);
t += inc;
++buffer;
}
@@ -2374,7 +3547,7 @@ static const uint * QT_FASTCALL qt_fetch_linear_gradient(uint *buffer, const Ope
qreal y = ry/rw;
t = (op->linear.dx*x + op->linear.dy *y) + op->linear.off;
- *buffer = qt_gradient_pixel(&data->gradient, t);
+ *buffer = GradientBase::fetchSingle(data->gradient, t);
rx += data->m11;
ry += data->m12;
rw += data->m13;
@@ -2388,6 +3561,18 @@ static const uint * QT_FASTCALL qt_fetch_linear_gradient(uint *buffer, const Ope
return b;
}
+static const uint * QT_FASTCALL qt_fetch_linear_gradient(uint *buffer, const Operator *op, const QSpanData *data,
+ int y, int x, int length)
+{
+ return qt_fetch_linear_gradient_template<GradientBase32, uint>(buffer, op, data, y, x, length);
+}
+
+static const QRgba64 * QT_FASTCALL qt_fetch_linear_gradient_rgb64(QRgba64 *buffer, const Operator *op, const QSpanData *data,
+ int y, int x, int length)
+{
+ return qt_fetch_linear_gradient_template<GradientBase64, QRgba64>(buffer, op, data, y, x, length);
+}
+
static void QT_FASTCALL getRadialGradientValues(RadialGradientValues *v, const QSpanData *data)
{
v->dx = data->gradient.radial.center.x - data->gradient.radial.focal.x;
@@ -2402,19 +3587,22 @@ static void QT_FASTCALL getRadialGradientValues(RadialGradientValues *v, const Q
v->extended = !qFuzzyIsNull(data->gradient.radial.focal.radius) || v->a <= 0;
}
-class RadialFetchPlain
+template <class GradientBase>
+class RadialFetchPlain : public GradientBase
{
public:
- static inline void fetch(uint *buffer, uint *end, const Operator *op, const QSpanData *data, qreal det,
- qreal delta_det, qreal delta_delta_det, qreal b, qreal delta_b)
+ typedef typename GradientBase::Type BlendType;
+ static void fetch(BlendType *buffer, BlendType *end,
+ const Operator *op, const QSpanData *data, qreal det,
+ qreal delta_det, qreal delta_delta_det, qreal b, qreal delta_b)
{
if (op->radial.extended) {
while (buffer < end) {
- quint32 result = 0;
+ BlendType result = GradientBase::null();
if (det >= 0) {
qreal w = qSqrt(det) - b;
if (data->gradient.radial.focal.radius + op->radial.dr * w >= 0)
- result = qt_gradient_pixel(&data->gradient, w);
+ result = GradientBase::fetchSingle(data->gradient, w);
}
*buffer = result;
@@ -2427,7 +3615,7 @@ public:
}
} else {
while (buffer < end) {
- *buffer++ = qt_gradient_pixel(&data->gradient, qSqrt(det) - b);
+ *buffer++ = GradientBase::fetchSingle(data->gradient, qSqrt(det) - b);
det += delta_det;
delta_det += delta_delta_det;
@@ -2440,15 +3628,23 @@ public:
const uint * QT_FASTCALL qt_fetch_radial_gradient_plain(uint *buffer, const Operator *op, const QSpanData *data,
int y, int x, int length)
{
- return qt_fetch_radial_gradient_template<RadialFetchPlain>(buffer, op, data, y, x, length);
+ return qt_fetch_radial_gradient_template<RadialFetchPlain<GradientBase32>, uint>(buffer, op, data, y, x, length);
}
static SourceFetchProc qt_fetch_radial_gradient = qt_fetch_radial_gradient_plain;
-static const uint * QT_FASTCALL qt_fetch_conical_gradient(uint *buffer, const Operator *, const QSpanData *data,
- int y, int x, int length)
+const QRgba64 * QT_FASTCALL qt_fetch_radial_gradient_rgb64(QRgba64 *buffer, const Operator *op, const QSpanData *data,
+ int y, int x, int length)
{
- const uint *b = buffer;
+ return qt_fetch_radial_gradient_template<RadialFetchPlain<GradientBase64>, QRgba64>(buffer, op, data, y, x, length);
+}
+
+template <class GradientBase, typename BlendType>
+static inline const BlendType * QT_FASTCALL qt_fetch_conical_gradient_template(
+ BlendType *buffer, const QSpanData *data,
+ int y, int x, int length)
+{
+ const BlendType *b = buffer;
qreal rx = data->m21 * (y + qreal(0.5))
+ data->dx + data->m11 * (x + qreal(0.5));
qreal ry = data->m22 * (y + qreal(0.5))
@@ -2457,14 +3653,14 @@ static const uint * QT_FASTCALL qt_fetch_conical_gradient(uint *buffer, const Op
const qreal inv2pi = M_1_PI / 2.0;
- const uint *end = buffer + length;
+ const BlendType *end = buffer + length;
if (affine) {
rx -= data->gradient.conical.center.x;
ry -= data->gradient.conical.center.y;
while (buffer < end) {
qreal angle = qAtan2(ry, rx) + data->gradient.conical.angle;
- *buffer = qt_gradient_pixel(&data->gradient, 1 - angle * inv2pi);
+ *buffer = GradientBase::fetchSingle(data->gradient, 1 - angle * inv2pi);
rx += data->m11;
ry += data->m12;
@@ -2480,7 +3676,7 @@ static const uint * QT_FASTCALL qt_fetch_conical_gradient(uint *buffer, const Op
rx/rw - data->gradient.conical.center.y)
+ data->gradient.conical.angle;
- *buffer = qt_gradient_pixel(&data->gradient, 1 - angle * inv2pi);
+ *buffer = GradientBase::fetchSingle(data->gradient, 1 - angle * inv2pi);
rx += data->m11;
ry += data->m12;
@@ -2494,1763 +3690,29 @@ static const uint * QT_FASTCALL qt_fetch_conical_gradient(uint *buffer, const Op
return b;
}
-# define PRELOAD_INIT(x)
-# define PRELOAD_INIT2(x,y)
-# define PRELOAD_COND(x)
-# define PRELOAD_COND2(x,y)
-
-/* The constant alpha factor describes an alpha factor that gets applied
- to the result of the composition operation combining it with the destination.
-
- The intent is that if const_alpha == 0. we get back dest, and if const_alpha == 1.
- we get the unmodified operation
-
- result = src op dest
- dest = result * const_alpha + dest * (1. - const_alpha)
-
- This means that in the comments below, the first line is the const_alpha==255 case, the
- second line the general one.
-
- In the lines below:
- s == src, sa == alpha(src), sia = 1 - alpha(src)
- d == dest, da == alpha(dest), dia = 1 - alpha(dest)
- ca = const_alpha, cia = 1 - const_alpha
-
- The methods exist in two variants. One where we have a constant source, the other
- where the source is an array of pixels.
-*/
-
-/*
- result = 0
- d = d * cia
-*/
-#define comp_func_Clear_impl(dest, length, const_alpha)\
-{\
- if (const_alpha == 255) {\
- QT_MEMFILL_UINT(dest, length, 0);\
- } else {\
- int ialpha = 255 - const_alpha;\
- PRELOAD_INIT(dest)\
- for (int i = 0; i < length; ++i) {\
- PRELOAD_COND(dest)\
- dest[i] = BYTE_MUL(dest[i], ialpha);\
- }\
- }\
-}
-
-void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha)
-{
- comp_func_Clear_impl(dest, length, const_alpha);
-}
-
-void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha)
-{
- comp_func_Clear_impl(dest, length, const_alpha);
-}
-
-/*
- result = s
- dest = s * ca + d * cia
-*/
-void QT_FASTCALL comp_func_solid_Source(uint *dest, int length, uint color, uint const_alpha)
-{
- if (const_alpha == 255) {
- QT_MEMFILL_UINT(dest, length, color);
- } else {
- int ialpha = 255 - const_alpha;
- color = BYTE_MUL(color, const_alpha);
- PRELOAD_INIT(dest)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- dest[i] = color + BYTE_MUL(dest[i], ialpha);
- }
- }
-}
-
-void QT_FASTCALL comp_func_Source(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
-{
- if (const_alpha == 255) {
- ::memcpy(dest, src, length * sizeof(uint));
- } else {
- int ialpha = 255 - const_alpha;
- PRELOAD_INIT2(dest, src)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- dest[i] = INTERPOLATE_PIXEL_255(src[i], const_alpha, dest[i], ialpha);
- }
- }
-}
-
-void QT_FASTCALL comp_func_solid_Destination(uint *, int, uint, uint)
-{
-}
-
-void QT_FASTCALL comp_func_Destination(uint *, const uint *, int, uint)
-{
-}
-
-/*
- result = s + d * sia
- dest = (s + d * sia) * ca + d * cia
- = s * ca + d * (sia * ca + cia)
- = s * ca + d * (1 - sa*ca)
-*/
-void QT_FASTCALL comp_func_solid_SourceOver(uint *dest, int length, uint color, uint const_alpha)
-{
- if ((const_alpha & qAlpha(color)) == 255) {
- QT_MEMFILL_UINT(dest, length, color);
- } else {
- if (const_alpha != 255)
- color = BYTE_MUL(color, const_alpha);
- PRELOAD_INIT(dest)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- dest[i] = color + BYTE_MUL(dest[i], qAlpha(~color));
- }
- }
-}
-
-void QT_FASTCALL comp_func_SourceOver(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
-{
- PRELOAD_INIT2(dest, src)
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint s = src[i];
- if (s >= 0xff000000)
- dest[i] = s;
- else if (s != 0)
- dest[i] = s + BYTE_MUL(dest[i], qAlpha(~s));
- }
- } else {
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint s = BYTE_MUL(src[i], const_alpha);
- dest[i] = s + BYTE_MUL(dest[i], qAlpha(~s));
- }
- }
-}
-
-/*
- result = d + s * dia
- dest = (d + s * dia) * ca + d * cia
- = d + s * dia * ca
-*/
-void QT_FASTCALL comp_func_solid_DestinationOver(uint *dest, int length, uint color, uint const_alpha)
-{
- if (const_alpha != 255)
- color = BYTE_MUL(color, const_alpha);
- PRELOAD_INIT(dest)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- uint d = dest[i];
- dest[i] = d + BYTE_MUL(color, qAlpha(~d));
- }
-}
-
-void QT_FASTCALL comp_func_DestinationOver(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
-{
- PRELOAD_INIT2(dest, src)
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint d = dest[i];
- dest[i] = d + BYTE_MUL(src[i], qAlpha(~d));
- }
- } else {
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint d = dest[i];
- uint s = BYTE_MUL(src[i], const_alpha);
- dest[i] = d + BYTE_MUL(s, qAlpha(~d));
- }
- }
-}
-
-/*
- result = s * da
- dest = s * da * ca + d * cia
-*/
-void QT_FASTCALL comp_func_solid_SourceIn(uint *dest, int length, uint color, uint const_alpha)
-{
- PRELOAD_INIT(dest)
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- dest[i] = BYTE_MUL(color, qAlpha(dest[i]));
- }
- } else {
- color = BYTE_MUL(color, const_alpha);
- uint cia = 255 - const_alpha;
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- uint d = dest[i];
- dest[i] = INTERPOLATE_PIXEL_255(color, qAlpha(d), d, cia);
- }
- }
-}
-
-void QT_FASTCALL comp_func_SourceIn(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
-{
- PRELOAD_INIT2(dest, src)
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- dest[i] = BYTE_MUL(src[i], qAlpha(dest[i]));
- }
- } else {
- uint cia = 255 - const_alpha;
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint d = dest[i];
- uint s = BYTE_MUL(src[i], const_alpha);
- dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(d), d, cia);
- }
- }
-}
-
-/*
- result = d * sa
- dest = d * sa * ca + d * cia
- = d * (sa * ca + cia)
-*/
-void QT_FASTCALL comp_func_solid_DestinationIn(uint *dest, int length, uint color, uint const_alpha)
-{
- uint a = qAlpha(color);
- if (const_alpha != 255) {
- a = BYTE_MUL(a, const_alpha) + 255 - const_alpha;
- }
- PRELOAD_INIT(dest)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- dest[i] = BYTE_MUL(dest[i], a);
- }
-}
-
-void QT_FASTCALL comp_func_DestinationIn(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
-{
- PRELOAD_INIT2(dest, src)
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- dest[i] = BYTE_MUL(dest[i], qAlpha(src[i]));
- }
- } else {
- int cia = 255 - const_alpha;
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint a = BYTE_MUL(qAlpha(src[i]), const_alpha) + cia;
- dest[i] = BYTE_MUL(dest[i], a);
- }
- }
-}
-
-/*
- result = s * dia
- dest = s * dia * ca + d * cia
-*/
-
-void QT_FASTCALL comp_func_solid_SourceOut(uint *dest, int length, uint color, uint const_alpha)
-{
- PRELOAD_INIT(dest)
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- dest[i] = BYTE_MUL(color, qAlpha(~dest[i]));
- }
- } else {
- color = BYTE_MUL(color, const_alpha);
- int cia = 255 - const_alpha;
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- uint d = dest[i];
- dest[i] = INTERPOLATE_PIXEL_255(color, qAlpha(~d), d, cia);
- }
- }
-}
-
-void QT_FASTCALL comp_func_SourceOut(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
-{
- PRELOAD_INIT2(dest, src)
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- dest[i] = BYTE_MUL(src[i], qAlpha(~dest[i]));
- }
- } else {
- int cia = 255 - const_alpha;
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint s = BYTE_MUL(src[i], const_alpha);
- uint d = dest[i];
- dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(~d), d, cia);
- }
- }
-}
-
-/*
- result = d * sia
- dest = d * sia * ca + d * cia
- = d * (sia * ca + cia)
-*/
-void QT_FASTCALL comp_func_solid_DestinationOut(uint *dest, int length, uint color, uint const_alpha)
-{
- uint a = qAlpha(~color);
- if (const_alpha != 255)
- a = BYTE_MUL(a, const_alpha) + 255 - const_alpha;
- PRELOAD_INIT(dest)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- dest[i] = BYTE_MUL(dest[i], a);
- }
-}
-
-void QT_FASTCALL comp_func_DestinationOut(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
-{
- PRELOAD_INIT2(dest, src)
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- dest[i] = BYTE_MUL(dest[i], qAlpha(~src[i]));
- }
- } else {
- int cia = 255 - const_alpha;
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint sia = BYTE_MUL(qAlpha(~src[i]), const_alpha) + cia;
- dest[i] = BYTE_MUL(dest[i], sia);
- }
- }
-}
-
-/*
- result = s*da + d*sia
- dest = s*da*ca + d*sia*ca + d *cia
- = s*ca * da + d * (sia*ca + cia)
- = s*ca * da + d * (1 - sa*ca)
-*/
-void QT_FASTCALL comp_func_solid_SourceAtop(uint *dest, int length, uint color, uint const_alpha)
-{
- if (const_alpha != 255) {
- color = BYTE_MUL(color, const_alpha);
- }
- uint sia = qAlpha(~color);
- PRELOAD_INIT(dest)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- dest[i] = INTERPOLATE_PIXEL_255(color, qAlpha(dest[i]), dest[i], sia);
- }
-}
-
-void QT_FASTCALL comp_func_SourceAtop(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
-{
- PRELOAD_INIT2(dest, src)
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint s = src[i];
- uint d = dest[i];
- dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(d), d, qAlpha(~s));
- }
- } else {
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint s = BYTE_MUL(src[i], const_alpha);
- uint d = dest[i];
- dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(d), d, qAlpha(~s));
- }
- }
-}
-
-/*
- result = d*sa + s*dia
- dest = d*sa*ca + s*dia*ca + d *cia
- = s*ca * dia + d * (sa*ca + cia)
-*/
-void QT_FASTCALL comp_func_solid_DestinationAtop(uint *dest, int length, uint color, uint const_alpha)
-{
- uint a = qAlpha(color);
- if (const_alpha != 255) {
- color = BYTE_MUL(color, const_alpha);
- a = qAlpha(color) + 255 - const_alpha;
- }
- PRELOAD_INIT(dest)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- uint d = dest[i];
- dest[i] = INTERPOLATE_PIXEL_255(d, a, color, qAlpha(~d));
- }
-}
-
-void QT_FASTCALL comp_func_DestinationAtop(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
-{
- PRELOAD_INIT2(dest, src)
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint s = src[i];
- uint d = dest[i];
- dest[i] = INTERPOLATE_PIXEL_255(d, qAlpha(s), s, qAlpha(~d));
- }
- } else {
- int cia = 255 - const_alpha;
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint s = BYTE_MUL(src[i], const_alpha);
- uint d = dest[i];
- uint a = qAlpha(s) + cia;
- dest[i] = INTERPOLATE_PIXEL_255(d, a, s, qAlpha(~d));
- }
- }
-}
-
-/*
- result = d*sia + s*dia
- dest = d*sia*ca + s*dia*ca + d *cia
- = s*ca * dia + d * (sia*ca + cia)
- = s*ca * dia + d * (1 - sa*ca)
-*/
-void QT_FASTCALL comp_func_solid_XOR(uint *dest, int length, uint color, uint const_alpha)
-{
- if (const_alpha != 255)
- color = BYTE_MUL(color, const_alpha);
- uint sia = qAlpha(~color);
-
- PRELOAD_INIT(dest)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- uint d = dest[i];
- dest[i] = INTERPOLATE_PIXEL_255(color, qAlpha(~d), d, sia);
- }
-}
-
-void QT_FASTCALL comp_func_XOR(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
-{
- PRELOAD_INIT2(dest, src)
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint d = dest[i];
- uint s = src[i];
- dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(~d), d, qAlpha(~s));
- }
- } else {
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint d = dest[i];
- uint s = BYTE_MUL(src[i], const_alpha);
- dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(~d), d, qAlpha(~s));
- }
- }
-}
-
-struct QFullCoverage {
- inline void store(uint *dest, const uint src) const
- {
- *dest = src;
- }
-};
-
-struct QPartialCoverage {
- inline QPartialCoverage(uint const_alpha)
- : ca(const_alpha)
- , ica(255 - const_alpha)
- {
- }
-
- inline void store(uint *dest, const uint src) const
- {
- *dest = INTERPOLATE_PIXEL_255(src, ca, *dest, ica);
- }
-
-private:
- const uint ca;
- const uint ica;
-};
-
-static inline int mix_alpha(int da, int sa)
-{
- return 255 - ((255 - sa) * (255 - da) >> 8);
-}
-
-/*
- Dca' = Sca.Da + Dca.Sa + Sca.(1 - Da) + Dca.(1 - Sa)
- = Sca + Dca
-*/
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Plus_impl(uint *dest, int length, uint color, const T &coverage)
-{
- uint s = color;
-
- PRELOAD_INIT(dest)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- uint d = dest[i];
- d = comp_func_Plus_one_pixel(d, s);
- coverage.store(&dest[i], d);
- }
-}
-
-void QT_FASTCALL comp_func_solid_Plus(uint *dest, int length, uint color, uint const_alpha)
-{
- if (const_alpha == 255)
- comp_func_solid_Plus_impl(dest, length, color, QFullCoverage());
- else
- comp_func_solid_Plus_impl(dest, length, color, QPartialCoverage(const_alpha));
-}
-
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Plus_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
-{
- PRELOAD_INIT2(dest, src)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint d = dest[i];
- uint s = src[i];
-
- d = comp_func_Plus_one_pixel(d, s);
-
- coverage.store(&dest[i], d);
- }
-}
-
-void QT_FASTCALL comp_func_Plus(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
-{
- if (const_alpha == 255)
- comp_func_Plus_impl(dest, src, length, QFullCoverage());
- else
- comp_func_Plus_impl(dest, src, length, QPartialCoverage(const_alpha));
-}
-
-/*
- Dca' = Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa)
-*/
-static inline int multiply_op(int dst, int src, int da, int sa)
-{
- return qt_div_255(src * dst + src * (255 - da) + dst * (255 - sa));
-}
-
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Multiply_impl(uint *dest, int length, uint color, const T &coverage)
-{
- int sa = qAlpha(color);
- int sr = qRed(color);
- int sg = qGreen(color);
- int sb = qBlue(color);
-
- PRELOAD_INIT(dest)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- uint d = dest[i];
- int da = qAlpha(d);
-
-#define OP(a, b) multiply_op(a, b, da, sa)
- int r = OP( qRed(d), sr);
- int b = OP( qBlue(d), sb);
- int g = OP(qGreen(d), sg);
- int a = mix_alpha(da, sa);
-#undef OP
-
- coverage.store(&dest[i], qRgba(r, g, b, a));
- }
-}
-
-void QT_FASTCALL comp_func_solid_Multiply(uint *dest, int length, uint color, uint const_alpha)
-{
- if (const_alpha == 255)
- comp_func_solid_Multiply_impl(dest, length, color, QFullCoverage());
- else
- comp_func_solid_Multiply_impl(dest, length, color, QPartialCoverage(const_alpha));
-}
-
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Multiply_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
-{
- PRELOAD_INIT2(dest, src)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint d = dest[i];
- uint s = src[i];
-
- int da = qAlpha(d);
- int sa = qAlpha(s);
-
-#define OP(a, b) multiply_op(a, b, da, sa)
- int r = OP( qRed(d), qRed(s));
- int b = OP( qBlue(d), qBlue(s));
- int g = OP(qGreen(d), qGreen(s));
- int a = mix_alpha(da, sa);
-#undef OP
-
- coverage.store(&dest[i], qRgba(r, g, b, a));
- }
-}
-
-void QT_FASTCALL comp_func_Multiply(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
-{
- if (const_alpha == 255)
- comp_func_Multiply_impl(dest, src, length, QFullCoverage());
- else
- comp_func_Multiply_impl(dest, src, length, QPartialCoverage(const_alpha));
-}
-
-/*
- Dca' = (Sca.Da + Dca.Sa - Sca.Dca) + Sca.(1 - Da) + Dca.(1 - Sa)
- = Sca + Dca - Sca.Dca
-*/
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Screen_impl(uint *dest, int length, uint color, const T &coverage)
-{
- int sa = qAlpha(color);
- int sr = qRed(color);
- int sg = qGreen(color);
- int sb = qBlue(color);
-
- PRELOAD_INIT(dest)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- uint d = dest[i];
- int da = qAlpha(d);
-
-#define OP(a, b) 255 - qt_div_255((255-a) * (255-b))
- int r = OP( qRed(d), sr);
- int b = OP( qBlue(d), sb);
- int g = OP(qGreen(d), sg);
- int a = mix_alpha(da, sa);
-#undef OP
-
- coverage.store(&dest[i], qRgba(r, g, b, a));
- }
-}
-
-void QT_FASTCALL comp_func_solid_Screen(uint *dest, int length, uint color, uint const_alpha)
-{
- if (const_alpha == 255)
- comp_func_solid_Screen_impl(dest, length, color, QFullCoverage());
- else
- comp_func_solid_Screen_impl(dest, length, color, QPartialCoverage(const_alpha));
-}
-
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Screen_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
-{
- PRELOAD_INIT2(dest, src)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint d = dest[i];
- uint s = src[i];
-
- int da = qAlpha(d);
- int sa = qAlpha(s);
-
-#define OP(a, b) 255 - (((255-a) * (255-b)) >> 8)
- int r = OP( qRed(d), qRed(s));
- int b = OP( qBlue(d), qBlue(s));
- int g = OP(qGreen(d), qGreen(s));
- int a = mix_alpha(da, sa);
-#undef OP
-
- coverage.store(&dest[i], qRgba(r, g, b, a));
- }
-}
-
-void QT_FASTCALL comp_func_Screen(uint *dest, const uint *src, int length, uint const_alpha)
-{
- if (const_alpha == 255)
- comp_func_Screen_impl(dest, src, length, QFullCoverage());
- else
- comp_func_Screen_impl(dest, src, length, QPartialCoverage(const_alpha));
-}
-
-/*
- if 2.Dca < Da
- Dca' = 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa)
- otherwise
- Dca' = Sa.Da - 2.(Da - Dca).(Sa - Sca) + Sca.(1 - Da) + Dca.(1 - Sa)
-*/
-static inline int overlay_op(int dst, int src, int da, int sa)
-{
- const int temp = src * (255 - da) + dst * (255 - sa);
- if (2 * dst < da)
- return qt_div_255(2 * src * dst + temp);
- else
- return qt_div_255(sa * da - 2 * (da - dst) * (sa - src) + temp);
-}
-
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Overlay_impl(uint *dest, int length, uint color, const T &coverage)
-{
- int sa = qAlpha(color);
- int sr = qRed(color);
- int sg = qGreen(color);
- int sb = qBlue(color);
-
- PRELOAD_INIT(dest)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- uint d = dest[i];
- int da = qAlpha(d);
-
-#define OP(a, b) overlay_op(a, b, da, sa)
- int r = OP( qRed(d), sr);
- int b = OP( qBlue(d), sb);
- int g = OP(qGreen(d), sg);
- int a = mix_alpha(da, sa);
-#undef OP
-
- coverage.store(&dest[i], qRgba(r, g, b, a));
- }
-}
-
-void QT_FASTCALL comp_func_solid_Overlay(uint *dest, int length, uint color, uint const_alpha)
-{
- if (const_alpha == 255)
- comp_func_solid_Overlay_impl(dest, length, color, QFullCoverage());
- else
- comp_func_solid_Overlay_impl(dest, length, color, QPartialCoverage(const_alpha));
-}
-
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Overlay_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
-{
- PRELOAD_INIT2(dest, src)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint d = dest[i];
- uint s = src[i];
-
- int da = qAlpha(d);
- int sa = qAlpha(s);
-
-#define OP(a, b) overlay_op(a, b, da, sa)
- int r = OP( qRed(d), qRed(s));
- int b = OP( qBlue(d), qBlue(s));
- int g = OP(qGreen(d), qGreen(s));
- int a = mix_alpha(da, sa);
-#undef OP
-
- coverage.store(&dest[i], qRgba(r, g, b, a));
- }
-}
-
-void QT_FASTCALL comp_func_Overlay(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
-{
- if (const_alpha == 255)
- comp_func_Overlay_impl(dest, src, length, QFullCoverage());
- else
- comp_func_Overlay_impl(dest, src, length, QPartialCoverage(const_alpha));
-}
-
-/*
- Dca' = min(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa)
- Da' = Sa + Da - Sa.Da
-*/
-static inline int darken_op(int dst, int src, int da, int sa)
-{
- return qt_div_255(qMin(src * da, dst * sa) + src * (255 - da) + dst * (255 - sa));
-}
-
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Darken_impl(uint *dest, int length, uint color, const T &coverage)
-{
- int sa = qAlpha(color);
- int sr = qRed(color);
- int sg = qGreen(color);
- int sb = qBlue(color);
-
- PRELOAD_INIT(dest)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- uint d = dest[i];
- int da = qAlpha(d);
-
-#define OP(a, b) darken_op(a, b, da, sa)
- int r = OP( qRed(d), sr);
- int b = OP( qBlue(d), sb);
- int g = OP(qGreen(d), sg);
- int a = mix_alpha(da, sa);
-#undef OP
-
- coverage.store(&dest[i], qRgba(r, g, b, a));
- }
-}
-
-void QT_FASTCALL comp_func_solid_Darken(uint *dest, int length, uint color, uint const_alpha)
-{
- if (const_alpha == 255)
- comp_func_solid_Darken_impl(dest, length, color, QFullCoverage());
- else
- comp_func_solid_Darken_impl(dest, length, color, QPartialCoverage(const_alpha));
-}
-
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Darken_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
-{
- PRELOAD_INIT2(dest, src)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint d = dest[i];
- uint s = src[i];
-
- int da = qAlpha(d);
- int sa = qAlpha(s);
-
-#define OP(a, b) darken_op(a, b, da, sa)
- int r = OP( qRed(d), qRed(s));
- int b = OP( qBlue(d), qBlue(s));
- int g = OP(qGreen(d), qGreen(s));
- int a = mix_alpha(da, sa);
-#undef OP
-
- coverage.store(&dest[i], qRgba(r, g, b, a));
- }
-}
-
-void QT_FASTCALL comp_func_Darken(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
-{
- if (const_alpha == 255)
- comp_func_Darken_impl(dest, src, length, QFullCoverage());
- else
- comp_func_Darken_impl(dest, src, length, QPartialCoverage(const_alpha));
-}
-
-/*
- Dca' = max(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa)
- Da' = Sa + Da - Sa.Da
-*/
-static inline int lighten_op(int dst, int src, int da, int sa)
-{
- return qt_div_255(qMax(src * da, dst * sa) + src * (255 - da) + dst * (255 - sa));
-}
-
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Lighten_impl(uint *dest, int length, uint color, const T &coverage)
-{
- int sa = qAlpha(color);
- int sr = qRed(color);
- int sg = qGreen(color);
- int sb = qBlue(color);
-
- PRELOAD_INIT(dest)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- uint d = dest[i];
- int da = qAlpha(d);
-
-#define OP(a, b) lighten_op(a, b, da, sa)
- int r = OP( qRed(d), sr);
- int b = OP( qBlue(d), sb);
- int g = OP(qGreen(d), sg);
- int a = mix_alpha(da, sa);
-#undef OP
-
- coverage.store(&dest[i], qRgba(r, g, b, a));
- }
-}
-
-void QT_FASTCALL comp_func_solid_Lighten(uint *dest, int length, uint color, uint const_alpha)
-{
- if (const_alpha == 255)
- comp_func_solid_Lighten_impl(dest, length, color, QFullCoverage());
- else
- comp_func_solid_Lighten_impl(dest, length, color, QPartialCoverage(const_alpha));
-}
-
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Lighten_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
-{
- PRELOAD_INIT2(dest, src)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint d = dest[i];
- uint s = src[i];
-
- int da = qAlpha(d);
- int sa = qAlpha(s);
-
-#define OP(a, b) lighten_op(a, b, da, sa)
- int r = OP( qRed(d), qRed(s));
- int b = OP( qBlue(d), qBlue(s));
- int g = OP(qGreen(d), qGreen(s));
- int a = mix_alpha(da, sa);
-#undef OP
-
- coverage.store(&dest[i], qRgba(r, g, b, a));
- }
-}
-
-void QT_FASTCALL comp_func_Lighten(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
-{
- if (const_alpha == 255)
- comp_func_Lighten_impl(dest, src, length, QFullCoverage());
- else
- comp_func_Lighten_impl(dest, src, length, QPartialCoverage(const_alpha));
-}
-
-/*
- if Sca.Da + Dca.Sa >= Sa.Da
- Dca' = Sa.Da + Sca.(1 - Da) + Dca.(1 - Sa)
- otherwise
- Dca' = Dca.Sa/(1-Sca/Sa) + Sca.(1 - Da) + Dca.(1 - Sa)
-*/
-static inline int color_dodge_op(int dst, int src, int da, int sa)
-{
- const int sa_da = sa * da;
- const int dst_sa = dst * sa;
- const int src_da = src * da;
-
- const int temp = src * (255 - da) + dst * (255 - sa);
- if (src_da + dst_sa >= sa_da)
- return qt_div_255(sa_da + temp);
- else
- return qt_div_255(255 * dst_sa / (255 - 255 * src / sa) + temp);
-}
-
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_ColorDodge_impl(uint *dest, int length, uint color, const T &coverage)
-{
- int sa = qAlpha(color);
- int sr = qRed(color);
- int sg = qGreen(color);
- int sb = qBlue(color);
-
- PRELOAD_INIT(dest)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- uint d = dest[i];
- int da = qAlpha(d);
-
-#define OP(a,b) color_dodge_op(a, b, da, sa)
- int r = OP( qRed(d), sr);
- int b = OP( qBlue(d), sb);
- int g = OP(qGreen(d), sg);
- int a = mix_alpha(da, sa);
-#undef OP
-
- coverage.store(&dest[i], qRgba(r, g, b, a));
- }
-}
-
-void QT_FASTCALL comp_func_solid_ColorDodge(uint *dest, int length, uint color, uint const_alpha)
-{
- if (const_alpha == 255)
- comp_func_solid_ColorDodge_impl(dest, length, color, QFullCoverage());
- else
- comp_func_solid_ColorDodge_impl(dest, length, color, QPartialCoverage(const_alpha));
-}
-
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorDodge_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
-{
- PRELOAD_INIT2(dest, src)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint d = dest[i];
- uint s = src[i];
-
- int da = qAlpha(d);
- int sa = qAlpha(s);
-
-#define OP(a, b) color_dodge_op(a, b, da, sa)
- int r = OP( qRed(d), qRed(s));
- int b = OP( qBlue(d), qBlue(s));
- int g = OP(qGreen(d), qGreen(s));
- int a = mix_alpha(da, sa);
-#undef OP
-
- coverage.store(&dest[i], qRgba(r, g, b, a));
- }
-}
-
-void QT_FASTCALL comp_func_ColorDodge(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
-{
- if (const_alpha == 255)
- comp_func_ColorDodge_impl(dest, src, length, QFullCoverage());
- else
- comp_func_ColorDodge_impl(dest, src, length, QPartialCoverage(const_alpha));
-}
-
-/*
- if Sca.Da + Dca.Sa <= Sa.Da
- Dca' = Sca.(1 - Da) + Dca.(1 - Sa)
- otherwise
- Dca' = Sa.(Sca.Da + Dca.Sa - Sa.Da)/Sca + Sca.(1 - Da) + Dca.(1 - Sa)
-*/
-static inline int color_burn_op(int dst, int src, int da, int sa)
-{
- const int src_da = src * da;
- const int dst_sa = dst * sa;
- const int sa_da = sa * da;
-
- const int temp = src * (255 - da) + dst * (255 - sa);
-
- if (src == 0 || src_da + dst_sa <= sa_da)
- return qt_div_255(temp);
- return qt_div_255(sa * (src_da + dst_sa - sa_da) / src + temp);
-}
-
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_ColorBurn_impl(uint *dest, int length, uint color, const T &coverage)
-{
- int sa = qAlpha(color);
- int sr = qRed(color);
- int sg = qGreen(color);
- int sb = qBlue(color);
-
- PRELOAD_INIT(dest)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- uint d = dest[i];
- int da = qAlpha(d);
-
-#define OP(a, b) color_burn_op(a, b, da, sa)
- int r = OP( qRed(d), sr);
- int b = OP( qBlue(d), sb);
- int g = OP(qGreen(d), sg);
- int a = mix_alpha(da, sa);
-#undef OP
-
- coverage.store(&dest[i], qRgba(r, g, b, a));
- }
-}
-
-void QT_FASTCALL comp_func_solid_ColorBurn(uint *dest, int length, uint color, uint const_alpha)
-{
- if (const_alpha == 255)
- comp_func_solid_ColorBurn_impl(dest, length, color, QFullCoverage());
- else
- comp_func_solid_ColorBurn_impl(dest, length, color, QPartialCoverage(const_alpha));
-}
-
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorBurn_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
-{
- PRELOAD_INIT2(dest, src)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint d = dest[i];
- uint s = src[i];
-
- int da = qAlpha(d);
- int sa = qAlpha(s);
-
-#define OP(a, b) color_burn_op(a, b, da, sa)
- int r = OP( qRed(d), qRed(s));
- int b = OP( qBlue(d), qBlue(s));
- int g = OP(qGreen(d), qGreen(s));
- int a = mix_alpha(da, sa);
-#undef OP
-
- coverage.store(&dest[i], qRgba(r, g, b, a));
- }
-}
-
-void QT_FASTCALL comp_func_ColorBurn(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
-{
- if (const_alpha == 255)
- comp_func_ColorBurn_impl(dest, src, length, QFullCoverage());
- else
- comp_func_ColorBurn_impl(dest, src, length, QPartialCoverage(const_alpha));
-}
-
-/*
- if 2.Sca < Sa
- Dca' = 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa)
- otherwise
- Dca' = Sa.Da - 2.(Da - Dca).(Sa - Sca) + Sca.(1 - Da) + Dca.(1 - Sa)
-*/
-static inline uint hardlight_op(int dst, int src, int da, int sa)
-{
- const uint temp = src * (255 - da) + dst * (255 - sa);
-
- if (2 * src < sa)
- return qt_div_255(2 * src * dst + temp);
- else
- return qt_div_255(sa * da - 2 * (da - dst) * (sa - src) + temp);
-}
-
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_HardLight_impl(uint *dest, int length, uint color, const T &coverage)
-{
- int sa = qAlpha(color);
- int sr = qRed(color);
- int sg = qGreen(color);
- int sb = qBlue(color);
-
- PRELOAD_INIT(dest)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- uint d = dest[i];
- int da = qAlpha(d);
-
-#define OP(a, b) hardlight_op(a, b, da, sa)
- int r = OP( qRed(d), sr);
- int b = OP( qBlue(d), sb);
- int g = OP(qGreen(d), sg);
- int a = mix_alpha(da, sa);
-#undef OP
-
- coverage.store(&dest[i], qRgba(r, g, b, a));
- }
-}
-
-void QT_FASTCALL comp_func_solid_HardLight(uint *dest, int length, uint color, uint const_alpha)
-{
- if (const_alpha == 255)
- comp_func_solid_HardLight_impl(dest, length, color, QFullCoverage());
- else
- comp_func_solid_HardLight_impl(dest, length, color, QPartialCoverage(const_alpha));
-}
-
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_HardLight_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
-{
- PRELOAD_INIT2(dest, src)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint d = dest[i];
- uint s = src[i];
-
- int da = qAlpha(d);
- int sa = qAlpha(s);
-
-#define OP(a, b) hardlight_op(a, b, da, sa)
- int r = OP( qRed(d), qRed(s));
- int b = OP( qBlue(d), qBlue(s));
- int g = OP(qGreen(d), qGreen(s));
- int a = mix_alpha(da, sa);
-#undef OP
-
- coverage.store(&dest[i], qRgba(r, g, b, a));
- }
-}
-
-void QT_FASTCALL comp_func_HardLight(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
-{
- if (const_alpha == 255)
- comp_func_HardLight_impl(dest, src, length, QFullCoverage());
- else
- comp_func_HardLight_impl(dest, src, length, QPartialCoverage(const_alpha));
-}
-
-/*
- if 2.Sca <= Sa
- Dca' = Dca.(Sa + (2.Sca - Sa).(1 - Dca/Da)) + Sca.(1 - Da) + Dca.(1 - Sa)
- otherwise if 2.Sca > Sa and 4.Dca <= Da
- Dca' = Dca.Sa + Da.(2.Sca - Sa).(4.Dca/Da.(4.Dca/Da + 1).(Dca/Da - 1) + 7.Dca/Da) + Sca.(1 - Da) + Dca.(1 - Sa)
- otherwise if 2.Sca > Sa and 4.Dca > Da
- Dca' = Dca.Sa + Da.(2.Sca - Sa).((Dca/Da)^0.5 - Dca/Da) + Sca.(1 - Da) + Dca.(1 - Sa)
-*/
-static inline int soft_light_op(int dst, int src, int da, int sa)
-{
- const int src2 = src << 1;
- const int dst_np = da != 0 ? (255 * dst) / da : 0;
- const int temp = (src * (255 - da) + dst * (255 - sa)) * 255;
-
- if (src2 < sa)
- return (dst * (sa * 255 + (src2 - sa) * (255 - dst_np)) + temp) / 65025;
- else if (4 * dst <= da)
- return (dst * sa * 255 + da * (src2 - sa) * ((((16 * dst_np - 12 * 255) * dst_np + 3 * 65025) * dst_np) / 65025) + temp) / 65025;
- else {
- return (dst * sa * 255 + da * (src2 - sa) * (int(qSqrt(qreal(dst_np * 255))) - dst_np) + temp) / 65025;
- }
-}
-
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_SoftLight_impl(uint *dest, int length, uint color, const T &coverage)
-{
- int sa = qAlpha(color);
- int sr = qRed(color);
- int sg = qGreen(color);
- int sb = qBlue(color);
-
- PRELOAD_INIT(dest)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- uint d = dest[i];
- int da = qAlpha(d);
-
-#define OP(a, b) soft_light_op(a, b, da, sa)
- int r = OP( qRed(d), sr);
- int b = OP( qBlue(d), sb);
- int g = OP(qGreen(d), sg);
- int a = mix_alpha(da, sa);
-#undef OP
-
- coverage.store(&dest[i], qRgba(r, g, b, a));
- }
-}
-
-void QT_FASTCALL comp_func_solid_SoftLight(uint *dest, int length, uint color, uint const_alpha)
-{
- if (const_alpha == 255)
- comp_func_solid_SoftLight_impl(dest, length, color, QFullCoverage());
- else
- comp_func_solid_SoftLight_impl(dest, length, color, QPartialCoverage(const_alpha));
-}
-
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_SoftLight_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
-{
- PRELOAD_INIT2(dest, src)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint d = dest[i];
- uint s = src[i];
-
- int da = qAlpha(d);
- int sa = qAlpha(s);
-
-#define OP(a, b) soft_light_op(a, b, da, sa)
- int r = OP( qRed(d), qRed(s));
- int b = OP( qBlue(d), qBlue(s));
- int g = OP(qGreen(d), qGreen(s));
- int a = mix_alpha(da, sa);
-#undef OP
-
- coverage.store(&dest[i], qRgba(r, g, b, a));
- }
-}
-
-void QT_FASTCALL comp_func_SoftLight(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
-{
- if (const_alpha == 255)
- comp_func_SoftLight_impl(dest, src, length, QFullCoverage());
- else
- comp_func_SoftLight_impl(dest, src, length, QPartialCoverage(const_alpha));
-}
-
-/*
- Dca' = abs(Dca.Sa - Sca.Da) + Sca.(1 - Da) + Dca.(1 - Sa)
- = Sca + Dca - 2.min(Sca.Da, Dca.Sa)
-*/
-static inline int difference_op(int dst, int src, int da, int sa)
-{
- return src + dst - qt_div_255(2 * qMin(src * da, dst * sa));
-}
-
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Difference_impl(uint *dest, int length, uint color, const T &coverage)
-{
- int sa = qAlpha(color);
- int sr = qRed(color);
- int sg = qGreen(color);
- int sb = qBlue(color);
-
- PRELOAD_INIT(dest)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- uint d = dest[i];
- int da = qAlpha(d);
-
-#define OP(a, b) difference_op(a, b, da, sa)
- int r = OP( qRed(d), sr);
- int b = OP( qBlue(d), sb);
- int g = OP(qGreen(d), sg);
- int a = mix_alpha(da, sa);
-#undef OP
-
- coverage.store(&dest[i], qRgba(r, g, b, a));
- }
-}
-
-void QT_FASTCALL comp_func_solid_Difference(uint *dest, int length, uint color, uint const_alpha)
-{
- if (const_alpha == 255)
- comp_func_solid_Difference_impl(dest, length, color, QFullCoverage());
- else
- comp_func_solid_Difference_impl(dest, length, color, QPartialCoverage(const_alpha));
-}
-
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Difference_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
-{
- PRELOAD_INIT2(dest, src)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint d = dest[i];
- uint s = src[i];
-
- int da = qAlpha(d);
- int sa = qAlpha(s);
-
-#define OP(a, b) difference_op(a, b, da, sa)
- int r = OP( qRed(d), qRed(s));
- int b = OP( qBlue(d), qBlue(s));
- int g = OP(qGreen(d), qGreen(s));
- int a = mix_alpha(da, sa);
-#undef OP
-
- coverage.store(&dest[i], qRgba(r, g, b, a));
- }
-}
-
-void QT_FASTCALL comp_func_Difference(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
-{
- if (const_alpha == 255)
- comp_func_Difference_impl(dest, src, length, QFullCoverage());
- else
- comp_func_Difference_impl(dest, src, length, QPartialCoverage(const_alpha));
-}
-
-/*
- Dca' = (Sca.Da + Dca.Sa - 2.Sca.Dca) + Sca.(1 - Da) + Dca.(1 - Sa)
-*/
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void QT_FASTCALL comp_func_solid_Exclusion_impl(uint *dest, int length, uint color, const T &coverage)
-{
- int sa = qAlpha(color);
- int sr = qRed(color);
- int sg = qGreen(color);
- int sb = qBlue(color);
-
- PRELOAD_INIT(dest)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND(dest)
- uint d = dest[i];
- int da = qAlpha(d);
-
-#define OP(a, b) (a + b - qt_div_255(2*(a*b)))
- int r = OP( qRed(d), sr);
- int b = OP( qBlue(d), sb);
- int g = OP(qGreen(d), sg);
- int a = mix_alpha(da, sa);
-#undef OP
-
- coverage.store(&dest[i], qRgba(r, g, b, a));
- }
-}
-
-void QT_FASTCALL comp_func_solid_Exclusion(uint *dest, int length, uint color, uint const_alpha)
-{
- if (const_alpha == 255)
- comp_func_solid_Exclusion_impl(dest, length, color, QFullCoverage());
- else
- comp_func_solid_Exclusion_impl(dest, length, color, QPartialCoverage(const_alpha));
-}
-
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Exclusion_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
-{
- PRELOAD_INIT2(dest, src)
- for (int i = 0; i < length; ++i) {
- PRELOAD_COND2(dest, src)
- uint d = dest[i];
- uint s = src[i];
-
- int da = qAlpha(d);
- int sa = qAlpha(s);
-
-#define OP(a, b) (a + b - ((a*b) >> 7))
- int r = OP( qRed(d), qRed(s));
- int b = OP( qBlue(d), qBlue(s));
- int g = OP(qGreen(d), qGreen(s));
- int a = mix_alpha(da, sa);
-#undef OP
-
- coverage.store(&dest[i], qRgba(r, g, b, a));
- }
-}
-
-void QT_FASTCALL comp_func_Exclusion(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
-{
- if (const_alpha == 255)
- comp_func_Exclusion_impl(dest, src, length, QFullCoverage());
- else
- comp_func_Exclusion_impl(dest, src, length, QPartialCoverage(const_alpha));
-}
-
-void QT_FASTCALL rasterop_solid_SourceOrDestination(uint *dest,
- int length,
- uint color,
- uint const_alpha)
-{
- Q_UNUSED(const_alpha);
- while (length--)
- *dest++ |= color;
-}
-
-void QT_FASTCALL rasterop_SourceOrDestination(uint *Q_DECL_RESTRICT dest,
- const uint *Q_DECL_RESTRICT src,
- int length,
- uint const_alpha)
-{
- Q_UNUSED(const_alpha);
- while (length--)
- *dest++ |= *src++;
-}
-
-void QT_FASTCALL rasterop_solid_SourceAndDestination(uint *dest,
- int length,
- uint color,
- uint const_alpha)
-{
- Q_UNUSED(const_alpha);
- color |= 0xff000000;
- while (length--)
- *dest++ &= color;
-}
-
-void QT_FASTCALL rasterop_SourceAndDestination(uint *Q_DECL_RESTRICT dest,
- const uint *Q_DECL_RESTRICT src,
- int length,
- uint const_alpha)
-{
- Q_UNUSED(const_alpha);
- while (length--) {
- *dest = (*src & *dest) | 0xff000000;
- ++dest; ++src;
- }
-}
-
-void QT_FASTCALL rasterop_solid_SourceXorDestination(uint *dest,
- int length,
- uint color,
- uint const_alpha)
-{
- Q_UNUSED(const_alpha);
- color &= 0x00ffffff;
- while (length--)
- *dest++ ^= color;
-}
-
-void QT_FASTCALL rasterop_SourceXorDestination(uint *Q_DECL_RESTRICT dest,
- const uint *Q_DECL_RESTRICT src,
- int length,
- uint const_alpha)
-{
- Q_UNUSED(const_alpha);
- while (length--) {
- *dest = (*src ^ *dest) | 0xff000000;
- ++dest; ++src;
- }
-}
-
-void QT_FASTCALL rasterop_solid_NotSourceAndNotDestination(uint *dest,
- int length,
- uint color,
- uint const_alpha)
-{
- Q_UNUSED(const_alpha);
- color = ~color;
- while (length--) {
- *dest = (color & ~(*dest)) | 0xff000000;
- ++dest;
- }
-}
-
-void QT_FASTCALL rasterop_NotSourceAndNotDestination(uint *Q_DECL_RESTRICT dest,
- const uint *Q_DECL_RESTRICT src,
- int length,
- uint const_alpha)
-{
- Q_UNUSED(const_alpha);
- while (length--) {
- *dest = (~(*src) & ~(*dest)) | 0xff000000;
- ++dest; ++src;
- }
-}
-
-void QT_FASTCALL rasterop_solid_NotSourceOrNotDestination(uint *dest,
- int length,
- uint color,
- uint const_alpha)
-{
- Q_UNUSED(const_alpha);
- color = ~color | 0xff000000;
- while (length--) {
- *dest = color | ~(*dest);
- ++dest;
- }
-}
-
-void QT_FASTCALL rasterop_NotSourceOrNotDestination(uint *Q_DECL_RESTRICT dest,
- const uint *Q_DECL_RESTRICT src,
- int length,
- uint const_alpha)
-{
- Q_UNUSED(const_alpha);
- while (length--) {
- *dest = ~(*src) | ~(*dest) | 0xff000000;
- ++dest; ++src;
- }
-}
-
-void QT_FASTCALL rasterop_solid_NotSourceXorDestination(uint *dest,
- int length,
- uint color,
- uint const_alpha)
-{
- Q_UNUSED(const_alpha);
- color = ~color & 0x00ffffff;
- while (length--) {
- *dest = color ^ (*dest);
- ++dest;
- }
-}
-
-void QT_FASTCALL rasterop_NotSourceXorDestination(uint *Q_DECL_RESTRICT dest,
- const uint *Q_DECL_RESTRICT src,
- int length,
- uint const_alpha)
-{
- Q_UNUSED(const_alpha);
- while (length--) {
- *dest = ((~(*src)) ^ (*dest)) | 0xff000000;
- ++dest; ++src;
- }
-}
-
-void QT_FASTCALL rasterop_solid_NotSource(uint *dest, int length,
- uint color, uint const_alpha)
-{
- Q_UNUSED(const_alpha);
- qt_memfill(dest, ~color | 0xff000000, length);
-}
-
-void QT_FASTCALL rasterop_NotSource(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src,
- int length, uint const_alpha)
-{
- Q_UNUSED(const_alpha);
- while (length--)
- *dest++ = ~(*src++) | 0xff000000;
-}
-
-void QT_FASTCALL rasterop_solid_NotSourceAndDestination(uint *dest,
- int length,
- uint color,
- uint const_alpha)
-{
- Q_UNUSED(const_alpha);
- color = ~color | 0xff000000;
- while (length--) {
- *dest = color & *dest;
- ++dest;
- }
-}
-
-void QT_FASTCALL rasterop_NotSourceAndDestination(uint *Q_DECL_RESTRICT dest,
- const uint *Q_DECL_RESTRICT src,
- int length,
- uint const_alpha)
-{
- Q_UNUSED(const_alpha);
- while (length--) {
- *dest = (~(*src) & *dest) | 0xff000000;
- ++dest; ++src;
- }
-}
-
-void QT_FASTCALL rasterop_solid_SourceAndNotDestination(uint *dest,
- int length,
- uint color,
- uint const_alpha)
-{
- Q_UNUSED(const_alpha);
- while (length--) {
- *dest = (color & ~(*dest)) | 0xff000000;
- ++dest;
- }
-}
-
-void QT_FASTCALL rasterop_SourceAndNotDestination(uint *Q_DECL_RESTRICT dest,
- const uint *Q_DECL_RESTRICT src,
- int length,
- uint const_alpha)
-{
- Q_UNUSED(const_alpha);
- while (length--) {
- *dest = (*src & ~(*dest)) | 0xff000000;
- ++dest; ++src;
- }
-}
-
-void QT_FASTCALL rasterop_NotSourceOrDestination(uint *Q_DECL_RESTRICT dest,
- const uint *Q_DECL_RESTRICT src,
- int length,
- uint const_alpha)
-{
- Q_UNUSED(const_alpha);
- while (length--) {
- *dest = (~(*src) | *dest) | 0xff000000;
- ++dest; ++src;
- }
-}
-
-void QT_FASTCALL rasterop_solid_NotSourceOrDestination(uint *Q_DECL_RESTRICT dest,
- int length,
- uint color,
- uint const_alpha)
+static const uint * QT_FASTCALL qt_fetch_conical_gradient(uint *buffer, const Operator *, const QSpanData *data,
+ int y, int x, int length)
{
- Q_UNUSED(const_alpha);
- color = ~color | 0xff000000;
- while (length--)
- *dest++ |= color;
+ return qt_fetch_conical_gradient_template<GradientBase32, uint>(buffer, data, y, x, length);
}
-void QT_FASTCALL rasterop_SourceOrNotDestination(uint *Q_DECL_RESTRICT dest,
- const uint *Q_DECL_RESTRICT src,
- int length,
- uint const_alpha)
+static const QRgba64 * QT_FASTCALL qt_fetch_conical_gradient_rgb64(QRgba64 *buffer, const Operator *, const QSpanData *data,
+ int y, int x, int length)
{
- Q_UNUSED(const_alpha);
- while (length--) {
- *dest = (*src | ~(*dest)) | 0xff000000;
- ++dest; ++src;
- }
+ return qt_fetch_conical_gradient_template<GradientBase64, QRgba64>(buffer, data, y, x, length);
}
-void QT_FASTCALL rasterop_solid_SourceOrNotDestination(uint *Q_DECL_RESTRICT dest,
- int length,
- uint color,
- uint const_alpha)
-{
- Q_UNUSED(const_alpha);
- while (length--) {
- *dest = (color | ~(*dest)) | 0xff000000;
- ++dest;
- }
-}
+extern CompositionFunctionSolid qt_functionForModeSolid_C[];
+extern CompositionFunctionSolid64 qt_functionForModeSolid64_C[];
-void QT_FASTCALL rasterop_ClearDestination(uint *Q_DECL_RESTRICT dest,
- const uint *Q_DECL_RESTRICT src,
- int length,
- uint const_alpha)
-{
- Q_UNUSED(src);
- comp_func_solid_SourceOver (dest, length, 0xff000000, const_alpha);
-}
-
-void QT_FASTCALL rasterop_solid_ClearDestination(uint *Q_DECL_RESTRICT dest,
- int length,
- uint color,
- uint const_alpha)
-{
- Q_UNUSED(color);
- comp_func_solid_SourceOver (dest, length, 0xff000000, const_alpha);
-}
-
-void QT_FASTCALL rasterop_SetDestination(uint *Q_DECL_RESTRICT dest,
- const uint *Q_DECL_RESTRICT src,
- int length,
- uint const_alpha)
-{
- Q_UNUSED(src);
- comp_func_solid_SourceOver (dest, length, 0xffffffff, const_alpha);
-}
-
-void QT_FASTCALL rasterop_solid_SetDestination(uint *Q_DECL_RESTRICT dest,
- int length,
- uint color,
- uint const_alpha)
-{
- Q_UNUSED(color);
- comp_func_solid_SourceOver (dest, length, 0xffffffff, const_alpha);
-}
-
-void QT_FASTCALL rasterop_NotDestination(uint *Q_DECL_RESTRICT dest,
- const uint *Q_DECL_RESTRICT src,
- int length,
- uint const_alpha)
-{
- Q_UNUSED(src);
- rasterop_solid_SourceXorDestination (dest, length, 0x00ffffff, const_alpha);
-}
-
-void QT_FASTCALL rasterop_solid_NotDestination(uint *Q_DECL_RESTRICT dest,
- int length,
- uint color,
- uint const_alpha)
-{
- Q_UNUSED(color);
- rasterop_solid_SourceXorDestination (dest, length, 0x00ffffff, const_alpha);
-}
-
-static CompositionFunctionSolid functionForModeSolid_C[] = {
- comp_func_solid_SourceOver,
- comp_func_solid_DestinationOver,
- comp_func_solid_Clear,
- comp_func_solid_Source,
- comp_func_solid_Destination,
- comp_func_solid_SourceIn,
- comp_func_solid_DestinationIn,
- comp_func_solid_SourceOut,
- comp_func_solid_DestinationOut,
- comp_func_solid_SourceAtop,
- comp_func_solid_DestinationAtop,
- comp_func_solid_XOR,
- comp_func_solid_Plus,
- comp_func_solid_Multiply,
- comp_func_solid_Screen,
- comp_func_solid_Overlay,
- comp_func_solid_Darken,
- comp_func_solid_Lighten,
- comp_func_solid_ColorDodge,
- comp_func_solid_ColorBurn,
- comp_func_solid_HardLight,
- comp_func_solid_SoftLight,
- comp_func_solid_Difference,
- comp_func_solid_Exclusion,
- rasterop_solid_SourceOrDestination,
- rasterop_solid_SourceAndDestination,
- rasterop_solid_SourceXorDestination,
- rasterop_solid_NotSourceAndNotDestination,
- rasterop_solid_NotSourceOrNotDestination,
- rasterop_solid_NotSourceXorDestination,
- rasterop_solid_NotSource,
- rasterop_solid_NotSourceAndDestination,
- rasterop_solid_SourceAndNotDestination,
- rasterop_solid_NotSourceOrDestination,
- rasterop_solid_SourceOrNotDestination,
- rasterop_solid_ClearDestination,
- rasterop_solid_SetDestination,
- rasterop_solid_NotDestination
-};
+static const CompositionFunctionSolid *functionForModeSolid = qt_functionForModeSolid_C;
+static const CompositionFunctionSolid64 *functionForModeSolid64 = qt_functionForModeSolid64_C;
-static const CompositionFunctionSolid *functionForModeSolid = functionForModeSolid_C;
-
-static CompositionFunction functionForMode_C[] = {
- comp_func_SourceOver,
- comp_func_DestinationOver,
- comp_func_Clear,
- comp_func_Source,
- comp_func_Destination,
- comp_func_SourceIn,
- comp_func_DestinationIn,
- comp_func_SourceOut,
- comp_func_DestinationOut,
- comp_func_SourceAtop,
- comp_func_DestinationAtop,
- comp_func_XOR,
- comp_func_Plus,
- comp_func_Multiply,
- comp_func_Screen,
- comp_func_Overlay,
- comp_func_Darken,
- comp_func_Lighten,
- comp_func_ColorDodge,
- comp_func_ColorBurn,
- comp_func_HardLight,
- comp_func_SoftLight,
- comp_func_Difference,
- comp_func_Exclusion,
- rasterop_SourceOrDestination,
- rasterop_SourceAndDestination,
- rasterop_SourceXorDestination,
- rasterop_NotSourceAndNotDestination,
- rasterop_NotSourceOrNotDestination,
- rasterop_NotSourceXorDestination,
- rasterop_NotSource,
- rasterop_NotSourceAndDestination,
- rasterop_SourceAndNotDestination,
- rasterop_NotSourceOrDestination,
- rasterop_SourceOrNotDestination,
- rasterop_ClearDestination,
- rasterop_SetDestination,
- rasterop_NotDestination
-};
+extern CompositionFunction qt_functionForMode_C[];
+extern CompositionFunction64 qt_functionForMode64_C[];
-static const CompositionFunction *functionForMode = functionForMode_C;
+static const CompositionFunction *functionForMode = qt_functionForMode_C;
+static const CompositionFunction64 *functionForMode64 = qt_functionForMode64_C;
static TextureBlendType getBlendType(const QSpanData *data)
{
@@ -4280,26 +3742,34 @@ static inline Operator getOperator(const QSpanData *data, const QSpan *spans, in
switch(data->type) {
case QSpanData::Solid:
- solidSource = (qAlpha(data->solid.color) == 255);
+ solidSource = data->solid.color.isOpaque();
+ op.srcFetch = 0;
+ op.srcFetch64 = 0;
break;
case QSpanData::LinearGradient:
solidSource = !data->gradient.alphaColor;
getLinearGradientValues(&op.linear, data);
- op.src_fetch = qt_fetch_linear_gradient;
+ op.srcFetch = qt_fetch_linear_gradient;
+ op.srcFetch64 = qt_fetch_linear_gradient_rgb64;
break;
case QSpanData::RadialGradient:
solidSource = !data->gradient.alphaColor;
getRadialGradientValues(&op.radial, data);
- op.src_fetch = qt_fetch_radial_gradient;
+ op.srcFetch = qt_fetch_radial_gradient;
+ op.srcFetch64 = qt_fetch_radial_gradient_rgb64;
break;
case QSpanData::ConicalGradient:
solidSource = !data->gradient.alphaColor;
- op.src_fetch = qt_fetch_conical_gradient;
+ op.srcFetch = qt_fetch_conical_gradient;
+ op.srcFetch64 = qt_fetch_conical_gradient_rgb64;
break;
case QSpanData::Texture:
- op.src_fetch = sourceFetch[getBlendType(data)][data->texture.format];
solidSource = !data->texture.hasAlpha;
+ op.srcFetch = sourceFetch[getBlendType(data)][data->texture.format];
+ op.srcFetch64 = sourceFetch64[getBlendType(data)][data->texture.format];
+ break;
default:
+ Q_UNREACHABLE();
break;
}
@@ -4307,12 +3777,13 @@ static inline Operator getOperator(const QSpanData *data, const QSpan *spans, in
if (op.mode == QPainter::CompositionMode_SourceOver && solidSource)
op.mode = QPainter::CompositionMode_Source;
- op.dest_fetch = destFetchProc[data->rasterBuffer->format];
+ op.destFetch = destFetchProc[data->rasterBuffer->format];
+ op.destFetch64 = destFetchProc64[data->rasterBuffer->format];
if (op.mode == QPainter::CompositionMode_Source) {
switch (data->rasterBuffer->format) {
case QImage::Format_RGB32:
case QImage::Format_ARGB32_Premultiplied:
- // don't clear dest_fetch as it sets up the pointer correctly to save one copy
+ // don't clear destFetch as it sets up the pointer correctly to save one copy
break;
default: {
if (data->type == QSpanData::Texture && data->texture.const_alpha != 256)
@@ -4327,15 +3798,18 @@ static inline Operator getOperator(const QSpanData *data, const QSpan *spans, in
++spans;
}
if (!alphaSpans)
- op.dest_fetch = 0;
+ op.destFetch = 0;
}
}
}
- op.dest_store = destStoreProc[data->rasterBuffer->format];
+ op.destStore = destStoreProc[data->rasterBuffer->format];
+ op.destStore64 = destStoreProc64[data->rasterBuffer->format];
op.funcSolid = functionForModeSolid[op.mode];
+ op.funcSolid64 = functionForModeSolid64[op.mode];
op.func = functionForMode[op.mode];
+ op.func64 = functionForMode64[op.mode];
return op;
}
@@ -4352,16 +3826,17 @@ void blend_color_generic(int count, const QSpan *spans, void *userData)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
uint buffer[buffer_size];
Operator op = getOperator(data, spans, count);
+ const uint color = data->solid.color.toArgb32();
while (count--) {
int x = spans->x;
int length = spans->len;
while (length) {
int l = qMin(buffer_size, length);
- uint *dest = op.dest_fetch ? op.dest_fetch(buffer, data->rasterBuffer, x, spans->y, l) : buffer;
- op.funcSolid(dest, l, data->solid.color, spans->coverage);
- if (op.dest_store)
- op.dest_store(data->rasterBuffer, x, spans->y, dest, l);
+ uint *dest = op.destFetch ? op.destFetch(buffer, data->rasterBuffer, x, spans->y, l) : buffer;
+ op.funcSolid(dest, l, color, spans->coverage);
+ if (op.destStore)
+ op.destStore(data->rasterBuffer, x, spans->y, dest, l);
length -= l;
x += l;
}
@@ -4374,15 +3849,16 @@ static void blend_color_argb(int count, const QSpan *spans, void *userData)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
Operator op = getOperator(data, spans, count);
+ const uint color = data->solid.color.toArgb32();
if (op.mode == QPainter::CompositionMode_Source) {
// inline for performance
while (count--) {
uint *target = ((uint *)data->rasterBuffer->scanLine(spans->y)) + spans->x;
if (spans->coverage == 255) {
- QT_MEMFILL_UINT(target, spans->len, data->solid.color);
+ QT_MEMFILL_UINT(target, spans->len, color);
} else {
- uint c = BYTE_MUL(data->solid.color, spans->coverage);
+ uint c = BYTE_MUL(color, spans->coverage);
int ialpha = 255 - spans->coverage;
for (int i = 0; i < spans->len; ++i)
target[i] = c + BYTE_MUL(target[i], ialpha);
@@ -4394,7 +3870,34 @@ static void blend_color_argb(int count, const QSpan *spans, void *userData)
while (count--) {
uint *target = ((uint *)data->rasterBuffer->scanLine(spans->y)) + spans->x;
- op.funcSolid(target, spans->len, data->solid.color, spans->coverage);
+ op.funcSolid(target, spans->len, color, spans->coverage);
+ ++spans;
+ }
+}
+
+void blend_color_generic_rgb64(int count, const QSpan *spans, void *userData)
+{
+ QSpanData *data = reinterpret_cast<QSpanData *>(userData);
+ Operator op = getOperator(data, spans, count);
+ if (!op.funcSolid64) {
+ qDebug("unsupported 64bit blend attempted");
+ return blend_color_generic(count, spans, userData);
+ }
+
+ QRgba64 buffer[buffer_size];
+ const QRgba64 color = data->solid.color;
+
+ while (count--) {
+ int x = spans->x;
+ int length = spans->len;
+ while (length) {
+ int l = qMin(buffer_size, length);
+ QRgba64 *dest = op.destFetch64(buffer, data->rasterBuffer, x, spans->y, l);
+ op.funcSolid64(dest, l, color, spans->coverage);
+ op.destStore64(data->rasterBuffer, x, spans->y, dest, l);
+ length -= l;
+ x += l;
+ }
++spans;
}
}
@@ -4409,13 +3912,12 @@ static void blend_color_rgb16(int count, const QSpan *spans, void *userData)
from qt_gradient_quint16 with minimal overhead.
*/
QPainter::CompositionMode mode = data->rasterBuffer->compositionMode;
- if (mode == QPainter::CompositionMode_SourceOver &&
- qAlpha(data->solid.color) == 255)
+ if (mode == QPainter::CompositionMode_SourceOver && data->solid.color.isOpaque())
mode = QPainter::CompositionMode_Source;
if (mode == QPainter::CompositionMode_Source) {
// inline for performance
- ushort c = qConvertRgb32To16(data->solid.color);
+ ushort c = data->solid.color.toRgb16();
while (count--) {
ushort *target = ((ushort *)data->rasterBuffer->scanLine(spans->y)) + spans->x;
if (spans->coverage == 255) {
@@ -4436,7 +3938,7 @@ static void blend_color_rgb16(int count, const QSpan *spans, void *userData)
if (mode == QPainter::CompositionMode_SourceOver) {
while (count--) {
- uint color = BYTE_MUL(data->solid.color, spans->coverage);
+ uint color = BYTE_MUL(data->solid.color.toArgb32(), spans->coverage);
int ialpha = qAlpha(~color);
ushort c = qConvertRgb32To16(color);
ushort *target = ((ushort *)data->rasterBuffer->scanLine(spans->y)) + spans->x;
@@ -4500,7 +4002,7 @@ void handleSpans(int count, const QSpan *spans, const QSpanData *data, T &handle
int process_length = l;
int process_x = x;
- const uint *src = handler.fetch(process_x, y, process_length);
+ const typename T::BlendType *src = handler.fetch(process_x, y, process_length);
int offset = 0;
while (l > 0) {
if (x == spans->x) // new span?
@@ -4525,8 +4027,10 @@ void handleSpans(int count, const QSpan *spans, const QSpanData *data, T &handle
}
}
+template<typename T>
struct QBlendBase
{
+ typedef T BlendType;
QBlendBase(QSpanData *d, Operator o)
: data(d)
, op(o)
@@ -4537,24 +4041,24 @@ struct QBlendBase
QSpanData *data;
Operator op;
- uint *dest;
+ BlendType *dest;
- uint buffer[buffer_size];
- uint src_buffer[buffer_size];
+ BlendType buffer[buffer_size];
+ BlendType src_buffer[buffer_size];
};
-class BlendSrcGeneric : public QBlendBase
+class BlendSrcGeneric : public QBlendBase<uint>
{
public:
BlendSrcGeneric(QSpanData *d, Operator o)
- : QBlendBase(d, o)
+ : QBlendBase<uint>(d, o)
{
}
const uint *fetch(int x, int y, int len)
{
- dest = op.dest_fetch ? op.dest_fetch(buffer, data->rasterBuffer, x, y, len) : buffer;
- return op.src_fetch(src_buffer, &op, data, y, x, len);
+ dest = op.destFetch ? op.destFetch(buffer, data->rasterBuffer, x, y, len) : buffer;
+ return op.srcFetch(src_buffer, &op, data, y, x, len);
}
void process(int, int, int len, int coverage, const uint *src, int offset)
@@ -4564,8 +4068,38 @@ public:
void store(int x, int y, int len)
{
- if (op.dest_store)
- op.dest_store(data->rasterBuffer, x, y, dest, len);
+ if (op.destStore)
+ op.destStore(data->rasterBuffer, x, y, dest, len);
+ }
+};
+
+class BlendSrcGenericRGB64 : public QBlendBase<QRgba64>
+{
+public:
+ BlendSrcGenericRGB64(QSpanData *d, Operator o)
+ : QBlendBase<QRgba64>(d, o)
+ {
+ }
+
+ bool isSupported() const
+ {
+ return op.func64 && op.destFetch64 && op.destStore64;
+ }
+
+ const QRgba64 *fetch(int x, int y, int len)
+ {
+ dest = op.destFetch64(buffer, data->rasterBuffer, x, y, len);
+ return op.srcFetch64(src_buffer, &op, data, y, x, len);
+ }
+
+ void process(int, int, int len, int coverage, const QRgba64 *src, int offset)
+ {
+ op.func64(dest + offset, src + offset, len, coverage);
+ }
+
+ void store(int x, int y, int len)
+ {
+ op.destStore64(data->rasterBuffer, x, y, dest, len);
}
};
@@ -4576,6 +4110,20 @@ static void blend_src_generic(int count, const QSpan *spans, void *userData)
handleSpans(count, spans, data, blend);
}
+static void blend_src_generic_rgb64(int count, const QSpan *spans, void *userData)
+{
+ QSpanData *data = reinterpret_cast<QSpanData *>(userData);
+ Operator op = getOperator(data, spans, count);
+ BlendSrcGenericRGB64 blend64(data, op);
+ if (blend64.isSupported())
+ handleSpans(count, spans, data, blend64);
+ else {
+ qDebug("blend_src_generic_rgb64: unsupported 64-bit blend attempted");
+ BlendSrcGeneric blend32(data, op);
+ handleSpans(count, spans, data, blend32);
+ }
+}
+
static void blend_untransformed_generic(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
@@ -4606,11 +4154,59 @@ static void blend_untransformed_generic(int count, const QSpan *spans, void *use
const int coverage = (spans->coverage * data->texture.const_alpha) >> 8;
while (length) {
int l = qMin(buffer_size, length);
- const uint *src = op.src_fetch(src_buffer, &op, data, sy, sx, l);
- uint *dest = op.dest_fetch ? op.dest_fetch(buffer, data->rasterBuffer, x, spans->y, l) : buffer;
+ const uint *src = op.srcFetch(src_buffer, &op, data, sy, sx, l);
+ uint *dest = op.destFetch ? op.destFetch(buffer, data->rasterBuffer, x, spans->y, l) : buffer;
op.func(dest, src, l, coverage);
- if (op.dest_store)
- op.dest_store(data->rasterBuffer, x, spans->y, dest, l);
+ if (op.destStore)
+ op.destStore(data->rasterBuffer, x, spans->y, dest, l);
+ x += l;
+ sx += l;
+ length -= l;
+ }
+ }
+ }
+ ++spans;
+ }
+}
+
+static void blend_untransformed_generic_rgb64(int count, const QSpan *spans, void *userData)
+{
+ QSpanData *data = reinterpret_cast<QSpanData *>(userData);
+
+ Operator op = getOperator(data, spans, count);
+ if (!op.func64) {
+ qWarning("Unsupported blend");
+ return blend_untransformed_generic(count, spans, userData);
+ }
+ QRgba64 buffer[buffer_size];
+ QRgba64 src_buffer[buffer_size];
+
+ const int image_width = data->texture.width;
+ const int image_height = data->texture.height;
+ int xoff = -qRound(-data->dx);
+ int yoff = -qRound(-data->dy);
+
+ while (count--) {
+ int x = spans->x;
+ int length = spans->len;
+ int sx = xoff + x;
+ int sy = yoff + spans->y;
+ if (sy >= 0 && sy < image_height && sx < image_width) {
+ if (sx < 0) {
+ x -= sx;
+ length += sx;
+ sx = 0;
+ }
+ if (sx + length > image_width)
+ length = image_width - sx;
+ if (length > 0) {
+ const int coverage = (spans->coverage * data->texture.const_alpha) >> 8;
+ while (length) {
+ int l = qMin(buffer_size, length);
+ const QRgba64 *src = op.srcFetch64(src_buffer, &op, data, sy, sx, l);
+ QRgba64 *dest = op.destFetch64(buffer, data->rasterBuffer, x, spans->y, l);
+ op.func64(dest, src, l, coverage);
+ op.destStore64(data->rasterBuffer, x, spans->y, dest, l);
x += l;
sx += l;
length -= l;
@@ -4799,11 +4395,62 @@ static void blend_tiled_generic(int count, const QSpan *spans, void *userData)
int l = qMin(image_width - sx, length);
if (buffer_size < l)
l = buffer_size;
- const uint *src = op.src_fetch(src_buffer, &op, data, sy, sx, l);
- uint *dest = op.dest_fetch ? op.dest_fetch(buffer, data->rasterBuffer, x, spans->y, l) : buffer;
+ const uint *src = op.srcFetch(src_buffer, &op, data, sy, sx, l);
+ uint *dest = op.destFetch ? op.destFetch(buffer, data->rasterBuffer, x, spans->y, l) : buffer;
op.func(dest, src, l, coverage);
- if (op.dest_store)
- op.dest_store(data->rasterBuffer, x, spans->y, dest, l);
+ if (op.destStore)
+ op.destStore(data->rasterBuffer, x, spans->y, dest, l);
+ x += l;
+ sx += l;
+ length -= l;
+ if (sx >= image_width)
+ sx = 0;
+ }
+ ++spans;
+ }
+}
+
+static void blend_tiled_generic_rgb64(int count, const QSpan *spans, void *userData)
+{
+ QSpanData *data = reinterpret_cast<QSpanData *>(userData);
+
+ Operator op = getOperator(data, spans, count);
+ if (!op.func64) {
+ qDebug("unsupported rgb64 blend");
+ return blend_tiled_generic(count, spans, userData);
+ }
+ QRgba64 buffer[buffer_size];
+ QRgba64 src_buffer[buffer_size];
+
+ const int image_width = data->texture.width;
+ const int image_height = data->texture.height;
+ int xoff = -qRound(-data->dx) % image_width;
+ int yoff = -qRound(-data->dy) % image_height;
+
+ if (xoff < 0)
+ xoff += image_width;
+ if (yoff < 0)
+ yoff += image_height;
+
+ while (count--) {
+ int x = spans->x;
+ int length = spans->len;
+ int sx = (xoff + spans->x) % image_width;
+ int sy = (spans->y + yoff) % image_height;
+ if (sx < 0)
+ sx += image_width;
+ if (sy < 0)
+ sy += image_height;
+
+ const int coverage = (spans->coverage * data->texture.const_alpha) >> 8;
+ while (length) {
+ int l = qMin(image_width - sx, length);
+ if (buffer_size < l)
+ l = buffer_size;
+ const QRgba64 *src = op.srcFetch64(src_buffer, &op, data, sy, sx, l);
+ QRgba64 *dest = op.destFetch64(buffer, data->rasterBuffer, x, spans->y, l);
+ op.func64(dest, src, l, coverage);
+ op.destStore64(data->rasterBuffer, x, spans->y, dest, l);
x += l;
sx += l;
length -= l;
@@ -5684,10 +5331,10 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats
blend_untransformed_generic,
blend_untransformed_generic,
blend_untransformed_generic,
- blend_untransformed_generic,
- blend_untransformed_generic,
- blend_untransformed_generic,
- blend_untransformed_generic,
+ blend_untransformed_generic_rgb64,
+ blend_untransformed_generic_rgb64,
+ blend_untransformed_generic_rgb64,
+ blend_untransformed_generic_rgb64,
blend_untransformed_generic,
blend_untransformed_generic,
},
@@ -5712,10 +5359,10 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats
blend_tiled_generic,
blend_tiled_generic,
blend_tiled_generic,
- blend_tiled_generic,
- blend_tiled_generic,
- blend_tiled_generic,
- blend_tiled_generic,
+ blend_tiled_generic_rgb64,
+ blend_tiled_generic_rgb64,
+ blend_tiled_generic_rgb64,
+ blend_tiled_generic_rgb64,
blend_tiled_generic,
blend_tiled_generic,
},
@@ -5740,10 +5387,10 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats
blend_src_generic,
blend_src_generic,
blend_src_generic,
- blend_src_generic,
- blend_src_generic,
- blend_src_generic,
- blend_src_generic,
+ blend_src_generic_rgb64,
+ blend_src_generic_rgb64,
+ blend_src_generic_rgb64,
+ blend_src_generic_rgb64,
blend_src_generic,
blend_src_generic,
},
@@ -5767,12 +5414,12 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats
blend_src_generic,
blend_src_generic,
blend_src_generic,
+ blend_src_generic_rgb64,
+ blend_src_generic_rgb64,
+ blend_src_generic_rgb64,
+ blend_src_generic_rgb64,
blend_src_generic,
blend_src_generic,
- blend_src_generic,
- blend_src_generic,
- blend_src_generic,
- blend_src_generic
},
// Bilinear
{
@@ -5795,10 +5442,10 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats
blend_src_generic,
blend_src_generic,
blend_src_generic,
- blend_src_generic,
- blend_src_generic,
- blend_src_generic,
- blend_src_generic,
+ blend_src_generic_rgb64,
+ blend_src_generic_rgb64,
+ blend_src_generic_rgb64,
+ blend_src_generic_rgb64,
blend_src_generic,
blend_src_generic,
},
@@ -5823,10 +5470,10 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats
blend_src_generic, // RGBX8888
blend_src_generic, // RGBA8888
blend_src_generic, // RGBA8888_Premultiplied
- blend_src_generic, // BGR30
- blend_src_generic, // A2BGR30_Premultiplied
- blend_src_generic, // RGB30
- blend_src_generic, // A2RGB30_Premultiplied
+ blend_src_generic_rgb64, // BGR30
+ blend_src_generic_rgb64, // A2BGR30_Premultiplied
+ blend_src_generic_rgb64, // RGB30
+ blend_src_generic_rgb64, // A2RGB30_Premultiplied
blend_src_generic, // Alpha8
blend_src_generic, // Grayscale8
}
@@ -5982,13 +5629,11 @@ static void qt_gradient_quint16(int count, const QSpan *spans, void *userData)
int yinc = int((linear.dy * data->m22 * gss) * FIXPT_SIZE);
int off = int((((linear.dy * (data->m22 * qreal(0.5) + data->dy) + linear.off) * gss) * FIXPT_SIZE));
- uint oldColor = data->solid.color;
+ QRgba64 oldColor = data->solid.color;
while (count--) {
int y = spans->y;
- quint32 color = qt_gradient_pixel_fixed(&data->gradient, yinc * y + off);
-
- data->solid.color = color;
+ data->solid.color = QRgba64::fromArgb32(qt_gradient_pixel_fixed(&data->gradient, yinc * y + off));
blend_color_rgb16(1, spans, userData);
++spans;
}
@@ -6000,39 +5645,49 @@ static void qt_gradient_quint16(int count, const QSpan *spans, void *userData)
}
inline static void qt_bitmapblit_argb32(QRasterBuffer *rasterBuffer,
- int x, int y, quint32 color,
+ int x, int y, const QRgba64 &color,
const uchar *map,
int mapWidth, int mapHeight, int mapStride)
{
- qt_bitmapblit_template<quint32>(rasterBuffer, x, y, color,
+ qt_bitmapblit_template<quint32>(rasterBuffer, x, y, color.toArgb32(),
map, mapWidth, mapHeight, mapStride);
}
inline static void qt_bitmapblit_rgba8888(QRasterBuffer *rasterBuffer,
- int x, int y, quint32 color,
+ int x, int y, const QRgba64 &color,
+ const uchar *map,
+ int mapWidth, int mapHeight, int mapStride)
+{
+ qt_bitmapblit_template<quint32>(rasterBuffer, x, y, ARGB2RGBA(color.toArgb32()),
+ map, mapWidth, mapHeight, mapStride);
+}
+
+template<QtPixelOrder PixelOrder>
+inline static void qt_bitmapblit_rgb30(QRasterBuffer *rasterBuffer,
+ int x, int y, const QRgba64 &color,
const uchar *map,
int mapWidth, int mapHeight, int mapStride)
{
- qt_bitmapblit_template<quint32>(rasterBuffer, x, y, ARGB2RGBA(color),
+ qt_bitmapblit_template<quint32>(rasterBuffer, x, y, qConvertRgb64ToRgb30<PixelOrder>(color),
map, mapWidth, mapHeight, mapStride);
}
inline static void qt_bitmapblit_quint16(QRasterBuffer *rasterBuffer,
- int x, int y, quint32 color,
+ int x, int y, const QRgba64 &color,
const uchar *map,
int mapWidth, int mapHeight, int mapStride)
{
- qt_bitmapblit_template<quint16>(rasterBuffer, x, y, qConvertRgb32To16(color),
+ qt_bitmapblit_template<quint16>(rasterBuffer, x, y, color.toRgb16(),
map, mapWidth, mapHeight, mapStride);
}
static void qt_alphamapblit_quint16(QRasterBuffer *rasterBuffer,
- int x, int y, quint32 color,
+ int x, int y, const QRgba64 &color,
const uchar *map,
int mapWidth, int mapHeight, int mapStride,
const QClipData *)
{
- const quint16 c = qConvertRgb32To16(color);
+ const quint16 c = color.toRgb16();
quint16 *dest = reinterpret_cast<quint16*>(rasterBuffer->scanLine(y)) + x;
const int destStride = rasterBuffer->bytesPerLine() / sizeof(quint16);
@@ -6130,7 +5785,7 @@ static inline void grayBlendPixel(quint32 *dst, int coverage, int sr, int sg, in
}
#endif
-static void qt_alphamapblit_argb32(QRasterBuffer *rasterBuffer,
+static void qt_alphamapblit_uint32(QRasterBuffer *rasterBuffer,
int x, int y, quint32 color,
const uchar *map,
int mapWidth, int mapHeight, int mapStride,
@@ -6226,28 +5881,38 @@ static void qt_alphamapblit_argb32(QRasterBuffer *rasterBuffer,
}
}
+
+static void qt_alphamapblit_argb32(QRasterBuffer *rasterBuffer,
+ int x, int y, const QRgba64 &color,
+ const uchar *map,
+ int mapWidth, int mapHeight, int mapStride,
+ const QClipData *clip)
+{
+ qt_alphamapblit_uint32(rasterBuffer, x, y, color.toArgb32(), map, mapWidth, mapHeight, mapStride, clip);
+}
+
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
static void qt_alphamapblit_rgba8888(QRasterBuffer *rasterBuffer,
- int x, int y, quint32 color,
+ int x, int y, const QRgba64 &color,
const uchar *map,
int mapWidth, int mapHeight, int mapStride,
const QClipData *clip)
{
- qt_alphamapblit_argb32(rasterBuffer, x, y, ARGB2RGBA(color), map, mapWidth, mapHeight, mapStride, clip);
+ qt_alphamapblit_uint32(rasterBuffer, x, y, ARGB2RGBA(color.toArgb32()), map, mapWidth, mapHeight, mapStride, clip);
}
#endif
static void qt_alphargbblit_argb32(QRasterBuffer *rasterBuffer,
- int x, int y, quint32 color,
+ int x, int y, const QRgba64 &color,
const uint *src, int mapWidth, int mapHeight, int srcStride,
const QClipData *clip)
{
- const quint32 c = color;
+ const quint32 c = color.toArgb32();
- int sr = qRed(color);
- int sg = qGreen(color);
- int sb = qBlue(color);
- int sa = qAlpha(color);
+ int sr = qRed(c);
+ int sg = qGreen(c);
+ int sb = qBlue(c);
+ int sa = qAlpha(c);
const QDrawHelperGammaTables *tables = QGuiApplicationPrivate::instance()->gammaTables();
if (!tables)
@@ -6314,58 +5979,67 @@ static void qt_alphargbblit_argb32(QRasterBuffer *rasterBuffer,
static void qt_rectfill_argb32(QRasterBuffer *rasterBuffer,
int x, int y, int width, int height,
- quint32 color)
+ const QRgba64 &color)
{
qt_rectfill<quint32>(reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
- color, x, y, width, height, rasterBuffer->bytesPerLine());
+ color.toArgb32(), x, y, width, height, rasterBuffer->bytesPerLine());
}
static void qt_rectfill_quint16(QRasterBuffer *rasterBuffer,
int x, int y, int width, int height,
- quint32 color)
+ const QRgba64 &color)
{
qt_rectfill<quint16>(reinterpret_cast<quint16 *>(rasterBuffer->buffer()),
- qConvertRgb32To16(color), x, y, width, height, rasterBuffer->bytesPerLine());
+ color.toRgb16(), x, y, width, height, rasterBuffer->bytesPerLine());
}
static void qt_rectfill_nonpremul_argb32(QRasterBuffer *rasterBuffer,
int x, int y, int width, int height,
- quint32 color)
+ const QRgba64 &color)
{
qt_rectfill<quint32>(reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
- qUnpremultiply(color), x, y, width, height, rasterBuffer->bytesPerLine());
+ color.unpremultiplied().toArgb32(), x, y, width, height, rasterBuffer->bytesPerLine());
}
static void qt_rectfill_rgba(QRasterBuffer *rasterBuffer,
int x, int y, int width, int height,
- quint32 color)
+ const QRgba64 &color)
{
qt_rectfill<quint32>(reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
- ARGB2RGBA(color), x, y, width, height, rasterBuffer->bytesPerLine());
+ ARGB2RGBA(color.toArgb32()), x, y, width, height, rasterBuffer->bytesPerLine());
}
static void qt_rectfill_nonpremul_rgba(QRasterBuffer *rasterBuffer,
int x, int y, int width, int height,
- quint32 color)
+ const QRgba64 &color)
{
qt_rectfill<quint32>(reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
- ARGB2RGBA(qUnpremultiply(color)), x, y, width, height, rasterBuffer->bytesPerLine());
+ ARGB2RGBA(color.unpremultiplied().toArgb32()), x, y, width, height, rasterBuffer->bytesPerLine());
+}
+
+template<QtPixelOrder PixelOrder>
+static void qt_rectfill_rgb30(QRasterBuffer *rasterBuffer,
+ int x, int y, int width, int height,
+ const QRgba64 &color)
+{
+ qt_rectfill<quint32>(reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
+ qConvertRgb64ToRgb30<PixelOrder>(color), x, y, width, height, rasterBuffer->bytesPerLine());
}
static void qt_rectfill_alpha(QRasterBuffer *rasterBuffer,
int x, int y, int width, int height,
- quint32 color)
+ const QRgba64 &color)
{
qt_rectfill<quint8>(reinterpret_cast<quint8 *>(rasterBuffer->buffer()),
- qAlpha(color), x, y, width, height, rasterBuffer->bytesPerLine());
+ color.alpha() >> 8, x, y, width, height, rasterBuffer->bytesPerLine());
}
static void qt_rectfill_gray(QRasterBuffer *rasterBuffer,
int x, int y, int width, int height,
- quint32 color)
+ const QRgba64 &color)
{
qt_rectfill<quint8>(reinterpret_cast<quint8 *>(rasterBuffer->buffer()),
- qGray(color), x, y, width, height, rasterBuffer->bytesPerLine());
+ qGray(color.toArgb32()), x, y, width, height, rasterBuffer->bytesPerLine());
}
// Map table for destination image format. Contains function pointers
@@ -6518,39 +6192,39 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
},
// Format_BGR30
{
- blend_color_generic,
- blend_src_generic,
- 0,
+ blend_color_generic_rgb64,
+ blend_src_generic_rgb64,
+ qt_bitmapblit_rgb30<PixelOrderBGR>,
0,
0,
- 0
+ qt_rectfill_rgb30<PixelOrderBGR>
},
// Format_A2BGR30_Premultiplied
{
- blend_color_generic,
- blend_src_generic,
- 0,
+ blend_color_generic_rgb64,
+ blend_src_generic_rgb64,
+ qt_bitmapblit_rgb30<PixelOrderBGR>,
0,
0,
- 0
+ qt_rectfill_rgb30<PixelOrderBGR>
},
// Format_RGB30
{
- blend_color_generic,
- blend_src_generic,
- 0,
+ blend_color_generic_rgb64,
+ blend_src_generic_rgb64,
+ qt_bitmapblit_rgb30<PixelOrderRGB>,
0,
0,
- 0
+ qt_rectfill_rgb30<PixelOrderRGB>
},
// Format_A2RGB30_Premultiplied
{
- blend_color_generic,
- blend_src_generic,
- 0,
+ blend_color_generic_rgb64,
+ blend_src_generic_rgb64,
+ qt_bitmapblit_rgb30<PixelOrderRGB>,
0,
0,
- 0
+ qt_rectfill_rgb30<PixelOrderRGB>
},
// Format_Alpha8
{
@@ -6619,6 +6293,11 @@ inline void qt_memfill_template(quint16 *dest, quint16 value, int count)
}
#endif
+void qt_memfill64(quint64 *dest, quint64 color, int count)
+{
+ qt_memfill_template<quint64>(dest, color, count);
+}
+
#if !defined(__SSE2__)
void qt_memfill16(quint16 *dest, quint16 color, int count)
{
@@ -6644,13 +6323,13 @@ void qt_memfill32(quint32 *dest, quint32 color, int count)
template<QtPixelOrder> const uint *QT_FASTCALL convertA2RGB30PMFromARGB32PM_sse4(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *);
#endif
-void qInitDrawhelperAsm()
+extern void qInitBlendFunctions();
+
+static void qInitDrawhelperFunctions()
{
- CompositionFunction *functionForModeAsm = 0;
- CompositionFunctionSolid *functionForModeSolidAsm = 0;
+ // Set up basic blend function tables.
+ qInitBlendFunctions();
- const uint features = qCpuFeatures();
- Q_UNUSED(features);
#ifdef __SSE2__
qDrawHelper[QImage::Format_RGB32].bitmapBlit = qt_bitmapblit32_sse2;
qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_sse2;
@@ -6695,7 +6374,7 @@ void qInitDrawhelperAsm()
qt_fetch_radial_gradient = qt_fetch_radial_gradient_sse2;
#ifdef QT_COMPILER_SUPPORTS_SSSE3
- if (features & SSSE3) {
+ if (qCpuHasFeature(SSSE3)) {
extern void qt_blend_argb32_on_argb32_ssse3(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
int w, int h,
@@ -6735,19 +6414,22 @@ void qInitDrawhelperAsm()
qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_avx2;
}
#endif
+ extern void QT_FASTCALL comp_func_SourceOver_sse2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
+ extern void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, uint color, uint const_alpha);
+ extern void QT_FASTCALL comp_func_Source_sse2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
+ extern void QT_FASTCALL comp_func_Plus_sse2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
+ qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_sse2;
+ qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_sse2;
+ qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_sse2;
+ qt_functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_sse2;
- functionForModeAsm = qt_functionForMode_SSE2;
- functionForModeSolidAsm = qt_functionForModeSolid_SSE2;
#endif // SSE2
-#if defined(__ARM_NEON__) && !defined(Q_OS_IOS)
+#if defined(__ARM_NEON__)
qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
- qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16_neon;
- qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB16] = qt_blend_rgb16_on_argb32_neon;
- qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_neon;
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon;
qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon;
@@ -6755,6 +6437,21 @@ void qInitDrawhelperAsm()
qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon;
#endif
+ qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = qt_blend_argb32_on_argb32_scanline_neon;
+ qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_neon;
+ qt_functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_neon;
+
+ extern const uint * QT_FASTCALL qt_fetch_radial_gradient_neon(uint *buffer, const Operator *op, const QSpanData *data,
+ int y, int x, int length);
+
+ qt_fetch_radial_gradient = qt_fetch_radial_gradient_neon;
+
+#if defined(ENABLE_PIXMAN_DRAWHELPERS)
+ // The RGB16 helpers are using Arm32 assemblythat has not been ported to AArch64
+ qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16_neon;
+ qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB16] = qt_blend_rgb16_on_argb32_neon;
+ qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_neon;
+
qScaleFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_rgb16_neon;
qScaleFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_scale_image_rgb16_on_rgb16_neon;
@@ -6763,19 +6460,13 @@ void qInitDrawhelperAsm()
qDrawHelper[QImage::Format_RGB16].alphamapBlit = qt_alphamapblit_quint16_neon;
- functionForMode_C[QPainter::CompositionMode_SourceOver] = qt_blend_argb32_on_argb32_scanline_neon;
- functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_neon;
- functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_neon;
destFetchProc[QImage::Format_RGB16] = qt_destFetchRGB16_neon;
destStoreProc[QImage::Format_RGB16] = qt_destStoreRGB16_neon;
qMemRotateFunctions[QImage::Format_RGB16][0] = qt_memrotate90_16_neon;
qMemRotateFunctions[QImage::Format_RGB16][2] = qt_memrotate270_16_neon;
+#endif
- extern const uint * QT_FASTCALL qt_fetch_radial_gradient_neon(uint *buffer, const Operator *op, const QSpanData *data,
- int y, int x, int length);
-
- qt_fetch_radial_gradient = qt_fetch_radial_gradient_neon;
#endif
#if defined(Q_PROCESSOR_MIPS_32) && defined(QT_COMPILER_SUPPORTS_MIPS_DSP)
@@ -6783,27 +6474,27 @@ void qInitDrawhelperAsm()
#endif // Q_PROCESSOR_MIPS_32
#if defined(QT_COMPILER_SUPPORTS_MIPS_DSP) || defined(QT_COMPILER_SUPPORTS_MIPS_DSPR2)
- if (features & (DSP | DSPR2)) {
+ if (qCpuHasFeature(DSP) && qCpuHasFeature(DSPR2)) {
// Composition functions are all DSP r1
- functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_asm_mips_dsp;
- functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_mips_dsp;
- functionForMode_C[QPainter::CompositionMode_DestinationOver] = comp_func_DestinationOver_mips_dsp;
- functionForMode_C[QPainter::CompositionMode_SourceIn] = comp_func_SourceIn_mips_dsp;
- functionForMode_C[QPainter::CompositionMode_DestinationIn] = comp_func_DestinationIn_mips_dsp;
- functionForMode_C[QPainter::CompositionMode_DestinationOut] = comp_func_DestinationOut_mips_dsp;
- functionForMode_C[QPainter::CompositionMode_SourceAtop] = comp_func_SourceAtop_mips_dsp;
- functionForMode_C[QPainter::CompositionMode_DestinationAtop] = comp_func_DestinationAtop_mips_dsp;
- functionForMode_C[QPainter::CompositionMode_Xor] = comp_func_XOR_mips_dsp;
- functionForMode_C[QPainter::CompositionMode_SourceOut] = comp_func_SourceOut_mips_dsp;
-
- functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_mips_dsp;
- functionForModeSolid_C[QPainter::CompositionMode_DestinationOver] = comp_func_solid_DestinationOver_mips_dsp;
- functionForModeSolid_C[QPainter::CompositionMode_SourceIn] = comp_func_solid_SourceIn_mips_dsp;
- functionForModeSolid_C[QPainter::CompositionMode_DestinationIn] = comp_func_solid_DestinationIn_mips_dsp;
- functionForModeSolid_C[QPainter::CompositionMode_SourceAtop] = comp_func_solid_SourceAtop_mips_dsp;
- functionForModeSolid_C[QPainter::CompositionMode_DestinationAtop] = comp_func_solid_DestinationAtop_mips_dsp;
- functionForModeSolid_C[QPainter::CompositionMode_Xor] = comp_func_solid_XOR_mips_dsp;
- functionForModeSolid_C[QPainter::CompositionMode_SourceOut] = comp_func_solid_SourceOut_mips_dsp;
+ qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_asm_mips_dsp;
+ qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_mips_dsp;
+ qt_functionForMode_C[QPainter::CompositionMode_DestinationOver] = comp_func_DestinationOver_mips_dsp;
+ qt_functionForMode_C[QPainter::CompositionMode_SourceIn] = comp_func_SourceIn_mips_dsp;
+ qt_functionForMode_C[QPainter::CompositionMode_DestinationIn] = comp_func_DestinationIn_mips_dsp;
+ qt_functionForMode_C[QPainter::CompositionMode_DestinationOut] = comp_func_DestinationOut_mips_dsp;
+ qt_functionForMode_C[QPainter::CompositionMode_SourceAtop] = comp_func_SourceAtop_mips_dsp;
+ qt_functionForMode_C[QPainter::CompositionMode_DestinationAtop] = comp_func_DestinationAtop_mips_dsp;
+ qt_functionForMode_C[QPainter::CompositionMode_Xor] = comp_func_XOR_mips_dsp;
+ qt_functionForMode_C[QPainter::CompositionMode_SourceOut] = comp_func_SourceOut_mips_dsp;
+
+ qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_mips_dsp;
+ qt_functionForModeSolid_C[QPainter::CompositionMode_DestinationOver] = comp_func_solid_DestinationOver_mips_dsp;
+ qt_functionForModeSolid_C[QPainter::CompositionMode_SourceIn] = comp_func_solid_SourceIn_mips_dsp;
+ qt_functionForModeSolid_C[QPainter::CompositionMode_DestinationIn] = comp_func_solid_DestinationIn_mips_dsp;
+ qt_functionForModeSolid_C[QPainter::CompositionMode_SourceAtop] = comp_func_solid_SourceAtop_mips_dsp;
+ qt_functionForModeSolid_C[QPainter::CompositionMode_DestinationAtop] = comp_func_solid_DestinationAtop_mips_dsp;
+ qt_functionForModeSolid_C[QPainter::CompositionMode_Xor] = comp_func_solid_XOR_mips_dsp;
+ qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOut] = comp_func_solid_SourceOut_mips_dsp;
qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_mips_dsp;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_mips_dsp;
@@ -6830,20 +6521,9 @@ void qInitDrawhelperAsm()
#endif // QT_COMPILER_SUPPORTS_MIPS_DSPR2
}
#endif // QT_COMPILER_SUPPORTS_MIPS_DSP || QT_COMPILER_SUPPORTS_MIPS_DSPR2
-
- if (functionForModeSolidAsm) {
- const int destinationMode = QPainter::CompositionMode_Destination;
- functionForModeSolidAsm[destinationMode] = functionForModeSolid_C[destinationMode];
-
- // use the default qdrawhelper implementation for the
- // extended composition modes
- for (int mode = 12; mode < 24; ++mode)
- functionForModeSolidAsm[mode] = functionForModeSolid_C[mode];
-
- functionForModeSolid = functionForModeSolidAsm;
- }
- if (functionForModeAsm)
- functionForMode = functionForModeAsm;
}
+// Ensure initialization if this object file is linked.
+Q_CONSTRUCTOR_FUNCTION(qInitDrawhelperFunctions);
+
QT_END_NAMESPACE
diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp
index 7e12e62151..e3f5d5bac7 100644
--- a/src/gui/painting/qdrawhelper_neon.cpp
+++ b/src/gui/painting/qdrawhelper_neon.cpp
@@ -31,21 +31,20 @@
**
****************************************************************************/
-#include <private/qdrawhelper_p.h>
+#include <private/qdrawhelper_neon_p.h>
#include <private/qblendfunctions_p.h>
#include <private/qmath_p.h>
#ifdef __ARM_NEON__
-#include <private/qdrawhelper_neon_p.h>
#include <private/qpaintengine_raster_p.h>
-#include <arm_neon.h>
QT_BEGIN_NAMESPACE
void qt_memfill32(quint32 *dest, quint32 value, int count)
{
const int epilogueSize = count % 16;
+#if !defined(Q_PROCESSOR_ARM_64)
if (count >= 16) {
quint32 *const neonEnd = dest + count - epilogueSize;
register uint32x4_t valueVector1 asm ("q0") = vdupq_n_u32(value);
@@ -60,6 +59,22 @@ void qt_memfill32(quint32 *dest, quint32 value, int count)
);
}
}
+#else
+ if (count >= 16) {
+ quint32 *const neonEnd = dest + count - epilogueSize;
+ register uint32x4_t valueVector1 asm ("v0") = vdupq_n_u32(value);
+ register uint32x4_t valueVector2 asm ("v1") = valueVector1;
+ while (dest != neonEnd) {
+ asm volatile (
+ "st2 { v0.4s, v1.4s }, [%[DST]], #32 \n\t"
+ "st2 { v0.4s, v1.4s }, [%[DST]], #32 \n\t"
+ : [DST]"+r" (dest)
+ : [VALUE1]"w"(valueVector1), [VALUE2]"w"(valueVector2)
+ : "memory"
+ );
+ }
+ }
+#endif
switch (epilogueSize)
{
@@ -120,6 +135,7 @@ static inline uint16x8_t qvsource_over_u16(uint16x8_t src16, uint16x8_t dst16, u
return vaddq_u16(src16, qvbyte_mul_u16(dst16, alpha16, half));
}
+#if defined(ENABLE_PIXMAN_DRAWHELPERS)
extern "C" void
pixman_composite_over_8888_0565_asm_neon (int32_t w,
int32_t h,
@@ -166,7 +182,6 @@ pixman_composite_src_0565_0565_asm_neon (int32_t w,
int32_t dst_stride,
uint16_t *src,
int32_t src_stride);
-
// qblendfunctions.cpp
void qt_blend_argb32_on_rgb16_const_alpha(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
@@ -206,6 +221,7 @@ void qt_blend_rgb16_on_rgb16(uchar *dst, int dbpl,
int w, int h,
int const_alpha);
+
template <int N>
static inline void scanLineBlit16(quint16 *dst, quint16 *src, int dstride)
{
@@ -331,11 +347,16 @@ void qt_blend_argb32_on_rgb16_neon(uchar *destPixels, int dbpl,
pixman_composite_over_8888_0565_asm_neon(w, h, dst, dbpl / 2, src, sbpl / 4);
}
+#endif
void qt_blend_argb32_on_argb32_scanline_neon(uint *dest, const uint *src, int length, uint const_alpha)
{
if (const_alpha == 255) {
+#if defined(ENABLE_PIXMAN_DRAWHELPERS)
pixman_composite_scanline_over_asm_neon(length, dest, src);
+#else
+ qt_blend_argb32_on_argb32_neon((uchar *)dest, 4 * length, (uchar *)src, 4 * length, length, 1, 256);
+#endif
} else {
qt_blend_argb32_on_argb32_neon((uchar *)dest, 4 * length, (uchar *)src, 4 * length, length, 1, (const_alpha * 256) / 255);
}
@@ -351,7 +372,51 @@ void qt_blend_argb32_on_argb32_neon(uchar *destPixels, int dbpl,
uint16x8_t half = vdupq_n_u16(0x80);
uint16x8_t full = vdupq_n_u16(0xff);
if (const_alpha == 256) {
+#if defined(ENABLE_PIXMAN_DRAWHELPERS)
pixman_composite_over_8888_8888_asm_neon(w, h, (uint32_t *)destPixels, dbpl / 4, (uint32_t *)srcPixels, sbpl / 4);
+#else
+ for (int y=0; y<h; ++y) {
+ int x = 0;
+ for (; x < w-3; x += 4) {
+ if (src[x] | src[x+1] | src[x+2] | src[x+3]) {
+ uint32x4_t src32 = vld1q_u32((uint32_t *)&src[x]);
+ uint32x4_t dst32 = vld1q_u32((uint32_t *)&dst[x]);
+
+ const uint8x16_t src8 = vreinterpretq_u8_u32(src32);
+ const uint8x16_t dst8 = vreinterpretq_u8_u32(dst32);
+
+ const uint8x8_t src8_low = vget_low_u8(src8);
+ const uint8x8_t dst8_low = vget_low_u8(dst8);
+
+ const uint8x8_t src8_high = vget_high_u8(src8);
+ const uint8x8_t dst8_high = vget_high_u8(dst8);
+
+ const uint16x8_t src16_low = vmovl_u8(src8_low);
+ const uint16x8_t dst16_low = vmovl_u8(dst8_low);
+
+ const uint16x8_t src16_high = vmovl_u8(src8_high);
+ const uint16x8_t dst16_high = vmovl_u8(dst8_high);
+
+ const uint16x8_t result16_low = qvsource_over_u16(src16_low, dst16_low, half, full);
+ const uint16x8_t result16_high = qvsource_over_u16(src16_high, dst16_high, half, full);
+
+ const uint32x2_t result32_low = vreinterpret_u32_u8(vmovn_u16(result16_low));
+ const uint32x2_t result32_high = vreinterpret_u32_u8(vmovn_u16(result16_high));
+
+ vst1q_u32((uint32_t *)&dst[x], vcombine_u32(result32_low, result32_high));
+ }
+ }
+ for (; x<w; ++x) {
+ uint s = src[x];
+ if (s >= 0xff000000)
+ dst[x] = s;
+ else if (s != 0)
+ dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s));
+ }
+ dst = (quint32 *)(((uchar *) dst) + dbpl);
+ src = (const quint32 *)(((const uchar *) src) + sbpl);
+ }
+#endif
} else if (const_alpha != 0) {
const_alpha = (const_alpha * 255) >> 8;
uint16x8_t const_alpha16 = vdupq_n_u16(const_alpha);
@@ -465,8 +530,9 @@ void qt_blend_rgb32_on_rgb32_neon(uchar *destPixels, int dbpl,
}
}
+#if defined(ENABLE_PIXMAN_DRAWHELPERS)
void qt_alphamapblit_quint16_neon(QRasterBuffer *rasterBuffer,
- int x, int y, quint32 color,
+ int x, int y, const QRgba64 &color,
const uchar *bitmap,
int mapWidth, int mapHeight, int mapStride,
const QClipData *)
@@ -475,8 +541,9 @@ void qt_alphamapblit_quint16_neon(QRasterBuffer *rasterBuffer,
const int destStride = rasterBuffer->bytesPerLine() / sizeof(quint16);
uchar *mask = const_cast<uchar *>(bitmap);
+ const uint c = color.toArgb32();
- pixman_composite_over_n_8_0565_asm_neon(mapWidth, mapHeight, dest, destStride, color, 0, mask, mapStride);
+ pixman_composite_over_n_8_0565_asm_neon(mapWidth, mapHeight, dest, destStride, c, 0, mask, mapStride);
}
extern "C" void blend_8_pixels_rgb16_on_rgb16_neon(quint16 *dst, const quint16 *src, int const_alpha);
@@ -704,6 +771,7 @@ void QT_FASTCALL qt_destStoreRGB16_neon(QRasterBuffer *rasterBuffer, int x, int
data[i + j] = dstBuffer[j];
}
}
+#endif
void QT_FASTCALL comp_func_solid_SourceOver_neon(uint *destPixels, int length, uint color, uint const_alpha)
{
@@ -755,16 +823,13 @@ void QT_FASTCALL comp_func_Plus_neon(uint *dst, const uint *src, int length, uin
uint *const neonEnd = end - 3;
while (dst < neonEnd) {
- asm volatile (
- "vld2.8 { d0, d1 }, [%[SRC]] !\n\t"
- "vld2.8 { d2, d3 }, [%[DST]]\n\t"
- "vqadd.u8 q0, q0, q1\n\t"
- "vst2.8 { d0, d1 }, [%[DST]] !\n\t"
- : [DST]"+r" (dst), [SRC]"+r" (src)
- :
- : "memory", "d0", "d1", "d2", "d3", "q0", "q1"
- );
- }
+ uint8x16_t vs = vld1q_u8((const uint8_t*)src);
+ const uint8x16_t vd = vld1q_u8((uint8_t*)dst);
+ vs = vqaddq_u8(vs, vd);
+ vst1q_u8((uint8_t*)dst, vs);
+ src += 4;
+ dst += 4;
+ };
while (dst != end) {
*dst = comp_func_Plus_one_pixel(*dst, *src);
@@ -803,6 +868,7 @@ void QT_FASTCALL comp_func_Plus_neon(uint *dst, const uint *src, int length, uin
}
}
+#if defined(ENABLE_PIXMAN_DRAWHELPERS)
static const int tileSize = 32;
extern "C" void qt_rotate90_16_neon(quint16 *dst, const quint16 *src, int sstride, int dstride, int count);
@@ -946,6 +1012,7 @@ void qt_memrotate270_16_neon(const uchar *srcPixels, int w, int h,
}
}
}
+#endif
class QSimdNeon
{
@@ -985,7 +1052,7 @@ public:
const uint * QT_FASTCALL qt_fetch_radial_gradient_neon(uint *buffer, const Operator *op, const QSpanData *data,
int y, int x, int length)
{
- return qt_fetch_radial_gradient_template<QRadialFetchSimd<QSimdNeon> >(buffer, op, data, y, x, length);
+ return qt_fetch_radial_gradient_template<QRadialFetchSimd<QSimdNeon>,uint>(buffer, op, data, y, x, length);
}
QT_END_NAMESPACE
diff --git a/src/gui/painting/qdrawhelper_neon_asm.S b/src/gui/painting/qdrawhelper_neon_asm.S
index 42a2084bbd..927a03f8ec 100644
--- a/src/gui/painting/qdrawhelper_neon_asm.S
+++ b/src/gui/painting/qdrawhelper_neon_asm.S
@@ -31,6 +31,8 @@
**
****************************************************************************/
+#if defined(ENABLE_PIXMAN_DRAWHELPERS)
+
/* Prevent the stack from becoming executable for no reason... */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
@@ -287,3 +289,5 @@ qt_rotate90_16_neon:
pop { r4-r11, pc }
.endfunc
+
+#endif \ No newline at end of file
diff --git a/src/gui/painting/qdrawhelper_neon_p.h b/src/gui/painting/qdrawhelper_neon_p.h
index bd030a8bf3..37e060f147 100644
--- a/src/gui/painting/qdrawhelper_neon_p.h
+++ b/src/gui/painting/qdrawhelper_neon_p.h
@@ -82,7 +82,7 @@ void qt_blend_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl,
int const_alpha);
void qt_alphamapblit_quint16_neon(QRasterBuffer *rasterBuffer,
- int x, int y, quint32 color,
+ int x, int y, const QRgba64 &color,
const uchar *bitmap,
int mapWidth, int mapHeight, int mapStride,
const QClipData *clip);
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index 73ff21812a..1ff19f4e04 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -50,6 +50,7 @@
#include "QtGui/qcolor.h"
#include "QtGui/qpainter.h"
#include "QtGui/qimage.h"
+#include "QtGui/qrgba64.h"
#ifndef QT_FT_BEGIN_HEADER
#define QT_FT_BEGIN_HEADER
#define QT_FT_END_HEADER
@@ -61,15 +62,12 @@ QT_BEGIN_NAMESPACE
#if defined(Q_CC_GNU)
# define Q_STATIC_TEMPLATE_FUNCTION static
-# define Q_ALWAYS_INLINE inline __attribute__((always_inline))
# define Q_DECL_RESTRICT __restrict__
#elif defined(Q_CC_MSVC)
# define Q_STATIC_TEMPLATE_FUNCTION static
-# define Q_ALWAYS_INLINE __forceinline
# define Q_DECL_RESTRICT __restrict
#else
# define Q_STATIC_TEMPLATE_FUNCTION static
-# define Q_ALWAYS_INLINE inline
# define Q_DECL_RESTRICT
#endif
@@ -99,25 +97,25 @@ class QRasterPaintEngineState;
typedef QT_FT_SpanFunc ProcessSpans;
typedef void (*BitmapBlitFunc)(QRasterBuffer *rasterBuffer,
- int x, int y, quint32 color,
+ int x, int y, const QRgba64 &color,
const uchar *bitmap,
int mapWidth, int mapHeight, int mapStride);
typedef void (*AlphamapBlitFunc)(QRasterBuffer *rasterBuffer,
- int x, int y, quint32 color,
+ int x, int y, const QRgba64 &color,
const uchar *bitmap,
int mapWidth, int mapHeight, int mapStride,
const QClipData *clip);
typedef void (*AlphaRGBBlitFunc)(QRasterBuffer *rasterBuffer,
- int x, int y, quint32 color,
+ int x, int y, const QRgba64 &color,
const uint *rgbmask,
int mapWidth, int mapHeight, int mapStride,
const QClipData *clip);
typedef void (*RectFillFunc)(QRasterBuffer *rasterBuffer,
int x, int y, int width, int height,
- quint32 color);
+ const QRgba64 &color);
typedef void (*SrcOverBlendFunc)(uchar *destPixels, int dbpl,
const uchar *src, int spbl,
@@ -158,11 +156,14 @@ extern MemRotateFunc qMemRotateFunctions[QImage::NImageFormats][3];
extern DrawHelper qDrawHelper[QImage::NImageFormats];
void qBlendTexture(int count, const QSpan *spans, void *userData);
+extern void qt_memfill64(quint64 *dest, quint64 value, int count);
extern void qt_memfill32(quint32 *dest, quint32 value, int count);
extern void qt_memfill16(quint16 *dest, quint16 value, int count);
typedef void (QT_FASTCALL *CompositionFunction)(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha);
+typedef void (QT_FASTCALL *CompositionFunction64)(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha);
typedef void (QT_FASTCALL *CompositionFunctionSolid)(uint *dest, int length, uint color, uint const_alpha);
+typedef void (QT_FASTCALL *CompositionFunctionSolid64)(QRgba64 *dest, int length, QRgba64 color, uint const_alpha);
struct LinearGradientValues
{
@@ -185,30 +186,38 @@ struct RadialGradientValues
struct Operator;
typedef uint* (QT_FASTCALL *DestFetchProc)(uint *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length);
+typedef QRgba64* (QT_FASTCALL *DestFetchProc64)(QRgba64 *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length);
typedef void (QT_FASTCALL *DestStoreProc)(QRasterBuffer *rasterBuffer, int x, int y, const uint *buffer, int length);
+typedef void (QT_FASTCALL *DestStoreProc64)(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length);
typedef const uint* (QT_FASTCALL *SourceFetchProc)(uint *buffer, const Operator *o, const QSpanData *data, int y, int x, int length);
+typedef const QRgba64* (QT_FASTCALL *SourceFetchProc64)(QRgba64 *buffer, const Operator *o, const QSpanData *data, int y, int x, int length);
struct Operator
{
QPainter::CompositionMode mode;
- DestFetchProc dest_fetch;
- DestStoreProc dest_store;
- SourceFetchProc src_fetch;
+ DestFetchProc destFetch;
+ DestStoreProc destStore;
+ SourceFetchProc srcFetch;
CompositionFunctionSolid funcSolid;
CompositionFunction func;
+
+ DestFetchProc64 destFetch64;
+ DestStoreProc64 destStore64;
+ SourceFetchProc64 srcFetch64;
+ CompositionFunctionSolid64 funcSolid64;
+ CompositionFunction64 func64;
+
union {
LinearGradientValues linear;
RadialGradientValues radial;
};
};
-void qInitDrawhelperAsm();
-
class QRasterPaintEngine;
struct QSolidData
{
- uint color;
+ QRgba64 color;
};
struct QLinearGradientData
@@ -259,7 +268,7 @@ struct QGradientData
#define GRADIENT_STOPTABLE_SIZE 1024
#define GRADIENT_STOPTABLE_SIZE_SHIFT 10
- uint* colorTable; //[GRADIENT_STOPTABLE_SIZE];
+ QRgba64* colorTable; //[GRADIENT_STOPTABLE_SIZE];
uint alphaColor : 1;
};
@@ -367,6 +376,12 @@ static inline uint qt_gradient_clamp(const QGradientData *data, int ipos)
static inline uint qt_gradient_pixel(const QGradientData *data, qreal pos)
{
int ipos = int(pos * (GRADIENT_STOPTABLE_SIZE - 1) + qreal(0.5));
+ return data->colorTable[qt_gradient_clamp(data, ipos)].toArgb32();
+}
+
+static inline const QRgba64& qt_gradient_pixel64(const QGradientData *data, qreal pos)
+{
+ int ipos = int(pos * (GRADIENT_STOPTABLE_SIZE - 1) + qreal(0.5));
return data->colorTable[qt_gradient_clamp(data, ipos)];
}
@@ -375,24 +390,24 @@ static inline qreal qRadialDeterminant(qreal a, qreal b, qreal c)
return (b * b) - (4 * a * c);
}
-template <class RadialFetchFunc> Q_STATIC_TEMPLATE_FUNCTION
-const uint * QT_FASTCALL qt_fetch_radial_gradient_template(uint *buffer, const Operator *op, const QSpanData *data,
- int y, int x, int length)
+template <class RadialFetchFunc, typename BlendType> static
+const BlendType * QT_FASTCALL qt_fetch_radial_gradient_template(BlendType *buffer, const Operator *op,
+ const QSpanData *data, int y, int x, int length)
{
// avoid division by zero
if (qFuzzyIsNull(op->radial.a)) {
- qt_memfill32(buffer, 0, length);
+ RadialFetchFunc::memfill(buffer, RadialFetchFunc::null(), length);
return buffer;
}
- const uint *b = buffer;
+ const BlendType *b = buffer;
qreal rx = data->m21 * (y + qreal(0.5))
+ data->dx + data->m11 * (x + qreal(0.5));
qreal ry = data->m22 * (y + qreal(0.5))
+ data->dy + data->m12 * (x + qreal(0.5));
bool affine = !data->m13 && !data->m23;
- uint *end = buffer + length;
+ BlendType *end = buffer + length;
if (affine) {
rx -= data->gradient.radial.focal.x;
ry -= data->gradient.radial.focal.y;
@@ -439,7 +454,7 @@ const uint * QT_FASTCALL qt_fetch_radial_gradient_template(uint *buffer, const O
qreal b = 2*(op->radial.dr*data->gradient.radial.focal.radius + gx*op->radial.dx + gy*op->radial.dy);
qreal det = qRadialDeterminant(op->radial.a, b, op->radial.sqrfr - (gx*gx + gy*gy));
- quint32 result = 0;
+ BlendType result = RadialFetchFunc::null();
if (det >= 0) {
qreal detSqrt = qSqrt(det);
@@ -449,7 +464,7 @@ const uint * QT_FASTCALL qt_fetch_radial_gradient_template(uint *buffer, const O
qreal s = qMax(s0, s1);
if (data->gradient.radial.focal.radius + op->radial.dr * s >= 0)
- result = qt_gradient_pixel(&data->gradient, s);
+ result = RadialFetchFunc::fetchSingle(data->gradient, s);
}
*buffer = result;
@@ -470,6 +485,15 @@ template <class Simd>
class QRadialFetchSimd
{
public:
+ static uint null() { return 0; }
+ static uint fetchSingle(const QGradientData& gradient, qreal v)
+ {
+ return qt_gradient_pixel(&gradient, v);
+ }
+ static void memfill(uint *buffer, uint fill, int length)
+ {
+ qt_memfill32(buffer, fill, length);
+ }
static void fetch(uint *buffer, uint *end, const Operator *op, const QSpanData *data, qreal det,
qreal delta_det, qreal delta_delta_det, qreal b, qreal delta_b)
{
@@ -526,7 +550,7 @@ public:
delta_det4_vec.v = Simd::v_add(delta_det4_vec.v, v_delta_delta_det16); \
b_vec.v = Simd::v_add(b_vec.v, v_delta_b4); \
for (int i = 0; i < 4; ++i) \
- *buffer++ = (extended_mask | v_buffer_mask.i[i]) & data->gradient.colorTable[index_vec.i[i]]; \
+ *buffer++ = (extended_mask | v_buffer_mask.i[i]) & data->gradient.colorTable[index_vec.i[i]].toArgb32(); \
}
#define FETCH_RADIAL_LOOP(FETCH_RADIAL_LOOP_CLAMP) \
@@ -562,7 +586,7 @@ static Q_ALWAYS_INLINE uint INTERPOLATE_PIXEL_255(uint x, uint a, uint y, uint b
return x;
}
-#if QT_POINTER_SIZE == 8 // 64-bit versions
+#if Q_PROCESSOR_WORDSIZE == 8 // 64-bit versions
static Q_ALWAYS_INLINE uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b) {
quint64 t = (((quint64(x)) | ((quint64(x)) << 24)) & 0x00ff00ff00ff00ff) * a;
@@ -680,19 +704,8 @@ static Q_ALWAYS_INLINE uint BYTE_MUL_RGB16_32(uint x, uint a) {
return t;
}
-static Q_ALWAYS_INLINE int qt_div_255(int x) { return (x + (x>>8) + 0x80) >> 8; }
-
-static Q_ALWAYS_INLINE uint BYTE_MUL_RGB30(uint x, uint a) {
- uint xa = x >> 30;
- uint xr = (x >> 20) & 0x3ff;
- uint xg = (x >> 10) & 0x3ff;
- uint xb = x & 0x3ff;
- xa = qt_div_255(xa * a);
- xr = qt_div_255(xr * a);
- xg = qt_div_255(xg * a);
- xb = qt_div_255(xb * a);
- return (xa << 30) | (xr << 20) | (xg << 10) | xb;
-}
+static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE int qt_div_255(int x) { return (x + (x>>8) + 0x80) >> 8; }
+static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_div_65535(uint x) { return (x + (x>>16) + 0x8000U) >> 16; }
static Q_ALWAYS_INLINE uint qAlphaRgb30(uint c)
{
@@ -723,6 +736,11 @@ inline quint24::operator uint() const
template <class T> Q_STATIC_TEMPLATE_FUNCTION
void qt_memfill(T *dest, T value, int count);
+template<> inline void qt_memfill(quint64 *dest, quint64 color, int count)
+{
+ qt_memfill64(dest, color, count);
+}
+
template<> inline void qt_memfill(quint32 *dest, quint32 color, int count)
{
qt_memfill32(dest, color, count);
@@ -862,6 +880,18 @@ inline QRgb qRepremultiply(QRgb p)
return qPremultiply(p);
}
+template<unsigned int Shift>
+inline QRgba64 qRepremultiply(QRgba64 p)
+{
+ const uint alpha = p.alpha();
+ if (alpha == 65535 || alpha == 0)
+ return p;
+ p = p.unpremultiplied();
+ Q_CONSTEXPR uint mult = 65535 / (65535 >> Shift);
+ p.setAlpha(mult * (alpha >> Shift));
+ return p.premultiplied();
+}
+
template<>
inline uint qConvertArgb32ToA2rgb30<PixelOrderBGR>(QRgb c)
{
@@ -924,6 +954,66 @@ inline QRgb qConvertA2rgb30ToArgb32<PixelOrderRGB>(uint c)
| ((c >> 2) & 0x000000ff);
}
+template<enum QtPixelOrder> inline QRgba64 qConvertA2rgb30ToRgb64(uint rgb);
+
+template<>
+inline QRgba64 qConvertA2rgb30ToRgb64<PixelOrderBGR>(uint rgb)
+{
+ quint16 alpha = rgb >> 30;
+ quint16 blue = (rgb >> 20) & 0x3ff;
+ quint16 green = (rgb >> 10) & 0x3ff;
+ quint16 red = rgb & 0x3ff;
+ // Expand the range.
+ alpha |= (alpha << 2);
+ alpha |= (alpha << 4);
+ alpha |= (alpha << 8);
+ red = (red << 6) | (red >> 4);
+ green = (green << 6) | (green >> 4);
+ blue = (blue << 6) | (blue >> 4);
+ return qRgba64(red, green, blue, alpha);
+}
+
+template<>
+inline QRgba64 qConvertA2rgb30ToRgb64<PixelOrderRGB>(uint rgb)
+{
+ quint16 alpha = rgb >> 30;
+ quint16 red = (rgb >> 20) & 0x3ff;
+ quint16 green = (rgb >> 10) & 0x3ff;
+ quint16 blue = rgb & 0x3ff;
+ // Expand the range.
+ alpha |= (alpha << 2);
+ alpha |= (alpha << 4);
+ alpha |= (alpha << 8);
+ red = (red << 6) | (red >> 4);
+ green = (green << 6) | (green >> 4);
+ blue = (blue << 6) | (blue >> 4);
+ return qRgba64(red, green, blue, alpha);
+}
+
+template<enum QtPixelOrder> inline unsigned int qConvertRgb64ToRgb30(QRgba64);
+
+template<>
+inline unsigned int qConvertRgb64ToRgb30<PixelOrderBGR>(QRgba64 c)
+{
+ c = qRepremultiply<14>(c);
+ const uint a = c.alpha() >> 14;
+ const uint r = c.red() >> 6;
+ const uint g = c.green() >> 6;
+ const uint b = c.blue() >> 6;
+ return (a << 30) | (b << 20) | (g << 10) | r;
+}
+
+template<>
+inline unsigned int qConvertRgb64ToRgb30<PixelOrderRGB>(QRgba64 c)
+{
+ c = qRepremultiply<14>(c);
+ const uint a = c.alpha() >> 14;
+ const uint r = c.red() >> 6;
+ const uint g = c.green() >> 6;
+ const uint b = c.blue() >> 6;
+ return (a << 30) | (r << 20) | (g << 10) | b;
+}
+
inline uint qRgbSwapRgb30(uint c)
{
const uint ag = c & 0xc00ffc00;
@@ -1001,7 +1091,7 @@ const uint qt_bayer_matrix[16][16] = {
((((argb >> 24) * alpha) >> 8) << 24) | (argb & 0x00ffffff)
-#if QT_POINTER_SIZE == 8 // 64-bit versions
+#if Q_PROCESSOR_WORDSIZE == 8 // 64-bit versions
#define AMIX(mask) (qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask)))
#define MIX(mask) (qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask)))
#else // 32 bits
@@ -1025,89 +1115,11 @@ inline int comp_func_Plus_one_pixel(uint d, const uint s)
#undef MIX
#undef AMIX
-// prototypes of all the composition functions
-void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL comp_func_DestinationOver(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha);
-void QT_FASTCALL comp_func_Source(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL comp_func_Destination(uint *, const uint *, int, uint);
-void QT_FASTCALL comp_func_SourceIn(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL comp_func_DestinationIn(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL comp_func_SourceOut(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL comp_func_DestinationOut(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL comp_func_SourceAtop(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL comp_func_DestinationAtop(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL comp_func_XOR(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL comp_func_Plus(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL comp_func_Multiply(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL comp_func_Screen(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL comp_func_Overlay(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL comp_func_Darken(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL comp_func_Lighten(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL comp_func_ColorDodge(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL comp_func_ColorBurn(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL comp_func_HardLight(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL comp_func_SoftLight(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL comp_func_Difference(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL comp_func_Exclusion(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL rasterop_SourceOrDestination(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL rasterop_SourceAndDestination(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL rasterop_SourceXorDestination(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL rasterop_NotSourceAndNotDestination(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL rasterop_NotSourceOrNotDestination(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL rasterop_NotSourceXorDestination(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL rasterop_NotSource(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL rasterop_NotSourceAndDestination(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL rasterop_SourceAndNotDestination(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL rasterop_NotSourceOrDestination(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL rasterop_SourceOrNotDestination(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL rasterop_ClearDestination(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL rasterop_SetDestination(uint *dest, const uint *src, int length, uint const_alpha);
-void QT_FASTCALL rasterop_NotDestination(uint *dest, const uint *src, int length, uint const_alpha);
-// prototypes of all the solid composition functions
-void QT_FASTCALL comp_func_solid_SourceOver(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL comp_func_solid_DestinationOver(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL comp_func_solid_Source(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL comp_func_solid_Destination(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL comp_func_solid_SourceIn(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL comp_func_solid_DestinationIn(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL comp_func_solid_SourceOut(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL comp_func_solid_DestinationOut(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL comp_func_solid_SourceAtop(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL comp_func_solid_DestinationAtop(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL comp_func_solid_XOR(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL comp_func_solid_Plus(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL comp_func_solid_Multiply(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL comp_func_solid_Screen(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL comp_func_solid_Overlay(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL comp_func_solid_Darken(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL comp_func_solid_Lighten(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL comp_func_solid_ColorDodge(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL comp_func_solid_ColorBurn(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL comp_func_solid_HardLight(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL comp_func_solid_SoftLight(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL comp_func_solid_Difference(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL comp_func_solid_Exclusion(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL rasterop_solid_SourceOrDestination(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL rasterop_solid_SourceAndDestination(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL rasterop_solid_SourceXorDestination(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL rasterop_solid_NotSourceAndNotDestination(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL rasterop_solid_NotSourceOrNotDestination(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL rasterop_solid_NotSourceXorDestination(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL rasterop_solid_NotSource(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL rasterop_solid_NotSourceAndDestination(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL rasterop_solid_SourceAndNotDestination(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL rasterop_solid_NotSourceOrDestination(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL rasterop_solid_SourceOrNotDestination(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL rasterop_solid_ClearDestination(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL rasterop_solid_SetDestination(uint *dest, int length, uint color, uint const_alpha);
-void QT_FASTCALL rasterop_solid_NotDestination(uint *dest, int length, uint color, uint const_alpha);
-
-
struct QPixelLayout;
typedef const uint *(QT_FASTCALL *ConvertFunc)(uint *buffer, const uint *src, int count,
const QPixelLayout *layout, const QRgb *clut);
+typedef const QRgba64 *(QT_FASTCALL *ConvertFunc64)(QRgba64 *buffer, const uint *src, int count,
+ const QPixelLayout *layout, const QRgb *clut);
struct QPixelLayout
{
@@ -1137,6 +1149,7 @@ struct QPixelLayout
ConvertFunc convertToARGB32PM;
ConvertFunc convertFromARGB32PM;
ConvertFunc convertFromRGB32;
+ ConvertFunc64 convertToARGB64PM;
};
typedef const uint *(QT_FASTCALL *FetchPixelsFunc)(uint *buffer, const uchar *src, int index, int count);
diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp
index 84eb3b7909..d7f3686e54 100644
--- a/src/gui/painting/qdrawhelper_sse2.cpp
+++ b/src/gui/painting/qdrawhelper_sse2.cpp
@@ -311,90 +311,6 @@ void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, u
}
}
-#ifndef QDRAWHELPER_AVX
-CompositionFunctionSolid qt_functionForModeSolid_SSE2[numCompositionFunctions] = {
- comp_func_solid_SourceOver_sse2,
- comp_func_solid_DestinationOver,
- comp_func_solid_Clear,
- comp_func_solid_Source,
- comp_func_solid_Destination,
- comp_func_solid_SourceIn,
- comp_func_solid_DestinationIn,
- comp_func_solid_SourceOut,
- comp_func_solid_DestinationOut,
- comp_func_solid_SourceAtop,
- comp_func_solid_DestinationAtop,
- comp_func_solid_XOR,
- comp_func_solid_Plus,
- comp_func_solid_Multiply,
- comp_func_solid_Screen,
- comp_func_solid_Overlay,
- comp_func_solid_Darken,
- comp_func_solid_Lighten,
- comp_func_solid_ColorDodge,
- comp_func_solid_ColorBurn,
- comp_func_solid_HardLight,
- comp_func_solid_SoftLight,
- comp_func_solid_Difference,
- comp_func_solid_Exclusion,
- rasterop_solid_SourceOrDestination,
- rasterop_solid_SourceAndDestination,
- rasterop_solid_SourceXorDestination,
- rasterop_solid_NotSourceAndNotDestination,
- rasterop_solid_NotSourceOrNotDestination,
- rasterop_solid_NotSourceXorDestination,
- rasterop_solid_NotSource,
- rasterop_solid_NotSourceAndDestination,
- rasterop_solid_SourceAndNotDestination,
- rasterop_solid_NotSourceOrDestination,
- rasterop_solid_SourceOrNotDestination,
- rasterop_solid_ClearDestination,
- rasterop_solid_SetDestination,
- rasterop_solid_NotDestination
-};
-
-CompositionFunction qt_functionForMode_SSE2[numCompositionFunctions] = {
- comp_func_SourceOver_sse2,
- comp_func_DestinationOver,
- comp_func_Clear,
- comp_func_Source_sse2,
- comp_func_Destination,
- comp_func_SourceIn,
- comp_func_DestinationIn,
- comp_func_SourceOut,
- comp_func_DestinationOut,
- comp_func_SourceAtop,
- comp_func_DestinationAtop,
- comp_func_XOR,
- comp_func_Plus_sse2,
- comp_func_Multiply,
- comp_func_Screen,
- comp_func_Overlay,
- comp_func_Darken,
- comp_func_Lighten,
- comp_func_ColorDodge,
- comp_func_ColorBurn,
- comp_func_HardLight,
- comp_func_SoftLight,
- comp_func_Difference,
- comp_func_Exclusion,
- rasterop_SourceOrDestination,
- rasterop_SourceAndDestination,
- rasterop_SourceXorDestination,
- rasterop_NotSourceAndNotDestination,
- rasterop_NotSourceOrNotDestination,
- rasterop_NotSourceXorDestination,
- rasterop_NotSource,
- rasterop_NotSourceAndDestination,
- rasterop_SourceAndNotDestination,
- rasterop_NotSourceOrDestination,
- rasterop_SourceOrNotDestination,
- rasterop_ClearDestination,
- rasterop_SetDestination,
- rasterop_NotDestination
-};
-#endif
-
void qt_memfill16(quint16 *dest, quint16 value, int count)
{
if (count < 3) {
@@ -417,7 +333,7 @@ void qt_memfill16(quint16 *dest, quint16 value, int count)
dest[count - 1] = value;
}
-void qt_bitmapblit32_sse2(QRasterBuffer *rasterBuffer, int x, int y,
+void qt_bitmapblit32_sse2_base(QRasterBuffer *rasterBuffer, int x, int y,
quint32 color,
const uchar *src, int width, int height, int stride)
{
@@ -468,18 +384,25 @@ void qt_bitmapblit32_sse2(QRasterBuffer *rasterBuffer, int x, int y,
}
}
+void qt_bitmapblit32_sse2(QRasterBuffer *rasterBuffer, int x, int y,
+ const QRgba64 &color,
+ const uchar *src, int width, int height, int stride)
+{
+ qt_bitmapblit32_sse2_base(rasterBuffer, x, y, color.toArgb32(), src, width, height, stride);
+}
+
void qt_bitmapblit8888_sse2(QRasterBuffer *rasterBuffer, int x, int y,
- quint32 color,
+ const QRgba64 &color,
const uchar *src, int width, int height, int stride)
{
- qt_bitmapblit32_sse2(rasterBuffer, x, y, ARGB2RGBA(color), src, width, height, stride);
+ qt_bitmapblit32_sse2_base(rasterBuffer, x, y, ARGB2RGBA(color.toArgb32()), src, width, height, stride);
}
void qt_bitmapblit16_sse2(QRasterBuffer *rasterBuffer, int x, int y,
- quint32 color,
+ const QRgba64 &color,
const uchar *src, int width, int height, int stride)
{
- const quint16 c = qConvertRgb32To16(color);
+ const quint16 c = qConvertRgb32To16(color.toArgb32());
quint16 *dest = reinterpret_cast<quint16*>(rasterBuffer->scanLine(y)) + x;
const int destStride = rasterBuffer->bytesPerLine() / sizeof(quint16);
@@ -543,7 +466,7 @@ public:
const uint * QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer, const Operator *op, const QSpanData *data,
int y, int x, int length)
{
- return qt_fetch_radial_gradient_template<QRadialFetchSimd<QSimdSse2> >(buffer, op, data, y, x, length);
+ return qt_fetch_radial_gradient_template<QRadialFetchSimd<QSimdSse2>,uint>(buffer, op, data, y, x, length);
}
void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
diff --git a/src/gui/painting/qdrawhelper_x86_p.h b/src/gui/painting/qdrawhelper_x86_p.h
index 4d203c4f9d..50ee83aa2c 100644
--- a/src/gui/painting/qdrawhelper_x86_p.h
+++ b/src/gui/painting/qdrawhelper_x86_p.h
@@ -53,13 +53,13 @@ QT_BEGIN_NAMESPACE
void qt_memfill32(quint32 *dest, quint32 value, int count);
void qt_memfill16(quint16 *dest, quint16 value, int count);
void qt_bitmapblit32_sse2(QRasterBuffer *rasterBuffer, int x, int y,
- quint32 color,
+ const QRgba64 &color,
const uchar *src, int width, int height, int stride);
void qt_bitmapblit8888_sse2(QRasterBuffer *rasterBuffer, int x, int y,
- quint32 color,
+ const QRgba64 &color,
const uchar *src, int width, int height, int stride);
void qt_bitmapblit16_sse2(QRasterBuffer *rasterBuffer, int x, int y,
- quint32 color,
+ const QRgba64 &color,
const uchar *src, int width, int height, int stride);
void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
diff --git a/src/gui/painting/qimagescale.cpp b/src/gui/painting/qimagescale.cpp
index 2f85e90c49..33dccc5374 100644
--- a/src/gui/painting/qimagescale.cpp
+++ b/src/gui/painting/qimagescale.cpp
@@ -77,8 +77,9 @@ QT_BEGIN_NAMESPACE
*
* Changes include formatting, namespaces and other C++'ings, removal of old
* #ifdef'ed code, and removal of unneeded border calculation code.
- * Later the code has been refactored and an SSE4.1 optimizated path have been
- * added instead of the removed MMX assembler.
+ * Later the code has been refactored, an SSE4.1 optimizated path have been
+ * added instead of the removed MMX assembler, and scaling of clipped area
+ * removed.
*
* Imlib2 is (C) Carsten Haitzler and various contributors. The MMX code
* is by Willem Monsuwe <willem@stack.nl>. All other modifications are
@@ -256,34 +257,27 @@ QImageScaleInfo* QImageScale::qimageCalcScaleInfo(const QImage &img,
static void qt_qimageScaleAARGBA_up_x_down_y(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy,
int dw, int dh, int dow, int sow);
static void qt_qimageScaleAARGBA_down_x_up_y(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy,
int dw, int dh, int dow, int sow);
static void qt_qimageScaleAARGBA_down_xy(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy, int dw,
- int dh, int dow, int sow);
+ int dw, int dh, int dow, int sow);
#if defined(QT_COMPILER_SUPPORTS_SSE4_1)
template<bool RGB>
void qt_qimageScaleAARGBA_up_x_down_y_sse4(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy,
int dw, int dh, int dow, int sow);
template<bool RGB>
void qt_qimageScaleAARGBA_down_x_up_y_sse4(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy,
int dw, int dh, int dow, int sow);
template<bool RGB>
void qt_qimageScaleAARGBA_down_xy_sse4(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy,
int dw, int dh, int dow, int sow);
#endif
static void qt_qimageScaleAARGBA_up_xy(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy,
int dw, int dh, int dow, int sow)
{
const unsigned int **ypoints = isi->ypoints;
@@ -291,15 +285,14 @@ static void qt_qimageScaleAARGBA_up_xy(QImageScaleInfo *isi, unsigned int *dest,
int *xapoints = isi->xapoints;
int *yapoints = isi->yapoints;
- int end = dxx + dw;
/* go through every scanline in the output buffer */
for (int y = 0; y < dh; y++) {
/* calculate the source line we'll scan from */
- const unsigned int *sptr = ypoints[dyy + y];
- unsigned int *dptr = dest + dx + ((y + dy) * dow);
- const int yap = yapoints[dyy + y];
+ const unsigned int *sptr = ypoints[y];
+ unsigned int *dptr = dest + (y * dow);
+ const int yap = yapoints[y];
if (yap > 0) {
- for (int x = dxx; x < end; x++) {
+ for (int x = 0; x < dw; x++) {
const unsigned int *pix = sptr + xpoints[x];
const int xap = xapoints[x];
if (xap > 0)
@@ -309,7 +302,7 @@ static void qt_qimageScaleAARGBA_up_xy(QImageScaleInfo *isi, unsigned int *dest,
dptr++;
}
} else {
- for (int x = dxx; x < end; x++) {
+ for (int x = 0; x < dw; x++) {
const unsigned int *pix = sptr + xpoints[x];
const int xap = xapoints[x];
if (xap > 0)
@@ -324,39 +317,38 @@ static void qt_qimageScaleAARGBA_up_xy(QImageScaleInfo *isi, unsigned int *dest,
/* scale by area sampling */
static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy, int dw,
- int dh, int dow, int sow)
+ int dw, int dh, int dow, int sow)
{
/* scaling up both ways */
if (isi->xup_yup == 3) {
- qt_qimageScaleAARGBA_up_xy(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow);
+ qt_qimageScaleAARGBA_up_xy(isi, dest, dw, dh, dow, sow);
}
/* if we're scaling down vertically */
else if (isi->xup_yup == 1) {
#ifdef QT_COMPILER_SUPPORTS_SSE4_1
if (qCpuHasFeature(SSE4_1))
- qt_qimageScaleAARGBA_up_x_down_y_sse4<false>(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow);
+ qt_qimageScaleAARGBA_up_x_down_y_sse4<false>(isi, dest, dw, dh, dow, sow);
else
#endif
- qt_qimageScaleAARGBA_up_x_down_y(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow);
+ qt_qimageScaleAARGBA_up_x_down_y(isi, dest, dw, dh, dow, sow);
}
/* if we're scaling down horizontally */
else if (isi->xup_yup == 2) {
#ifdef QT_COMPILER_SUPPORTS_SSE4_1
if (qCpuHasFeature(SSE4_1))
- qt_qimageScaleAARGBA_down_x_up_y_sse4<false>(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow);
+ qt_qimageScaleAARGBA_down_x_up_y_sse4<false>(isi, dest, dw, dh, dow, sow);
else
#endif
- qt_qimageScaleAARGBA_down_x_up_y(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow);
+ qt_qimageScaleAARGBA_down_x_up_y(isi, dest, dw, dh, dow, sow);
}
/* if we're scaling down horizontally & vertically */
else {
#ifdef QT_COMPILER_SUPPORTS_SSE4_1
if (qCpuHasFeature(SSE4_1))
- qt_qimageScaleAARGBA_down_xy_sse4<false>(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow);
+ qt_qimageScaleAARGBA_down_xy_sse4<false>(isi, dest, dw, dh, dow, sow);
else
#endif
- qt_qimageScaleAARGBA_down_xy(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow);
+ qt_qimageScaleAARGBA_down_xy(isi, dest, dw, dh, dow, sow);
}
}
@@ -382,7 +374,6 @@ inline static void qt_qimageScaleAARGBA_helper(const unsigned int *pix, int xyap
}
static void qt_qimageScaleAARGBA_up_x_down_y(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy,
int dw, int dh, int dow, int sow)
{
const unsigned int **ypoints = isi->ypoints;
@@ -390,16 +381,14 @@ static void qt_qimageScaleAARGBA_up_x_down_y(QImageScaleInfo *isi, unsigned int
int *xapoints = isi->xapoints;
int *yapoints = isi->yapoints;
- int end = dxx + dw;
-
/* go through every scanline in the output buffer */
for (int y = 0; y < dh; y++) {
- int Cy = (yapoints[dyy + y]) >> 16;
- int yap = (yapoints[dyy + y]) & 0xffff;
+ int Cy = yapoints[y] >> 16;
+ int yap = yapoints[y] & 0xffff;
- unsigned int *dptr = dest + dx + ((y + dy) * dow);
- for (int x = dxx; x < end; x++) {
- const unsigned int *sptr = ypoints[dyy + y] + xpoints[x];
+ unsigned int *dptr = dest + (y * dow);
+ for (int x = 0; x < dw; x++) {
+ const unsigned int *sptr = ypoints[y] + xpoints[x];
int r, g, b, a;
qt_qimageScaleAARGBA_helper(sptr, yap, Cy, sow, r, g, b, a);
@@ -423,7 +412,6 @@ static void qt_qimageScaleAARGBA_up_x_down_y(QImageScaleInfo *isi, unsigned int
}
static void qt_qimageScaleAARGBA_down_x_up_y(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy,
int dw, int dh, int dow, int sow)
{
const unsigned int **ypoints = isi->ypoints;
@@ -431,20 +419,18 @@ static void qt_qimageScaleAARGBA_down_x_up_y(QImageScaleInfo *isi, unsigned int
int *xapoints = isi->xapoints;
int *yapoints = isi->yapoints;
- int end = dxx + dw;
-
/* go through every scanline in the output buffer */
for (int y = 0; y < dh; y++) {
- unsigned int *dptr = dest + dx + ((y + dy) * dow);
- for (int x = dxx; x < end; x++) {
+ unsigned int *dptr = dest + (y * dow);
+ for (int x = 0; x < dw; x++) {
int Cx = xapoints[x] >> 16;
int xap = xapoints[x] & 0xffff;
- const unsigned int *sptr = ypoints[dyy + y] + xpoints[x];
+ const unsigned int *sptr = ypoints[y] + xpoints[x];
int r, g, b, a;
qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, r, g, b, a);
- int yap = yapoints[dyy + y];
+ int yap = yapoints[y];
if (yap > 0) {
int rr, gg, bb, aa;
qt_qimageScaleAARGBA_helper(sptr + sow, xap, Cx, 1, rr, gg, bb, aa);
@@ -465,26 +451,23 @@ static void qt_qimageScaleAARGBA_down_x_up_y(QImageScaleInfo *isi, unsigned int
}
static void qt_qimageScaleAARGBA_down_xy(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy, int dw,
- int dh, int dow, int sow)
+ int dw, int dh, int dow, int sow)
{
const unsigned int **ypoints = isi->ypoints;
int *xpoints = isi->xpoints;
int *xapoints = isi->xapoints;
int *yapoints = isi->yapoints;
- int end = dxx + dw;
-
for (int y = 0; y < dh; y++) {
- int Cy = (yapoints[dyy + y]) >> 16;
- int yap = (yapoints[dyy + y]) & 0xffff;
+ int Cy = (yapoints[y]) >> 16;
+ int yap = (yapoints[y]) & 0xffff;
- unsigned int *dptr = dest + dx + ((y + dy) * dow);
- for (int x = dxx; x < end; x++) {
+ unsigned int *dptr = dest + (y * dow);
+ for (int x = 0; x < dw; x++) {
int Cx = xapoints[x] >> 16;
int xap = xapoints[x] & 0xffff;
- const unsigned int *sptr = ypoints[dyy + y] + xpoints[x];
+ const unsigned int *sptr = ypoints[y] + xpoints[x];
int rx, gx, bx, ax;
qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, rx, gx, bx, ax);
@@ -517,52 +500,48 @@ static void qt_qimageScaleAARGBA_down_xy(QImageScaleInfo *isi, unsigned int *des
}
static void qt_qimageScaleAARGB_up_x_down_y(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy, int dw,
- int dh, int dow, int sow);
+ int dw, int dh, int dow, int sow);
static void qt_qimageScaleAARGB_down_x_up_y(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy, int dw,
- int dh, int dow, int sow);
+ int dw, int dh, int dow, int sow);
static void qt_qimageScaleAARGB_down_xy(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy, int dw,
- int dh, int dow, int sow);
+ int dw, int dh, int dow, int sow);
/* scale by area sampling - IGNORE the ALPHA byte*/
static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy,
int dw, int dh, int dow, int sow)
{
/* scaling up both ways */
if (isi->xup_yup == 3) {
- qt_qimageScaleAARGBA_up_xy(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow);
+ qt_qimageScaleAARGBA_up_xy(isi, dest, dw, dh, dow, sow);
}
/* if we're scaling down vertically */
else if (isi->xup_yup == 1) {
#ifdef QT_COMPILER_SUPPORTS_SSE4_1
if (qCpuHasFeature(SSE4_1))
- qt_qimageScaleAARGBA_up_x_down_y_sse4<true>(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow);
+ qt_qimageScaleAARGBA_up_x_down_y_sse4<true>(isi, dest, dw, dh, dow, sow);
else
#endif
- qt_qimageScaleAARGB_up_x_down_y(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow);
+ qt_qimageScaleAARGB_up_x_down_y(isi, dest, dw, dh, dow, sow);
}
/* if we're scaling down horizontally */
else if (isi->xup_yup == 2) {
#ifdef QT_COMPILER_SUPPORTS_SSE4_1
if (qCpuHasFeature(SSE4_1))
- qt_qimageScaleAARGBA_down_x_up_y_sse4<true>(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow);
+ qt_qimageScaleAARGBA_down_x_up_y_sse4<true>(isi, dest, dw, dh, dow, sow);
else
#endif
- qt_qimageScaleAARGB_down_x_up_y(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow);
+ qt_qimageScaleAARGB_down_x_up_y(isi, dest, dw, dh, dow, sow);
}
/* if we're scaling down horizontally & vertically */
else {
#ifdef QT_COMPILER_SUPPORTS_SSE4_1
if (qCpuHasFeature(SSE4_1))
- qt_qimageScaleAARGBA_down_xy_sse4<true>(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow);
+ qt_qimageScaleAARGBA_down_xy_sse4<true>(isi, dest, dw, dh, dow, sow);
else
#endif
- qt_qimageScaleAARGB_down_xy(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow);
+ qt_qimageScaleAARGB_down_xy(isi, dest, dw, dh, dow, sow);
}
}
@@ -586,24 +565,21 @@ inline static void qt_qimageScaleAARGB_helper(const unsigned int *pix, int xyap,
}
static void qt_qimageScaleAARGB_up_x_down_y(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy, int dw,
- int dh, int dow, int sow)
+ int dw, int dh, int dow, int sow)
{
const unsigned int **ypoints = isi->ypoints;
int *xpoints = isi->xpoints;
int *xapoints = isi->xapoints;
int *yapoints = isi->yapoints;
- int end = dxx + dw;
-
/* go through every scanline in the output buffer */
for (int y = 0; y < dh; y++) {
- int Cy = (yapoints[dyy + y]) >> 16;
- int yap = (yapoints[dyy + y]) & 0xffff;
+ int Cy = yapoints[y] >> 16;
+ int yap = yapoints[y] & 0xffff;
- unsigned int *dptr = dest + dx + ((y + dy) * dow);
- for (int x = dxx; x < end; x++) {
- const unsigned int *sptr = ypoints[dyy + y] + xpoints[x];
+ unsigned int *dptr = dest + (y * dow);
+ for (int x = 0; x < dw; x++) {
+ const unsigned int *sptr = ypoints[y] + xpoints[x];
int r, g, b;
qt_qimageScaleAARGB_helper(sptr, yap, Cy, sow, r, g, b);
@@ -625,28 +601,25 @@ static void qt_qimageScaleAARGB_up_x_down_y(QImageScaleInfo *isi, unsigned int *
}
static void qt_qimageScaleAARGB_down_x_up_y(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy, int dw,
- int dh, int dow, int sow)
+ int dw, int dh, int dow, int sow)
{
const unsigned int **ypoints = isi->ypoints;
int *xpoints = isi->xpoints;
int *xapoints = isi->xapoints;
int *yapoints = isi->yapoints;
- int end = dxx + dw;
-
/* go through every scanline in the output buffer */
for (int y = 0; y < dh; y++) {
- unsigned int *dptr = dest + dx + ((y + dy) * dow);
- for (int x = dxx; x < end; x++) {
+ unsigned int *dptr = dest + (y * dow);
+ for (int x = 0; x < dw; x++) {
int Cx = xapoints[x] >> 16;
int xap = xapoints[x] & 0xffff;
- const unsigned int *sptr = ypoints[dyy + y] + xpoints[x];
+ const unsigned int *sptr = ypoints[y] + xpoints[x];
int r, g, b;
qt_qimageScaleAARGB_helper(sptr, xap, Cx, 1, r, g, b);
- int yap = yapoints[dyy + y];
+ int yap = yapoints[y];
if (yap > 0) {
int rr, bb, gg;
qt_qimageScaleAARGB_helper(sptr + sow, xap, Cx, 1, rr, gg, bb);
@@ -664,26 +637,23 @@ static void qt_qimageScaleAARGB_down_x_up_y(QImageScaleInfo *isi, unsigned int *
}
static void qt_qimageScaleAARGB_down_xy(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy, int dw,
- int dh, int dow, int sow)
+ int dw, int dh, int dow, int sow)
{
const unsigned int **ypoints = isi->ypoints;
int *xpoints = isi->xpoints;
int *xapoints = isi->xapoints;
int *yapoints = isi->yapoints;
- int end = dxx + dw;
-
for (int y = 0; y < dh; y++) {
- int Cy = (yapoints[dyy + y]) >> 16;
- int yap = (yapoints[dyy + y]) & 0xffff;
+ int Cy = yapoints[y] >> 16;
+ int yap = yapoints[y] & 0xffff;
- unsigned int *dptr = dest + dx + ((y + dy) * dow);
- for (int x = dxx; x < end; x++) {
+ unsigned int *dptr = dest + (y * dow);
+ for (int x = 0; x < dw; x++) {
int Cx = xapoints[x] >> 16;
int xap = xapoints[x] & 0xffff;
- const unsigned int *sptr = ypoints[dyy + y] + xpoints[x];
+ const unsigned int *sptr = ypoints[y] + xpoints[x];
int rx, gx, bx;
qt_qimageScaleAARGB_helper(sptr, xap, Cx, 1, rx, gx, bx);
@@ -735,10 +705,10 @@ QImage qSmoothScaleImage(const QImage &src, int dw, int dh)
if (src.hasAlphaChannel())
qt_qimageScaleAARGBA(scaleinfo, (unsigned int *)buffer.scanLine(0),
- 0, 0, 0, 0, dw, dh, dw, src.bytesPerLine() / 4);
+ dw, dh, dw, src.bytesPerLine() / 4);
else
qt_qimageScaleAARGB(scaleinfo, (unsigned int *)buffer.scanLine(0),
- 0, 0, 0, 0, dw, dh, dw, src.bytesPerLine() / 4);
+ dw, dh, dw, src.bytesPerLine() / 4);
qimageFreeScaleInfo(scaleinfo);
return buffer;
diff --git a/src/gui/painting/qimagescale_sse4.cpp b/src/gui/painting/qimagescale_sse4.cpp
index 303e0fd980..8712b5d324 100644
--- a/src/gui/painting/qimagescale_sse4.cpp
+++ b/src/gui/painting/qimagescale_sse4.cpp
@@ -59,7 +59,6 @@ inline static __m128i qt_qimageScaleAARGBA_helper(const unsigned int *pix, int x
template<bool RGB>
void qt_qimageScaleAARGBA_up_x_down_y_sse4(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy,
int dw, int dh, int dow, int sow)
{
const unsigned int **ypoints = isi->ypoints;
@@ -67,20 +66,18 @@ void qt_qimageScaleAARGBA_up_x_down_y_sse4(QImageScaleInfo *isi, unsigned int *d
int *xapoints = isi->xapoints;
int *yapoints = isi->yapoints;
- int end = dxx + dw;
-
const __m128i v256 = _mm_set1_epi32(256);
/* go through every scanline in the output buffer */
for (int y = 0; y < dh; y++) {
- int Cy = (yapoints[dyy + y]) >> 16;
- int yap = (yapoints[dyy + y]) & 0xffff;
+ int Cy = yapoints[y] >> 16;
+ int yap = yapoints[y] & 0xffff;
const __m128i vCy = _mm_set1_epi32(Cy);
const __m128i vyap = _mm_set1_epi32(yap);
- unsigned int *dptr = dest + dx + ((y + dy) * dow);
- for (int x = dxx; x < end; x++) {
- const unsigned int *sptr = ypoints[dyy + y] + xpoints[x];
+ unsigned int *dptr = dest + (y * dow);
+ for (int x = 0; x < dw; x++) {
+ const unsigned int *sptr = ypoints[y] + xpoints[x];
__m128i vx = qt_qimageScaleAARGBA_helper(sptr, yap, Cy, sow, vyap, vCy);
int xap = xapoints[x];
@@ -107,7 +104,6 @@ void qt_qimageScaleAARGBA_up_x_down_y_sse4(QImageScaleInfo *isi, unsigned int *d
template<bool RGB>
void qt_qimageScaleAARGBA_down_x_up_y_sse4(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy,
int dw, int dh, int dow, int sow)
{
const unsigned int **ypoints = isi->ypoints;
@@ -115,23 +111,21 @@ void qt_qimageScaleAARGBA_down_x_up_y_sse4(QImageScaleInfo *isi, unsigned int *d
int *xapoints = isi->xapoints;
int *yapoints = isi->yapoints;
- int end = dxx + dw;
-
const __m128i v256 = _mm_set1_epi32(256);
/* go through every scanline in the output buffer */
for (int y = 0; y < dh; y++) {
- unsigned int *dptr = dest + dx + ((y + dy) * dow);
- for (int x = dxx; x < end; x++) {
+ unsigned int *dptr = dest + (y * dow);
+ for (int x = 0; x < dw; x++) {
int Cx = xapoints[x] >> 16;
int xap = xapoints[x] & 0xffff;
const __m128i vCx = _mm_set1_epi32(Cx);
const __m128i vxap = _mm_set1_epi32(xap);
- const unsigned int *sptr = ypoints[dyy + y] + xpoints[x];
+ const unsigned int *sptr = ypoints[y] + xpoints[x];
__m128i vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, vxap, vCx);
- int yap = yapoints[dyy + y];
+ int yap = yapoints[y];
if (yap > 0) {
const __m128i vyap = _mm_set1_epi32(yap);
const __m128i vinvyap = _mm_sub_epi32(v256, vyap);
@@ -155,7 +149,6 @@ void qt_qimageScaleAARGBA_down_x_up_y_sse4(QImageScaleInfo *isi, unsigned int *d
template<bool RGB>
void qt_qimageScaleAARGBA_down_xy_sse4(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy,
int dw, int dh, int dow, int sow)
{
const unsigned int **ypoints = isi->ypoints;
@@ -164,20 +157,19 @@ void qt_qimageScaleAARGBA_down_xy_sse4(QImageScaleInfo *isi, unsigned int *dest,
int *yapoints = isi->yapoints;
for (int y = 0; y < dh; y++) {
- int Cy = (yapoints[dyy + y]) >> 16;
- int yap = (yapoints[dyy + y]) & 0xffff;
+ int Cy = yapoints[y] >> 16;
+ int yap = yapoints[y] & 0xffff;
const __m128i vCy = _mm_set1_epi32(Cy);
const __m128i vyap = _mm_set1_epi32(yap);
- unsigned int *dptr = dest + dx + ((y + dy) * dow);
- int end = dxx + dw;
- for (int x = dxx; x < end; x++) {
+ unsigned int *dptr = dest + (y * dow);
+ for (int x = 0; x < dw; x++) {
const int Cx = xapoints[x] >> 16;
const int xap = xapoints[x] & 0xffff;
const __m128i vCx = _mm_set1_epi32(Cx);
const __m128i vxap = _mm_set1_epi32(xap);
- const unsigned int *sptr = ypoints[dyy + y] + xpoints[x];
+ const unsigned int *sptr = ypoints[y] + xpoints[x];
__m128i vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, vxap, vCx);
__m128i vr = _mm_mullo_epi32(_mm_srli_epi32(vx, 4), vyap);
@@ -203,27 +195,21 @@ void qt_qimageScaleAARGBA_down_xy_sse4(QImageScaleInfo *isi, unsigned int *dest,
}
template void qt_qimageScaleAARGBA_up_x_down_y_sse4<false>(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy,
int dw, int dh, int dow, int sow);
template void qt_qimageScaleAARGBA_up_x_down_y_sse4<true>(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy,
int dw, int dh, int dow, int sow);
template void qt_qimageScaleAARGBA_down_x_up_y_sse4<false>(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy,
int dw, int dh, int dow, int sow);
template void qt_qimageScaleAARGBA_down_x_up_y_sse4<true>(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy,
int dw, int dh, int dow, int sow);
template void qt_qimageScaleAARGBA_down_xy_sse4<false>(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy,
int dw, int dh, int dow, int sow);
template void qt_qimageScaleAARGBA_down_xy_sse4<true>(QImageScaleInfo *isi, unsigned int *dest,
- int dxx, int dyy, int dx, int dy,
int dw, int dh, int dow, int sow);
QT_END_NAMESPACE
diff --git a/src/gui/painting/qmatrix.cpp b/src/gui/painting/qmatrix.cpp
index acedc6a7ba..e4d756c18d 100644
--- a/src/gui/painting/qmatrix.cpp
+++ b/src/gui/painting/qmatrix.cpp
@@ -31,9 +31,11 @@
**
****************************************************************************/
+#include "qmatrix.h"
+
#include "qdatastream.h"
#include "qdebug.h"
-#include "qmatrix.h"
+#include "qhashfunctions.h"
#include "qregion.h"
#include "qpainterpath.h"
#include "qpainterpath_p.h"
@@ -972,6 +974,26 @@ bool QMatrix::operator==(const QMatrix &m) const
_dy == m._dy;
}
+
+/*!
+ \since 5.6
+ \relates QMatrix
+
+ Returns the hash value for \a key, using
+ \a seed to seed the calculation.
+*/
+uint qHash(const QMatrix &key, uint seed) Q_DECL_NOTHROW
+{
+ QtPrivate::QHashCombine hash;
+ seed = hash(key.m11(), seed);
+ seed = hash(key.m12(), seed);
+ seed = hash(key.m21(), seed);
+ seed = hash(key.m22(), seed);
+ seed = hash(key.dx(), seed);
+ seed = hash(key.dy(), seed);
+ return seed;
+}
+
/*!
\fn bool QMatrix::operator!=(const QMatrix &matrix) const
diff --git a/src/gui/painting/qmatrix.h b/src/gui/painting/qmatrix.h
index ddffa8a8b9..809a19a0b8 100644
--- a/src/gui/painting/qmatrix.h
+++ b/src/gui/painting/qmatrix.h
@@ -92,7 +92,7 @@ public:
bool isInvertible() const { return !qFuzzyIsNull(_m11*_m22 - _m12*_m21); }
qreal determinant() const { return _m11*_m22 - _m12*_m21; }
- QMatrix inverted(bool *invertible = 0) const Q_REQUIRED_RESULT;
+ QMatrix inverted(bool *invertible = Q_NULLPTR) const Q_REQUIRED_RESULT;
bool operator==(const QMatrix &) const;
bool operator!=(const QMatrix &) const;
@@ -126,6 +126,8 @@ private:
};
Q_DECLARE_TYPEINFO(QMatrix, Q_MOVABLE_TYPE);
+Q_GUI_EXPORT Q_DECL_CONST_FUNCTION uint qHash(const QMatrix &key, uint seed = 0) Q_DECL_NOTHROW;
+
// mathematical semantics
inline QPoint operator*(const QPoint &p, const QMatrix &m)
{ return m.map(p); }
diff --git a/src/gui/painting/qpagedpaintdevice.cpp b/src/gui/painting/qpagedpaintdevice.cpp
index 3adc5e9411..547cedf51f 100644
--- a/src/gui/painting/qpagedpaintdevice.cpp
+++ b/src/gui/painting/qpagedpaintdevice.cpp
@@ -36,6 +36,10 @@
QT_BEGIN_NAMESPACE
+QPagedPaintDevicePrivate::~QPagedPaintDevicePrivate()
+{
+}
+
/*!
\class QPagedPaintDevice
\inmodule QtGui
diff --git a/src/gui/painting/qpagedpaintdevice_p.h b/src/gui/painting/qpagedpaintdevice_p.h
index 62f69747db..30b1c0a1e6 100644
--- a/src/gui/painting/qpagedpaintdevice_p.h
+++ b/src/gui/painting/qpagedpaintdevice_p.h
@@ -61,9 +61,7 @@ public:
{
}
- virtual ~QPagedPaintDevicePrivate()
- {
- }
+ virtual ~QPagedPaintDevicePrivate();
// ### Qt6 Remove these and make public class methods virtual
virtual bool setPageLayout(const QPageLayout &newPageLayout)
diff --git a/src/gui/painting/qpagelayout.h b/src/gui/painting/qpagelayout.h
index 17e5eeece2..7eac348c43 100644
--- a/src/gui/painting/qpagelayout.h
+++ b/src/gui/painting/qpagelayout.h
@@ -75,14 +75,13 @@ public:
const QMarginsF &margins, Unit units = Point,
const QMarginsF &minMargins = QMarginsF(0, 0, 0, 0));
QPageLayout(const QPageLayout &other);
- ~QPageLayout();
-
- QPageLayout &operator=(const QPageLayout &other);
- #ifdef Q_COMPILER_RVALUE_REFS
- QPageLayout &operator=(QPageLayout &&other) { swap(other); return *this; }
+#ifdef Q_COMPILER_RVALUE_REFS
+ QPageLayout &operator=(QPageLayout &&other) Q_DECL_NOTHROW { swap(other); return *this; }
#endif
+ QPageLayout &operator=(const QPageLayout &other);
+ ~QPageLayout();
- void swap(QPageLayout &other) { d.swap(other.d); }
+ void swap(QPageLayout &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
friend Q_GUI_EXPORT bool operator==(const QPageLayout &lhs, const QPageLayout &rhs);
bool isEquivalentTo(const QPageLayout &other) const;
diff --git a/src/gui/painting/qpagesize.h b/src/gui/painting/qpagesize.h
index 00e22a243f..9119a582ac 100644
--- a/src/gui/painting/qpagesize.h
+++ b/src/gui/painting/qpagesize.h
@@ -229,14 +229,14 @@ public:
const QString &name = QString(),
SizeMatchPolicy matchPolicy = FuzzyMatch);
QPageSize(const QPageSize &other);
- ~QPageSize();
-
- QPageSize &operator=(const QPageSize &other);
#ifdef Q_COMPILER_RVALUE_REFS
- QPageSize &operator=(QPageSize &&other) { swap(other); return *this; }
+ QPageSize &operator=(QPageSize &&other) Q_DECL_NOTHROW { swap(other); return *this; }
#endif
+ QPageSize &operator=(const QPageSize &other);
+ ~QPageSize();
+
- void swap(QPageSize &other) { d.swap(other.d); }
+ void swap(QPageSize &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
friend Q_GUI_EXPORT bool operator==(const QPageSize &lhs, const QPageSize &rhs);
bool isEquivalentTo(const QPageSize &other) const;
diff --git a/src/gui/painting/qpaintdevice.cpp b/src/gui/painting/qpaintdevice.cpp
index bbf8e8f170..2332d11a03 100644
--- a/src/gui/painting/qpaintdevice.cpp
+++ b/src/gui/painting/qpaintdevice.cpp
@@ -79,7 +79,13 @@ Q_GUI_EXPORT int qt_paint_device_metric(const QPaintDevice *device, QPaintDevice
int QPaintDevice::metric(PaintDeviceMetric m) const
{
+ // Fallback: A subclass has not implemented PdmDevicePixelRatioScaled but might
+ // have implemented PdmDevicePixelRatio.
+ if (m == PdmDevicePixelRatioScaled)
+ return this->metric(PdmDevicePixelRatio) * devicePixelRatioFScale();
+
qWarning("QPaintDevice::metrics: Device has no metric information");
+
if (m == PdmDpiX) {
return 72;
} else if (m == PdmDpiY) {
diff --git a/src/gui/painting/qpaintdevice.h b/src/gui/painting/qpaintdevice.h
index 4eb972786b..72a6ca4cb3 100644
--- a/src/gui/painting/qpaintdevice.h
+++ b/src/gui/painting/qpaintdevice.h
@@ -58,7 +58,8 @@ public:
PdmDpiY,
PdmPhysicalDpiX,
PdmPhysicalDpiY,
- PdmDevicePixelRatio
+ PdmDevicePixelRatio,
+ PdmDevicePixelRatioScaled
};
virtual ~QPaintDevice();
@@ -76,9 +77,11 @@ public:
int physicalDpiX() const { return metric(PdmPhysicalDpiX); }
int physicalDpiY() const { return metric(PdmPhysicalDpiY); }
int devicePixelRatio() const { return metric(PdmDevicePixelRatio); }
+ qreal devicePixelRatioF() const { return metric(PdmDevicePixelRatioScaled) / devicePixelRatioFScale(); }
int colorCount() const { return metric(PdmNumColors); }
int depth() const { return metric(PdmDepth); }
+ static inline qreal devicePixelRatioFScale() { return 0x10000; }
protected:
QPaintDevice() Q_DECL_NOEXCEPT;
virtual int metric(PaintDeviceMetric metric) const;
@@ -87,7 +90,6 @@ protected:
virtual QPainter *sharedPainter() const;
ushort painters; // refcount
-
private:
Q_DISABLE_COPY(QPaintDevice)
diff --git a/src/gui/painting/qpaintdevice.qdoc b/src/gui/painting/qpaintdevice.qdoc
index 8db65af18e..ef5deb154d 100644
--- a/src/gui/painting/qpaintdevice.qdoc
+++ b/src/gui/painting/qpaintdevice.qdoc
@@ -118,7 +118,13 @@
values are 1 for normal-dpi displays and 2 for high-dpi "retina"
displays.
- \sa metric()
+ \value PdmDevicePixelRatioScaled The scaled device pixel ratio for the device.
+ This is identical to PdmDevicePixelRatio, except that the value is scaled by a
+ constant factor in order to support paint devices with fractional scale factors.
+ The constant scaling factor used is devicePixelRatioFScale(). This enum value
+ has been introduced in Qt 5.6.
+
+ \sa metric(), devicePixelRatioF()
*/
/*!
@@ -286,3 +292,24 @@
Common values are 1 for normal-dpi displays and 2 for high-dpi
"retina" displays.
*/
+
+/*!
+ \fn qreal QPaintDevice::devicePixelRatioF() const
+
+ Returns the device pixel ratio for the device as a floating point number.
+
+ \since 5.6
+*/
+
+/*!
+ \fn qreal QPaintDevice::devicePixelRatioFScale()
+
+ \internal
+
+ Returns the scaling factor used for \c PdmDevicePixelRatioScaled. Classes
+ that are not QPaintDevice subclasses are implementing metric(), and need to
+ access this constant. Since it's a qreal, it cannot be an enum, and an inline
+ function is more efficient than a static member variable.
+
+ \since 5.6
+*/
diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp
index 6ba26df3b4..ef93094387 100644
--- a/src/gui/painting/qpaintengine.cpp
+++ b/src/gui/painting/qpaintengine.cpp
@@ -968,6 +968,10 @@ QRect QPaintEngine::systemRect() const
return d_func()->systemRect;
}
+QPaintEnginePrivate::~QPaintEnginePrivate()
+{
+}
+
void QPaintEnginePrivate::drawBoxTextItem(const QPointF &p, const QTextItemInt &ti)
{
if (!ti.glyphs.numGlyphs)
diff --git a/src/gui/painting/qpaintengine.h b/src/gui/painting/qpaintengine.h
index eeca87ce16..fa3fad1caa 100644
--- a/src/gui/painting/qpaintengine.h
+++ b/src/gui/painting/qpaintengine.h
@@ -137,7 +137,7 @@ public:
PolylineMode
};
- explicit QPaintEngine(PaintEngineFeatures features=0);
+ explicit QPaintEngine(PaintEngineFeatures features=PaintEngineFeatures());
virtual ~QPaintEngine();
bool isActive() const { return active; }
@@ -220,7 +220,7 @@ public:
inline bool isExtended() const { return extended; }
protected:
- QPaintEngine(QPaintEnginePrivate &data, PaintEngineFeatures devcaps=0);
+ QPaintEngine(QPaintEnginePrivate &data, PaintEngineFeatures devcaps=PaintEngineFeatures());
QPaintEngineState *state;
PaintEngineFeatures gccaps;
diff --git a/src/gui/painting/qpaintengine_p.h b/src/gui/painting/qpaintengine_p.h
index c58662ede4..918c98997b 100644
--- a/src/gui/painting/qpaintengine_p.h
+++ b/src/gui/painting/qpaintengine_p.h
@@ -60,7 +60,8 @@ class Q_GUI_EXPORT QPaintEnginePrivate
public:
QPaintEnginePrivate() : pdev(0), q_ptr(0), currentClipDevice(0), hasSystemTransform(0),
hasSystemViewport(0) {}
- virtual ~QPaintEnginePrivate() { }
+ virtual ~QPaintEnginePrivate();
+
QPaintDevice *pdev;
QPaintEngine *q_ptr;
QRegion systemClip;
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index a5957ca86e..05ccff5de0 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -42,7 +42,6 @@
#include <qpainterpath.h>
#include <qdebug.h>
-#include <qhash.h>
#include <qbitmap.h>
#include <qmath.h>
@@ -57,6 +56,7 @@
#include <private/qstatictext_p.h>
#include <private/qcosmeticstroker_p.h>
#include "qmemrotate_p.h"
+#include "qrgba64_p.h"
#include "qpaintengine_raster_p.h"
// #include "qbezier_p.h"
@@ -830,7 +830,7 @@ void QRasterPaintEngine::updateRasterState()
&& s->intOpacity == 256
&& (mode == QPainter::CompositionMode_Source
|| (mode == QPainter::CompositionMode_SourceOver
- && qAlpha(s->penData.solid.color) == 255));
+ && s->penData.solid.color.isOpaque()));
}
s->dirty = 0;
@@ -1412,10 +1412,9 @@ static void fillRect_normalized(const QRect &r, QSpanData *data,
if (data->fillRect && (mode == QPainter::CompositionMode_Source
|| (mode == QPainter::CompositionMode_SourceOver
- && qAlpha(data->solid.color) == 255)))
+ && data->solid.color.isOpaque())))
{
- data->fillRect(data->rasterBuffer, x1, y1, width, height,
- data->solid.color);
+ data->fillRect(data->rasterBuffer, x1, y1, width, height, data->solid.color);
return;
}
}
@@ -1773,8 +1772,9 @@ void QRasterPaintEngine::fillRect(const QRectF &r, const QColor &color)
Q_D(QRasterPaintEngine);
QRasterPaintEngineState *s = state();
- d->solid_color_filler.solid.color = qPremultiply(ARGB_COMBINE_ALPHA(color.rgba(), s->intOpacity));
- if ((d->solid_color_filler.solid.color & 0xff000000) == 0
+ d->solid_color_filler.solid.color = qPremultiply(combineAlpha256(color.rgba64(), s->intOpacity));
+
+ if (d->solid_color_filler.solid.color.isTransparent()
&& s->composition_mode == QPainter::CompositionMode_SourceOver) {
return;
}
@@ -2219,19 +2219,15 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
case QImage::Format_A2BGR30_Premultiplied:
case QImage::Format_A2RGB30_Premultiplied:
// Combine premultiplied color with the opacity set on the painter.
- d->solid_color_filler.solid.color =
- ((((color & 0x00ff00ff) * s->intOpacity) >> 8) & 0x00ff00ff)
- | ((((color & 0xff00ff00) >> 8) * s->intOpacity) & 0xff00ff00);
+ d->solid_color_filler.solid.color = multiplyAlpha256(QRgba64::fromArgb32(color), s->intOpacity);
break;
default:
- d->solid_color_filler.solid.color = qPremultiply(ARGB_COMBINE_ALPHA(color, s->intOpacity));
+ d->solid_color_filler.solid.color = qPremultiply(combineAlpha256(QRgba64::fromArgb32(color), s->intOpacity));
break;
}
- if ((d->solid_color_filler.solid.color & 0xff000000) == 0
- && s->composition_mode == QPainter::CompositionMode_SourceOver) {
+ if (d->solid_color_filler.solid.color.isTransparent() && s->composition_mode == QPainter::CompositionMode_SourceOver)
return;
- }
d->solid_color_filler.clip = d->clip();
d->solid_color_filler.adjustSpanMethods();
@@ -3657,8 +3653,9 @@ QImage::Format QRasterBuffer::prepare(QImage *image)
drawHelper = qDrawHelper + format;
if (image->depth() == 1 && image->colorTable().size() == 2) {
monoDestinationWithClut = true;
- destColor0 = qPremultiply(image->colorTable()[0]);
- destColor1 = qPremultiply(image->colorTable()[1]);
+ const QVector<QRgb> colorTable = image->colorTable();
+ destColor0 = qPremultiply(colorTable[0]);
+ destColor1 = qPremultiply(colorTable[1]);
}
return format;
@@ -4140,8 +4137,8 @@ class QGradientCache
struct CacheInfo
{
inline CacheInfo(QGradientStops s, int op, QGradient::InterpolationMode mode) :
- stops(s), opacity(op), interpolationMode(mode) {}
- uint buffer[GRADIENT_STOPTABLE_SIZE];
+ stops(qMove(s)), opacity(op), interpolationMode(mode) {}
+ QRgba64 buffer[GRADIENT_STOPTABLE_SIZE];
QGradientStops stops;
int opacity;
QGradient::InterpolationMode interpolationMode;
@@ -4150,12 +4147,12 @@ class QGradientCache
typedef QMultiHash<quint64, CacheInfo> QGradientColorTableHash;
public:
- inline const uint *getBuffer(const QGradient &gradient, int opacity) {
+ inline const QRgba64 *getBuffer(const QGradient &gradient, int opacity) {
quint64 hash_val = 0;
- QGradientStops stops = gradient.stops();
+ const QGradientStops stops = gradient.stops();
for (int i = 0; i < stops.size() && i <= 2; i++)
- hash_val += stops[i].second.rgba();
+ hash_val += stops[i].second.rgba64();
QMutexLocker lock(&mutex);
QGradientColorTableHash::const_iterator it = cache.constFind(hash_val);
@@ -4178,9 +4175,9 @@ public:
protected:
inline int maxCacheSize() const { return 60; }
inline void generateGradientColorTable(const QGradient& g,
- uint *colorTable,
+ QRgba64 *colorTable,
int size, int opacity) const;
- uint *addCacheElement(quint64 hash_val, const QGradient &gradient, int opacity) {
+ QRgba64 *addCacheElement(quint64 hash_val, const QGradient &gradient, int opacity) {
if (cache.size() == maxCacheSize()) {
// may remove more than 1, but OK
cache.erase(cache.begin() + (qrand() % maxCacheSize()));
@@ -4194,23 +4191,25 @@ protected:
QMutex mutex;
};
-void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint *colorTable, int size, int opacity) const
+void QGradientCache::generateGradientColorTable(const QGradient& gradient, QRgba64 *colorTable, int size, int opacity) const
{
- QGradientStops stops = gradient.stops();
+ const QGradientStops stops = gradient.stops();
int stopCount = stops.count();
Q_ASSERT(stopCount > 0);
bool colorInterpolation = (gradient.interpolationMode() == QGradient::ColorInterpolation);
if (stopCount == 2) {
- uint first_color = ARGB_COMBINE_ALPHA(stops[0].second.rgba(), opacity);
- uint second_color = ARGB_COMBINE_ALPHA(stops[1].second.rgba(), opacity);
+ QRgba64 first_color = combineAlpha256(stops[0].second.rgba64(), opacity);
+ QRgba64 second_color = combineAlpha256(stops[1].second.rgba64(), opacity);
qreal first_stop = stops[0].first;
qreal second_stop = stops[1].first;
if (second_stop < first_stop) {
- qSwap(first_color, second_color);
+ quint64 tmp = first_color;
+ first_color = second_color;
+ second_color = tmp;
qSwap(first_stop, second_stop);
}
@@ -4222,15 +4221,15 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
int first_index = qRound(first_stop * (GRADIENT_STOPTABLE_SIZE-1));
int second_index = qRound(second_stop * (GRADIENT_STOPTABLE_SIZE-1));
- uint red_first = qRed(first_color) << 16;
- uint green_first = qGreen(first_color) << 16;
- uint blue_first = qBlue(first_color) << 16;
- uint alpha_first = qAlpha(first_color) << 16;
+ uint red_first = uint(first_color.red()) << 16;
+ uint green_first = uint(first_color.green()) << 16;
+ uint blue_first = uint(first_color.blue()) << 16;
+ uint alpha_first = uint(first_color.alpha()) << 16;
- uint red_second = qRed(second_color) << 16;
- uint green_second = qGreen(second_color) << 16;
- uint blue_second = qBlue(second_color) << 16;
- uint alpha_second = qAlpha(second_color) << 16;
+ uint red_second = uint(second_color.red()) << 16;
+ uint green_second = uint(second_color.green()) << 16;
+ uint blue_second = uint(second_color.blue()) << 16;
+ uint alpha_second = uint(second_color.alpha()) << 16;
int i = 0;
for (; i <= qMin(GRADIENT_STOPTABLE_SIZE, first_index); ++i) {
@@ -4243,10 +4242,10 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
if (i < second_index) {
qreal reciprocal = qreal(1) / (second_index - first_index);
- int red_delta = qRound(int(red_second - red_first) * reciprocal);
- int green_delta = qRound(int(green_second - green_first) * reciprocal);
- int blue_delta = qRound(int(blue_second - blue_first) * reciprocal);
- int alpha_delta = qRound(int(alpha_second - alpha_first) * reciprocal);
+ int red_delta = qRound((qreal(red_second) - red_first) * reciprocal);
+ int green_delta = qRound((qreal(green_second) - green_first) * reciprocal);
+ int blue_delta = qRound((qreal(blue_second) - blue_first) * reciprocal);
+ int alpha_delta = qRound((qreal(alpha_second) - alpha_first) * reciprocal);
// rounding
red_first += 1 << 15;
@@ -4260,8 +4259,7 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
blue_first += blue_delta;
alpha_first += alpha_delta;
- const uint color = ((alpha_first << 8) & 0xff000000) | (red_first & 0xff0000)
- | ((green_first >> 8) & 0xff00) | (blue_first >> 16);
+ const QRgba64 color = qRgba64(red_first >> 16, green_first >> 16, blue_first >> 16, alpha_first >> 16);
if (colorInterpolation)
colorTable[i] = color;
@@ -4280,7 +4278,7 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
return;
}
- uint current_color = ARGB_COMBINE_ALPHA(stops[0].second.rgba(), opacity);
+ QRgba64 current_color = combineAlpha256(stops[0].second.rgba64(), opacity);
if (stopCount == 1) {
current_color = qPremultiply(current_color);
for (int i = 0; i < size; ++i)
@@ -4293,7 +4291,7 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
qreal end_pos = stops[stopCount-1].first;
int pos = 0; // The position in the color table.
- uint next_color;
+ QRgba64 next_color;
qreal incr = 1 / qreal(size); // the double increment.
qreal dpos = 1.5 * incr; // current position in gradient stop list (0 to 1)
@@ -4317,8 +4315,8 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
++current_stop;
if (current_stop != 0)
- current_color = ARGB_COMBINE_ALPHA(stops[current_stop].second.rgba(), opacity);
- next_color = ARGB_COMBINE_ALPHA(stops[current_stop+1].second.rgba(), opacity);
+ current_color = combineAlpha256(stops[current_stop].second.rgba64(), opacity);
+ next_color = combineAlpha256(stops[current_stop+1].second.rgba64(), opacity);
if (colorInterpolation) {
current_color = qPremultiply(current_color);
@@ -4337,9 +4335,9 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
int idist = 256 - dist;
if (colorInterpolation)
- colorTable[pos] = INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist);
+ colorTable[pos] = interpolate256(current_color, idist, next_color, dist);
else
- colorTable[pos] = qPremultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
+ colorTable[pos] = qPremultiply(interpolate256(current_color, idist, next_color, dist));
++pos;
dpos += incr;
@@ -4358,8 +4356,8 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
if (skip == 1)
current_color = next_color;
else
- current_color = ARGB_COMBINE_ALPHA(stops[current_stop].second.rgba(), opacity);
- next_color = ARGB_COMBINE_ALPHA(stops[current_stop+1].second.rgba(), opacity);
+ current_color = combineAlpha256(stops[current_stop].second.rgba64(), opacity);
+ next_color = combineAlpha256(stops[current_stop+1].second.rgba64(), opacity);
if (colorInterpolation) {
if (skip != 1)
@@ -4376,7 +4374,7 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
}
// After last point
- current_color = qPremultiply(ARGB_COMBINE_ALPHA(stops[stopCount - 1].second.rgba(), opacity));
+ current_color = qPremultiply(combineAlpha256(stops[stopCount - 1].second.rgba64(), opacity));
while (pos < size - 1) {
colorTable[pos] = current_color;
++pos;
@@ -4409,12 +4407,9 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode
case Qt::SolidPattern: {
type = Solid;
QColor c = qbrush_color(brush);
- QRgb rgba = c.rgba();
- solid.color = qPremultiply(ARGB_COMBINE_ALPHA(rgba, alpha));
- if ((solid.color & 0xff000000) == 0
- && compositionMode == QPainter::CompositionMode_SourceOver) {
+ solid.color = qPremultiply(combineAlpha256(c.rgba64(), alpha));
+ if (solid.color.isTransparent() && compositionMode == QPainter::CompositionMode_SourceOver)
type = None;
- }
break;
}
@@ -4423,7 +4418,7 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode
type = LinearGradient;
const QLinearGradient *g = static_cast<const QLinearGradient *>(brush.gradient());
gradient.alphaColor = !brush.isOpaque() || alpha != 256;
- gradient.colorTable = const_cast<uint*>(qt_gradient_cache()->getBuffer(*g, alpha));
+ gradient.colorTable = const_cast<QRgba64*>(qt_gradient_cache()->getBuffer(*g, alpha));
gradient.spread = g->spread();
QLinearGradientData &linearData = gradient.linear;
@@ -4440,7 +4435,7 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode
type = RadialGradient;
const QRadialGradient *g = static_cast<const QRadialGradient *>(brush.gradient());
gradient.alphaColor = !brush.isOpaque() || alpha != 256;
- gradient.colorTable = const_cast<uint*>(qt_gradient_cache()->getBuffer(*g, alpha));
+ gradient.colorTable = const_cast<QRgba64*>(qt_gradient_cache()->getBuffer(*g, alpha));
gradient.spread = g->spread();
QRadialGradientData &radialData = gradient.radial;
@@ -4461,7 +4456,7 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode
type = ConicalGradient;
const QConicalGradient *g = static_cast<const QConicalGradient *>(brush.gradient());
gradient.alphaColor = !brush.isOpaque() || alpha != 256;
- gradient.colorTable = const_cast<uint*>(qt_gradient_cache()->getBuffer(*g, alpha));
+ gradient.colorTable = const_cast<QRgba64*>(qt_gradient_cache()->getBuffer(*g, alpha));
gradient.spread = QGradient::RepeatSpread;
QConicalGradientData &conicalData = gradient.conical;
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 20608e5aee..5dcab11f0a 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -219,18 +219,18 @@ QTransform QPainterPrivate::viewTransform() const
return QTransform();
}
-int QPainterPrivate::effectiveDevicePixelRatio() const
+qreal QPainterPrivate::effectiveDevicePixelRatio() const
{
// Special cases for devices that does not support PdmDevicePixelRatio go here:
if (device->devType() == QInternal::Printer)
- return 1;
+ return qreal(1);
- return qMax(1, device->metric(QPaintDevice::PdmDevicePixelRatio));
+ return qMax(qreal(1), device->devicePixelRatioF());
}
QTransform QPainterPrivate::hidpiScaleTransform() const
{
- int devicePixelRatio = effectiveDevicePixelRatio();
+ const qreal devicePixelRatio = effectiveDevicePixelRatio();
return QTransform::fromScale(devicePixelRatio, devicePixelRatio);
}
@@ -3154,7 +3154,7 @@ void QPainter::shear(qreal sh, qreal sv)
/*!
\fn void QPainter::rotate(qreal angle)
- Rotates the coordinate system clockwise. The given \a angle parameter uses degree unit.
+ Rotates the coordinate system clockwise. The given \a angle parameter is in degrees.
\sa setWorldTransform(), {QPainter#Coordinate Transformations}{Coordinate Transformations}
*/
@@ -5110,7 +5110,7 @@ void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm)
x += d->state->matrix.dx();
y += d->state->matrix.dy();
}
- int scale = pm.devicePixelRatio();
+ qreal scale = pm.devicePixelRatio();
d->engine->drawPixmap(QRectF(x, y, w / scale, h / scale), pm, QRectF(0, 0, w, h));
}
}
@@ -7470,7 +7470,7 @@ start_lengthVariant:
}
}
- QList<QTextLayout::FormatRange> underlineFormats;
+ QVector<QTextLayout::FormatRange> underlineFormats;
int length = offset - old_offset;
if ((hidemnmemonic || showmnemonic) && maxUnderlines > 0) {
QChar *cout = text.data() + old_offset;
@@ -7526,6 +7526,7 @@ start_lengthVariant:
if (engine.option.tabs().isEmpty() && ta) {
QList<qreal> tabs;
+ tabs.reserve(tabarraylen);
for (int i = 0; i < tabarraylen; i++)
tabs.append(qreal(ta[i]));
engine.option.setTabArray(tabs);
@@ -7544,7 +7545,7 @@ start_lengthVariant:
engine.forceJustification = true;
QTextLayout textLayout(&engine);
textLayout.setCacheEnabled(true);
- textLayout.setAdditionalFormats(underlineFormats);
+ textLayout.setFormats(underlineFormats);
if (finalText.isEmpty()) {
height = fm.height();
diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h
index 51776a9642..8e2d17d3a5 100644
--- a/src/gui/painting/qpainter.h
+++ b/src/gui/painting/qpainter.h
@@ -374,7 +374,7 @@ public:
inline void drawPixmap(int x, int y, int w, int h, const QPixmap &pm);
void drawPixmapFragments(const PixmapFragment *fragments, int fragmentCount,
- const QPixmap &pixmap, PixmapFragmentHints hints = 0);
+ const QPixmap &pixmap, PixmapFragmentHints hints = PixmapFragmentHints());
void drawImage(const QRectF &targetRect, const QImage &image, const QRectF &sourceRect,
Qt::ImageConversionFlags flags = Qt::AutoColor);
@@ -408,9 +408,9 @@ public:
void drawText(const QPointF &p, const QString &str, int tf, int justificationPadding);
- void drawText(const QRectF &r, int flags, const QString &text, QRectF *br=0);
- void drawText(const QRect &r, int flags, const QString &text, QRect *br=0);
- inline void drawText(int x, int y, int w, int h, int flags, const QString &text, QRect *br=0);
+ void drawText(const QRectF &r, int flags, const QString &text, QRectF *br = Q_NULLPTR);
+ void drawText(const QRect &r, int flags, const QString &text, QRect *br = Q_NULLPTR);
+ inline void drawText(int x, int y, int w, int h, int flags, const QString &text, QRect *br = Q_NULLPTR);
void drawText(const QRectF &r, const QString &text, const QTextOption &o = QTextOption());
@@ -453,7 +453,7 @@ public:
static void setRedirected(const QPaintDevice *device, QPaintDevice *replacement,
const QPoint& offset = QPoint());
- static QPaintDevice *redirected(const QPaintDevice *device, QPoint *offset = 0);
+ static QPaintDevice *redirected(const QPaintDevice *device, QPoint *offset = Q_NULLPTR);
static void restoreRedirected(const QPaintDevice *device);
void beginNativePainting();
diff --git a/src/gui/painting/qpainter_p.h b/src/gui/painting/qpainter_p.h
index 7c32dc1694..e8b675365f 100644
--- a/src/gui/painting/qpainter_p.h
+++ b/src/gui/painting/qpainter_p.h
@@ -53,7 +53,6 @@
#include "QtGui/qpainter.h"
#include "QtGui/qpainterpath.h"
#include "QtGui/qpaintengine.h"
-#include <QtCore/qhash.h>
#include <private/qpen_p.h>
@@ -241,7 +240,7 @@ public:
}
QTransform viewTransform() const;
- int effectiveDevicePixelRatio() const;
+ qreal effectiveDevicePixelRatio() const;
QTransform hidpiScaleTransform() const;
static bool attachPainterPrivate(QPainter *q, QPaintDevice *pdev);
void detachPainterPrivate(QPainter *q);
diff --git a/src/gui/painting/qpathclipper.cpp b/src/gui/painting/qpathclipper.cpp
index 0798418c17..3a686bd209 100644
--- a/src/gui/painting/qpathclipper.cpp
+++ b/src/gui/painting/qpathclipper.cpp
@@ -548,11 +548,11 @@ void SegmentTree::produceIntersectionsLeaf(const TreeNode &node, int segment)
for (int k = 0; k < m_intersections.size(); ++k) {
QPathSegments::Intersection i_isect, j_isect;
- i_isect.vertex = j_isect.vertex = m_segments.addPoint(m_intersections.at(k).pos);
-
i_isect.t = m_intersections.at(k).alphaA;
j_isect.t = m_intersections.at(k).alphaB;
+ i_isect.vertex = j_isect.vertex = m_segments.addPoint(m_intersections.at(k).pos);
+
i_isect.next = 0;
j_isect.next = 0;
@@ -1889,10 +1889,10 @@ bool QPathClipper::handleCrossingEdges(QWingedEdge &list, qreal y, ClipperMode m
namespace {
-QList<QPainterPath> toSubpaths(const QPainterPath &path)
+QVector<QPainterPath> toSubpaths(const QPainterPath &path)
{
- QList<QPainterPath> subpaths;
+ QVector<QPainterPath> subpaths;
if (path.isEmpty())
return subpaths;
@@ -2092,7 +2092,7 @@ QPainterPath clip(const QPainterPath &path, qreal t)
QPainterPath intersectPath(const QPainterPath &path, const QRectF &rect)
{
- QList<QPainterPath> subpaths = toSubpaths(path);
+ QVector<QPainterPath> subpaths = toSubpaths(path);
QPainterPath result;
result.setFillRule(path.fillRule());
diff --git a/src/gui/painting/qpathclipper_p.h b/src/gui/painting/qpathclipper_p.h
index 36330052dd..d1caea4a1a 100644
--- a/src/gui/painting/qpathclipper_p.h
+++ b/src/gui/painting/qpathclipper_p.h
@@ -156,9 +156,8 @@ class QPathSegments
{
public:
struct Intersection {
- int vertex;
qreal t;
-
+ int vertex;
int next;
bool operator<(const Intersection &o) const {
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index 54e656e339..d746ab9379 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -377,8 +377,8 @@ QByteArray QPdf::generateDashes(const QPen &pen)
s << dw;
}
s << ']';
- //qDebug() << "dasharray: pen has" << dasharray;
- //qDebug() << " => " << result;
+ s << pen.dashOffset() * w;
+ s << " d\n";
return result;
}
@@ -996,6 +996,34 @@ void QPdfEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
*d->currentPage << "Q\n";
}
+void QPdfEngine::drawHyperlink(const QRectF &r, const QUrl &url)
+{
+ Q_D(QPdfEngine);
+
+ const uint annot = d->addXrefEntry(-1);
+ const QByteArray urlascii = url.toEncoded();
+ int len = urlascii.size();
+ QVarLengthArray<char> url_esc(0);
+ for (int j = 0; j < len; j++) {
+ if (urlascii[j] == '(' || urlascii[j] == ')' || urlascii[j] == '\\')
+ url_esc.append('\\');
+ url_esc.append(urlascii[j]);
+ }
+ url_esc.append('\0');
+
+ char buf[256];
+ const QRectF rr = d->pageMatrix().mapRect(r);
+ d->xprintf("<<\n/Type /Annot\n/Subtype /Link\n/Rect [");
+ d->xprintf("%s ", qt_real_to_string(rr.left(), buf));
+ d->xprintf("%s ", qt_real_to_string(rr.top(), buf));
+ d->xprintf("%s ", qt_real_to_string(rr.right(), buf));
+ d->xprintf("%s", qt_real_to_string(rr.bottom(), buf));
+ d->xprintf("]\n/Border [0 0 0]\n/A <<\n");
+ d->xprintf("/Type /Action\n/S /URI\n/URI (%s)\n", url_esc.constData());
+ d->xprintf(">>\n>>\n");
+ d->xprintf("endobj\n");
+ d->currentPage->annotations.append(annot);
+}
void QPdfEngine::updateState(const QPaintEngineState &state)
{
@@ -1181,7 +1209,7 @@ void QPdfEngine::setPen()
}
*d->currentPage << pdfJoinStyle << "j ";
- *d->currentPage << QPdf::generateDashes(d->pen) << " 0 d\n";
+ *d->currentPage << QPdf::generateDashes(d->pen);
}
@@ -1318,6 +1346,9 @@ int QPdfEngine::metric(QPaintDevice::PaintDeviceMetric metricType) const
case QPaintDevice::PdmDevicePixelRatio:
val = 1;
break;
+ case QPaintDevice::PdmDevicePixelRatioScaled:
+ val = 1 * QPaintDevice::devicePixelRatioFScale();
+ break;
default:
qWarning("QPdfWriter::metric: Invalid metric command");
return 0;
@@ -1467,7 +1498,7 @@ void QPdfEnginePrivate::writeInfo()
printString(creator);
xprintf("\n/Producer ");
printString(QString::fromLatin1("Qt " QT_VERSION_STR));
- QDateTime now = QDateTime::currentDateTime().toUTC();
+ QDateTime now = QDateTime::currentDateTimeUtc();
QTime t = now.time();
QDate d = now.date();
xprintf("\n/CreationDate (D:%d%02d%02d%02d%02d%02d)\n",
@@ -1762,7 +1793,7 @@ void QPdfEnginePrivate::printString(const QString &string) {
array.append(part[j]);
}
}
- array.append(")");
+ array.append(')');
write(array);
}
@@ -1952,7 +1983,9 @@ int QPdfEnginePrivate::createShadingFunction(const QGradient *gradient, int from
stops.append(QGradientStop(1, stops.at(stops.size() - 1).second));
QVector<int> functions;
- for (int i = 0; i < stops.size() - 1; ++i) {
+ const int numStops = stops.size();
+ functions.reserve(numStops - 1);
+ for (int i = 0; i < numStops - 1; ++i) {
int f = addXrefEntry(-1);
QByteArray data;
QPdf::ByteStream s(&data);
@@ -2098,9 +2131,9 @@ int QPdfEnginePrivate::generateLinearGradientShader(const QLinearGradient *gradi
int QPdfEnginePrivate::generateRadialGradientShader(const QRadialGradient *gradient, const QTransform &matrix, bool alpha)
{
QPointF p1 = gradient->center();
- double r1 = gradient->centerRadius();
+ qreal r1 = gradient->centerRadius();
QPointF p0 = gradient->focalPoint();
- double r0 = gradient->focalRadius();
+ qreal r0 = gradient->focalRadius();
Q_ASSERT(gradient->coordinateMode() == QGradient::LogicalMode);
diff --git a/src/gui/painting/qpdf_p.h b/src/gui/painting/qpdf_p.h
index 94e74f30b9..de30744ca2 100644
--- a/src/gui/painting/qpdf_p.h
+++ b/src/gui/painting/qpdf_p.h
@@ -188,6 +188,8 @@ public:
Qt::ImageConversionFlags flags = Qt::AutoColor) Q_DECL_OVERRIDE;
void drawTiledPixmap (const QRectF & rectangle, const QPixmap & pixmap, const QPointF & point) Q_DECL_OVERRIDE;
+ void drawHyperlink(const QRectF &r, const QUrl &url);
+
void updateState(const QPaintEngineState &state) Q_DECL_OVERRIDE;
int metric(QPaintDevice::PaintDeviceMetric metricType) const;
@@ -243,7 +245,7 @@ public:
QPointF brushOrigin;
QBrush brush;
QPen pen;
- QList<QPainterPath> clips;
+ QVector<QPainterPath> clips;
bool clipEnabled;
bool allClipped;
bool hasPen;
diff --git a/src/gui/painting/qpen.cpp b/src/gui/painting/qpen.cpp
index 6263d18b01..073d254b49 100644
--- a/src/gui/painting/qpen.cpp
+++ b/src/gui/painting/qpen.cpp
@@ -980,6 +980,7 @@ QDataStream &operator>>(QDataStream &s, QPen &p)
quint32 numDashes;
s >> numDashes;
double dash;
+ dashPattern.reserve(numDashes);
for (quint32 i = 0; i < numDashes; ++i) {
s >> dash;
dashPattern << dash;
diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp
index 22f5662c34..5ac903c71d 100644
--- a/src/gui/painting/qplatformbackingstore.cpp
+++ b/src/gui/painting/qplatformbackingstore.cpp
@@ -48,6 +48,22 @@
#include <qpa/qplatformgraphicsbuffer.h>
#include <qpa/qplatformgraphicsbufferhelper.h>
+#ifndef GL_TEXTURE_BASE_LEVEL
+#define GL_TEXTURE_BASE_LEVEL 0x813C
+#endif
+#ifndef GL_TEXTURE_MAX_LEVEL
+#define GL_TEXTURE_MAX_LEVEL 0x813D
+#endif
+#ifndef GL_UNPACK_ROW_LENGTH
+#define GL_UNPACK_ROW_LENGTH 0x0CF2
+#endif
+#ifndef GL_RGB10_A2
+#define GL_RGB10_A2 0x8059
+#endif
+#ifndef GL_UNSIGNED_INT_2_10_10_10_REV
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#endif
+
QT_BEGIN_NAMESPACE
class QPlatformBackingStorePrivate
@@ -82,6 +98,7 @@ public:
mutable GLuint textureId;
mutable QSize textureSize;
mutable bool needsSwizzle;
+ mutable bool premultiplied;
QOpenGLTextureBlitter *blitter;
#endif
};
@@ -107,7 +124,7 @@ public:
{
}
- QList<QBackingstoreTextureInfo> textures;
+ QVector<QBackingstoreTextureInfo> textures;
bool locked;
};
@@ -221,14 +238,16 @@ static inline QRect deviceRect(const QRect &rect, QWindow *window)
return deviceRect;
}
-static QRegion deviceRegion(const QRegion &region, QWindow *window)
+static QRegion deviceRegion(const QRegion &region, QWindow *window, const QPoint &offset)
{
- if (!(window->devicePixelRatio() > 1))
+ if (offset.isNull() && window->devicePixelRatio() <= 1)
return region;
QVector<QRect> rects;
- foreach (QRect rect, region.rects())
- rects.append(deviceRect(rect, window));
+ const QVector<QRect> regionRects = region.rects();
+ rects.reserve(regionRects.count());
+ foreach (const QRect &rect, regionRects)
+ rects.append(deviceRect(rect.translated(offset), window));
QRegion deviceRegion;
deviceRegion.setRects(rects.constData(), rects.count());
@@ -241,13 +260,17 @@ static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight)
topLeftRect.width(), topLeftRect.height());
}
-static void blit(const QPlatformTextureList *textures, int idx, QWindow *window, const QRect &deviceWindowRect,
- QOpenGLTextureBlitter *blitter)
+static void blitTextureForWidget(const QPlatformTextureList *textures, int idx, QWindow *window, const QRect &deviceWindowRect,
+ QOpenGLTextureBlitter *blitter, const QPoint &offset)
{
- const QRect rectInWindow = textures->geometry(idx);
- QRect clipRect = textures->clipRect(idx);
+ const QRect clipRect = textures->clipRect(idx);
if (clipRect.isEmpty())
- clipRect = QRect(QPoint(0, 0), rectInWindow.size());
+ return;
+
+ QRect rectInWindow = textures->geometry(idx);
+ // relative to the TLW, not necessarily our window (if the flush is for a native child widget), have to adjust
+ rectInWindow.translate(-offset);
+
const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft());
const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height());
@@ -269,7 +292,9 @@ static void blit(const QPlatformTextureList *textures, int idx, QWindow *window,
and composes using OpenGL. May be reimplemented in subclasses if there
is a more efficient native way to do it.
- Note that the \a offset parameter is currently unused.
+ \note \a region is relative to the window which may not be top-level in case
+ \a window corresponds to a native child widget. \a offset is the position of
+ the native child relative to the top-level window.
*/
void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &region,
@@ -277,13 +302,16 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
QPlatformTextureList *textures, QOpenGLContext *context,
bool translucentBackground)
{
- Q_UNUSED(offset);
+ if (!qt_window_private(window)->receivedExpose)
+ return;
if (!context->makeCurrent(window)) {
qWarning("composeAndFlush: makeCurrent() failed");
return;
}
+ QWindowPrivate::get(window)->lastComposeTime.start();
+
QOpenGLFunctions *funcs = context->functions();
funcs->glViewport(0, 0, window->width() * window->devicePixelRatio(), window->height() * window->devicePixelRatio());
funcs->glClearColor(0, 0, 0, translucentBackground ? 0 : 1);
@@ -301,16 +329,9 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
// Textures for renderToTexture widgets.
for (int i = 0; i < textures->count(); ++i) {
if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop))
- blit(textures, i, window, deviceWindowRect, d_ptr->blitter);
+ blitTextureForWidget(textures, i, window, deviceWindowRect, d_ptr->blitter, offset);
}
- funcs->glEnable(GL_BLEND);
- funcs->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- // Do not write out alpha. We need blending, but only for RGB. The toplevel may have
- // alpha enabled in which case blending (writing out < 1.0 alpha values) would lead to
- // semi-transparency even when it is not wanted.
- funcs->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
-
// Backingstore texture with the normal widgets.
GLuint textureId = 0;
QOpenGLTextureBlitter::Origin origin = QOpenGLTextureBlitter::OriginTopLeft;
@@ -320,18 +341,17 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
funcs->glDeleteTextures(1, &d_ptr->textureId);
funcs->glGenTextures(1, &d_ptr->textureId);
funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId);
-#ifndef QT_OPENGL_ES_2
- if (!QOpenGLContext::currentContext()->isOpenGLES()) {
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
}
-#endif
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- if (QPlatformGraphicsBufferHelper::lockAndBindToTexture(graphicsBuffer, &d_ptr->needsSwizzle)) {
+ if (QPlatformGraphicsBufferHelper::lockAndBindToTexture(graphicsBuffer, &d_ptr->needsSwizzle, &d_ptr->premultiplied)) {
d_ptr->textureSize = graphicsBuffer->size();
} else {
d_ptr->textureSize = QSize(0,0);
@@ -340,7 +360,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
graphicsBuffer->unlock();
} else if (!region.isEmpty()){
funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId);
- QPlatformGraphicsBufferHelper::lockAndBindToTexture(graphicsBuffer, &d_ptr->needsSwizzle);
+ QPlatformGraphicsBufferHelper::lockAndBindToTexture(graphicsBuffer, &d_ptr->needsSwizzle, &d_ptr->premultiplied);
}
if (graphicsBuffer->origin() == QPlatformGraphicsBuffer::OriginBottomLeft)
@@ -348,17 +368,29 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
textureId = d_ptr->textureId;
} else {
TextureFlags flags = 0;
- textureId = toTexture(deviceRegion(region, window), &d_ptr->textureSize, &flags);
+ textureId = toTexture(deviceRegion(region, window, offset), &d_ptr->textureSize, &flags);
d_ptr->needsSwizzle = (flags & TextureSwizzle) != 0;
+ d_ptr->premultiplied = (flags & TexturePremultiplied) != 0;
if (flags & TextureFlip)
origin = QOpenGLTextureBlitter::OriginBottomLeft;
}
+ funcs->glEnable(GL_BLEND);
+ if (d_ptr->premultiplied)
+ funcs->glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
+ else
+ funcs->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
+
if (textureId) {
- QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(QRect(QPoint(), d_ptr->textureSize), deviceWindowRect);
if (d_ptr->needsSwizzle)
d_ptr->blitter->setSwizzleRB(true);
- d_ptr->blitter->blit(textureId, target, origin);
+ // The backingstore is for the entire tlw.
+ // In case of native children offset tells the position relative to the tlw.
+ const QRect srcRect = toBottomLeftRect(deviceWindowRect.translated(offset), d_ptr->textureSize.height());
+ const QMatrix3x3 source = QOpenGLTextureBlitter::sourceTransform(srcRect,
+ d_ptr->textureSize,
+ origin);
+ d_ptr->blitter->blit(textureId, QMatrix4x4(), source);
if (d_ptr->needsSwizzle)
d_ptr->blitter->setSwizzleRB(false);
}
@@ -366,10 +398,9 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
// Textures for renderToTexture widgets that have WA_AlwaysStackOnTop set.
for (int i = 0; i < textures->count(); ++i) {
if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop))
- blit(textures, i, window, deviceWindowRect, d_ptr->blitter);
+ blitTextureForWidget(textures, i, window, deviceWindowRect, d_ptr->blitter, offset);
}
- funcs->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
funcs->glDisable(GL_BLEND);
d_ptr->blitter->release();
@@ -414,6 +445,8 @@ QImage QPlatformBackingStore::toImage() const
If the image has to be flipped (e.g. because the texture is attached to an FBO), \a
flags will be set to include \c TextureFlip.
+
+ \note \a dirtyRegion is relative to the backingstore so no adjustment is needed.
*/
GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textureSize, TextureFlags *flags) const
{
@@ -423,10 +456,50 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
QImage image = toImage();
QSize imageSize = image.size();
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ GLenum internalFormat = GL_RGBA;
+ GLuint pixelType = GL_UNSIGNED_BYTE;
+
+ bool needsConversion = false;
*flags = 0;
- if (image.format() == QImage::Format_RGB32)
+ switch (image.format()) {
+ case QImage::Format_ARGB32_Premultiplied:
+ *flags |= TexturePremultiplied;
+ // no break
+ case QImage::Format_RGB32:
+ case QImage::Format_ARGB32:
*flags |= TextureSwizzle;
-
+ break;
+ case QImage::Format_RGBA8888_Premultiplied:
+ *flags |= TexturePremultiplied;
+ // no break
+ case QImage::Format_RGBX8888:
+ case QImage::Format_RGBA8888:
+ break;
+ case QImage::Format_BGR30:
+ case QImage::Format_A2BGR30_Premultiplied:
+ if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
+ pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
+ internalFormat = GL_RGB10_A2;
+ *flags |= TexturePremultiplied;
+ } else {
+ needsConversion = true;
+ }
+ break;
+ case QImage::Format_RGB30:
+ case QImage::Format_A2RGB30_Premultiplied:
+ if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
+ pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
+ internalFormat = GL_RGB10_A2;
+ *flags |= TextureSwizzle | TexturePremultiplied;
+ } else {
+ needsConversion = true;
+ }
+ break;
+ default:
+ needsConversion = true;
+ break;
+ }
if (imageSize.isEmpty()) {
*textureSize = imageSize;
return 0;
@@ -440,44 +513,37 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
*textureSize = imageSize;
- // Fast path for RGB32 and RGBA8888, convert everything else to RGBA8888.
- if (image.format() != QImage::Format_RGB32 && image.format() != QImage::Format_RGBA8888)
+ if (needsConversion)
image = image.convertToFormat(QImage::Format_RGBA8888);
- QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
-
+ QOpenGLFunctions *funcs = ctx->functions();
if (resized) {
if (d_ptr->textureId)
funcs->glDeleteTextures(1, &d_ptr->textureId);
funcs->glGenTextures(1, &d_ptr->textureId);
funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId);
-#ifndef QT_OPENGL_ES_2
- if (!QOpenGLContext::currentContext()->isOpenGLES()) {
+ if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
}
-#endif
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageSize.width(), imageSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, imageSize.width(), imageSize.height(), 0, GL_RGBA, pixelType,
const_cast<uchar*>(image.constBits()));
} else {
funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId);
QRect imageRect = image.rect();
QRect rect = dirtyRegion.boundingRect() & imageRect;
-#ifndef QT_OPENGL_ES_2
- if (!QOpenGLContext::currentContext()->isOpenGLES()) {
+ if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, image.width());
- funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
image.constScanLine(rect.y()) + rect.x() * 4);
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- } else
-#endif
- {
+ } else {
// if the rect is wide enough it's cheaper to just
// extend it instead of doing an image copy
if (rect.width() >= imageRect.width() / 2) {
@@ -489,10 +555,10 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
// OpenGL instead of copying, since there's no gap between scanlines
if (rect.width() == imageRect.width()) {
- funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
image.constScanLine(rect.y()));
} else {
- funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
image.copy(rect).constBits());
}
}
diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h
index eac97e9cf6..9c8da0d1db 100644
--- a/src/gui/painting/qplatformbackingstore.h
+++ b/src/gui/painting/qplatformbackingstore.h
@@ -118,7 +118,8 @@ public:
virtual QImage toImage() const;
enum TextureFlag {
TextureSwizzle = 0x01,
- TextureFlip = 0x02
+ TextureFlip = 0x02,
+ TexturePremultiplied = 0x04,
};
Q_DECLARE_FLAGS(TextureFlags, TextureFlag)
virtual GLuint toTexture(const QRegion &dirtyRegion, QSize *textureSize, TextureFlags *flags) const;
diff --git a/src/gui/painting/qpolygon.h b/src/gui/painting/qpolygon.h
index 1549ebe2b5..1e503c03b7 100644
--- a/src/gui/painting/qpolygon.h
+++ b/src/gui/painting/qpolygon.h
@@ -52,11 +52,19 @@ public:
inline QPolygon() {}
inline ~QPolygon() {}
inline explicit QPolygon(int size);
- inline QPolygon(const QPolygon &a) : QVector<QPoint>(a) {}
inline /*implicit*/ QPolygon(const QVector<QPoint> &v) : QVector<QPoint>(v) {}
+#ifdef Q_COMPILER_RVALUE_REFS
+ /*implicit*/ QPolygon(QVector<QPoint> &&v) Q_DECL_NOTHROW : QVector<QPoint>(std::move(v)) {}
+#endif
QPolygon(const QRect &r, bool closed=false);
QPolygon(int nPoints, const int *points);
- inline void swap(QPolygon &other) { QVector<QPoint>::swap(other); } // prevent QVector<QPoint><->QPolygon swaps
+ QPolygon(const QPolygon &other) : QVector<QPoint>(other) {}
+#ifdef Q_COMPILER_RVALUE_REFS
+ QPolygon(QPolygon &&other) Q_DECL_NOTHROW : QVector<QPoint>(std::move(other)) {}
+ QPolygon &operator=(QPolygon &&other) Q_DECL_NOTHROW { swap(other); return *this; }
+#endif
+ QPolygon &operator=(const QPolygon &other) { QVector<QPoint>::operator=(other); return *this; }
+ void swap(QPolygon &other) Q_DECL_NOTHROW { QVector<QPoint>::swap(other); } // prevent QVector<QPoint><->QPolygon swaps
operator QVariant() const;
@@ -126,10 +134,18 @@ public:
inline QPolygonF() {}
inline ~QPolygonF() {}
inline explicit QPolygonF(int size);
- inline QPolygonF(const QPolygonF &a) : QVector<QPointF>(a) {}
inline /*implicit*/ QPolygonF(const QVector<QPointF> &v) : QVector<QPointF>(v) {}
+#ifdef Q_COMPILER_RVALUE_REFS
+ /* implicit */ QPolygonF(QVector<QPointF> &&v) Q_DECL_NOTHROW : QVector<QPointF>(std::move(v)) {}
+#endif
QPolygonF(const QRectF &r);
/*implicit*/ QPolygonF(const QPolygon &a);
+ inline QPolygonF(const QPolygonF &a) : QVector<QPointF>(a) {}
+#ifdef Q_COMPILER_RVALUE_REFS
+ QPolygonF(QPolygonF &&other) Q_DECL_NOTHROW : QVector<QPointF>(std::move(other)) {}
+ QPolygonF &operator=(QPolygonF &&other) Q_DECL_NOTHROW { swap(other); return *this; }
+#endif
+ QPolygonF &operator=(const QPolygonF &other) { QVector<QPointF>::operator=(other); return *this; }
inline void swap(QPolygonF &other) { QVector<QPointF>::swap(other); } // prevent QVector<QPointF><->QPolygonF swaps
operator QVariant() const;
diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp
index e6b777a30e..5e648eabf5 100644
--- a/src/gui/painting/qregion.cpp
+++ b/src/gui/painting/qregion.cpp
@@ -41,7 +41,7 @@
#include "qimage.h"
#include "qbitmap.h"
-#include <qdebug.h>
+#include <private/qdebug_p.h>
QT_BEGIN_NAMESPACE
@@ -422,11 +422,32 @@ QDataStream &operator>>(QDataStream &s, QRegion &r)
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug s, const QRegion &r)
{
- QVector<QRect> rects = r.rects();
- s.nospace() << "QRegion(size=" << rects.size() << "), "
- << "bounds = " << r.boundingRect() << '\n';
- for (int i=0; i<rects.size(); ++i)
- s << "- " << i << rects.at(i) << '\n';
+ QDebugStateSaver saver(s);
+ s.nospace();
+ s << "QRegion(";
+ if (r.isNull()) {
+ s << "null";
+ } else if (r.isEmpty()) {
+ s << "empty";
+ } else {
+ const QVector<QRect> rects = r.rects();
+ const int count = rects.size();
+ if (count > 1)
+ s << "size=" << count << ", bounds=(";
+ QtDebugUtils::formatQRect(s, r.boundingRect());
+ if (count > 1) {
+ s << ") - [";
+ for (int i = 0; i < count; ++i) {
+ if (i)
+ s << ", ";
+ s << '(';
+ QtDebugUtils::formatQRect(s, rects.at(i));
+ s << ')';
+ }
+ s << ']';
+ }
+ }
+ s << ')';
return s;
}
#endif
diff --git a/src/gui/painting/qrgb.h b/src/gui/painting/qrgb.h
index f7f2185bef..ca9fc03d14 100644
--- a/src/gui/painting/qrgb.h
+++ b/src/gui/painting/qrgb.h
@@ -58,10 +58,10 @@ inline Q_DECL_CONSTEXPR int qAlpha(QRgb rgb) // get alpha part of
{ return rgb >> 24; }
inline Q_DECL_CONSTEXPR QRgb qRgb(int r, int g, int b)// set RGB value
-{ return (0xffu << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); }
+{ return (0xffu << 24) | ((r & 0xffu) << 16) | ((g & 0xffu) << 8) | (b & 0xffu); }
inline Q_DECL_CONSTEXPR QRgb qRgba(int r, int g, int b, int a)// set RGBA value
-{ return ((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); }
+{ return ((a & 0xffu) << 24) | ((r & 0xffu) << 16) | ((g & 0xffu) << 8) | (b & 0xffu); }
inline Q_DECL_CONSTEXPR int qGray(int r, int g, int b)// convert R,G,B to gray 0..255
{ return (r*11+g*16+b*5)/32; }
diff --git a/src/gui/painting/qrgba64.h b/src/gui/painting/qrgba64.h
new file mode 100644
index 0000000000..fab9506ff2
--- /dev/null
+++ b/src/gui/painting/qrgba64.h
@@ -0,0 +1,228 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QRGBA64_H
+#define QRGBA64_H
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qprocessordetection.h>
+
+QT_BEGIN_NAMESPACE
+
+class QRgba64 {
+ quint64 rgba;
+
+ // Make sure that the representation always has the order: red green blue alpha, independent
+ // of byte order. This way, vector operations that assume 4 16-bit values see the correct ones.
+ enum {
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+ RedShift = 48,
+ GreenShift = 32,
+ BlueShift = 16,
+ AlphaShift = 0
+#else // little endian:
+ RedShift = 0,
+ GreenShift = 16,
+ BlueShift = 32,
+ AlphaShift = 48
+#endif
+ };
+
+ // No constructors are allowed in C++98, since this needs to be usable in a union.
+ // We however require one for constexprs in C++11/C++14
+#ifdef Q_COMPILER_CONSTEXPR
+ explicit Q_ALWAYS_INLINE Q_DECL_CONSTEXPR QRgba64(quint64 c) : rgba(c) { }
+#endif
+public:
+#ifdef Q_COMPILER_CONSTEXPR
+ Q_ALWAYS_INLINE Q_DECL_CONSTEXPR QRgba64() : rgba(0) { }
+#endif
+
+ Q_DECL_CONSTEXPR static
+ QRgba64 fromRgba64(quint64 c)
+ {
+#ifdef Q_COMPILER_CONSTEXPR
+ return QRgba64(c);
+#else
+ QRgba64 rgba64;
+ rgba64.rgba = c;
+ return rgba64;
+#endif
+ }
+ Q_DECL_CONSTEXPR static
+ QRgba64 fromRgba64(quint16 red, quint16 green, quint16 blue, quint16 alpha)
+ {
+ return fromRgba64(quint64(red) << RedShift
+ | quint64(green) << GreenShift
+ | quint64(blue) << BlueShift
+ | quint64(alpha) << AlphaShift);
+ }
+ Q_DECL_RELAXED_CONSTEXPR static QRgba64 fromRgba(quint8 red, quint8 green, quint8 blue, quint8 alpha)
+ {
+ QRgba64 rgb64 = fromRgba64(red, green, blue, alpha);
+ // Expand the range so that 0x00 maps to 0x0000 and 0xff maps to 0xffff.
+ rgb64.rgba |= rgb64.rgba << 8;
+ return rgb64;
+ }
+ Q_DECL_RELAXED_CONSTEXPR static
+ QRgba64 fromArgb32(uint rgb)
+ {
+ return fromRgba(rgb >> 16, rgb >> 8, rgb, rgb >> 24);
+ }
+
+ Q_DECL_CONSTEXPR bool isOpaque() const
+ {
+ return (rgba & alphaMask()) == alphaMask();
+ }
+ Q_DECL_CONSTEXPR bool isTransparent() const
+ {
+ return (rgba & alphaMask()) == 0;
+ }
+
+ Q_DECL_CONSTEXPR quint16 red() const { return rgba >> RedShift; }
+ Q_DECL_CONSTEXPR quint16 green() const { return rgba >> GreenShift; }
+ Q_DECL_CONSTEXPR quint16 blue() const { return rgba >> BlueShift; }
+ Q_DECL_CONSTEXPR quint16 alpha() const { return rgba >> AlphaShift; }
+ void setRed(quint16 _red) { rgba = (rgba & ~(Q_UINT64_C(0xffff) << RedShift)) | (quint64(_red) << RedShift); }
+ void setGreen(quint16 _green) { rgba = (rgba & ~(Q_UINT64_C(0xffff) << GreenShift)) | (quint64(_green) << GreenShift); }
+ void setBlue(quint16 _blue) { rgba = (rgba & ~(Q_UINT64_C(0xffff) << BlueShift)) | (quint64(_blue) << BlueShift); }
+ void setAlpha(quint16 _alpha) { rgba = (rgba & ~(Q_UINT64_C(0xffff) << AlphaShift)) | (quint64(_alpha) << AlphaShift); }
+
+ Q_DECL_CONSTEXPR quint8 red8() const { return div_257(red()); }
+ Q_DECL_CONSTEXPR quint8 green8() const { return div_257(green()); }
+ Q_DECL_CONSTEXPR quint8 blue8() const { return div_257(blue()); }
+ Q_DECL_CONSTEXPR quint8 alpha8() const { return div_257(alpha()); }
+ Q_DECL_CONSTEXPR uint toArgb32() const
+ {
+ return (alpha8() << 24) | (red8() << 16) | (green8() << 8) | blue8();
+ }
+ Q_DECL_CONSTEXPR ushort toRgb16() const
+ {
+ return (red() & 0xf800) | ((green() >> 10) << 5) | (blue() >> 11);
+ }
+
+ Q_DECL_RELAXED_CONSTEXPR QRgba64 premultiplied() const
+ {
+ const quint32 a = alpha();
+ const quint16 r = div_65535(red() * a);
+ const quint16 g = div_65535(green() * a);
+ const quint16 b = div_65535(blue() * a);
+ return fromRgba64(r, g, b, a);
+ }
+
+ Q_DECL_RELAXED_CONSTEXPR QRgba64 unpremultiplied() const
+ {
+#if Q_PROCESSOR_WORDSIZE < 8
+ return unpremultiplied_32bit();
+#else
+ return unpremultiplied_64bit();
+#endif
+ }
+
+ Q_DECL_CONSTEXPR operator quint64() const
+ {
+ return rgba;
+ }
+
+ QRgba64 operator=(quint64 _rgba)
+ {
+ rgba = _rgba;
+ return *this;
+ }
+
+private:
+ static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE quint64 alphaMask() { return Q_UINT64_C(0xffff) << AlphaShift; }
+
+ static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint div_257_floor(uint x) { return (x - (x >> 8)) >> 8; }
+ static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint div_257(uint x) { return div_257_floor(x + 128); }
+ static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint div_65535(uint x) { return (x + (x>>16) + 0x8000U) >> 16; }
+ Q_DECL_RELAXED_CONSTEXPR Q_ALWAYS_INLINE QRgba64 unpremultiplied_32bit() const
+ {
+ if (isOpaque() || isTransparent())
+ return *this;
+ const quint32 a = alpha();
+ const quint16 r = (quint32(red()) * 0xffff + a/2) / a;
+ const quint16 g = (quint32(green()) * 0xffff + a/2) / a;
+ const quint16 b = (quint32(blue()) * 0xffff + a/2) / a;
+ return fromRgba64(r, g, b, a);
+ }
+ Q_DECL_RELAXED_CONSTEXPR Q_ALWAYS_INLINE QRgba64 unpremultiplied_64bit() const
+ {
+ if (isOpaque() || isTransparent())
+ return *this;
+ const quint64 a = alpha();
+ const quint64 fa = (Q_UINT64_C(0xffff00008000) + a/2) / a;
+ const quint16 r = (red() * fa + 0x80000000) >> 32;
+ const quint16 g = (green() * fa + 0x80000000) >> 32;
+ const quint16 b = (blue() * fa + 0x80000000) >> 32;
+ return fromRgba64(r, g, b, a);
+ }
+};
+
+Q_DECLARE_TYPEINFO(QRgba64, Q_PRIMITIVE_TYPE);
+
+Q_DECL_CONSTEXPR inline QRgba64 qRgba64(quint16 r, quint16 g, quint16 b, quint16 a)
+{
+ return QRgba64::fromRgba64(r, g, b, a);
+}
+
+Q_DECL_CONSTEXPR inline QRgba64 qRgba64(quint64 c)
+{
+ return QRgba64::fromRgba64(c);
+}
+
+Q_DECL_RELAXED_CONSTEXPR inline QRgba64 qPremultiply(QRgba64 c)
+{
+ return c.premultiplied();
+}
+
+Q_DECL_RELAXED_CONSTEXPR inline QRgba64 qUnpremultiply(QRgba64 c)
+{
+ return c.unpremultiplied();
+}
+
+inline Q_DECL_CONSTEXPR uint qRed(QRgba64 rgb)
+{ return rgb.red8(); }
+
+inline Q_DECL_CONSTEXPR uint qGreen(QRgba64 rgb)
+{ return rgb.green8(); }
+
+inline Q_DECL_CONSTEXPR uint qBlue(QRgba64 rgb)
+{ return rgb.blue8(); }
+
+inline Q_DECL_CONSTEXPR uint qAlpha(QRgba64 rgb)
+{ return rgb.alpha8(); }
+
+QT_END_NAMESPACE
+
+#endif // QRGBA64_H
diff --git a/src/gui/painting/qrgba64.qdoc b/src/gui/painting/qrgba64.qdoc
new file mode 100644
index 0000000000..b786e91b03
--- /dev/null
+++ b/src/gui/painting/qrgba64.qdoc
@@ -0,0 +1,303 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QRgba64
+ \brief The QRgba64 struct contains a 64-bit RGB color.
+ \since 5.6
+
+ \ingroup painting
+ \inmodule QtGui
+
+ QRgba64 is a 64-bit data-structure containing four 16-bit color channels: Red, green, blue and alpha.
+
+ QRgba64 can be used a replacement for QRgb when higher precision is needed. In particular a
+ premultiplied QRgba64 can operate on unpremultiplied QRgb without loss of precision except
+ for alpha 0.
+
+ \sa QRgb, QColor
+*/
+
+/*!
+ \fn QRgba64 QRgba64::operator=(quint64 rgba)
+
+ Assigns the value \a rgba to this instance of QRgba64 and returns it.
+*/
+
+/*!
+ \fn static QRgba64 QRgba64::fromRgba64(quint16 r, quint16 g, quint16 b, quint16 a)
+
+ Returns the QRgba64 quadruplet (\a{r}, \a{g}, \a{b}, \a{a}).
+
+ \sa fromRgba()
+*/
+
+/*!
+ \fn static QRgba64 QRgba64::fromRgba64(quint64 c)
+
+ Returns \a c as a QRgba64 struct.
+
+ \sa fromArgb32()
+*/
+
+/*!
+ \fn static QRgba64 QRgba64::fromRgba(quint8 red, quint8 green, quint8 blue, quint8 alpha)
+
+ Constructs a QRgba64 value from the four 8-bit color channels \a red, \a green, \a blue and \a alpha.
+
+ \sa fromArgb32()
+*/
+
+/*!
+ \fn static QRgba64 QRgba64::fromArgb32(uint rgb)
+
+ Constructs a QRgba64 value from the 32bit ARGB value \a rgb.
+
+ \sa fromRgba()
+*/
+
+/*!
+ \fn bool QRgba64::isOpaque() const
+
+ Returns whether the color is fully opaque.
+
+ \sa isTransparent(), alpha()
+*/
+
+/*!
+ \fn bool QRgba64::isTransparent() const
+
+ Returns whether the color is transparent.
+
+ \sa isOpaque(), alpha()
+*/
+
+/*!
+ \fn quint16 QRgba64::red() const
+
+ Returns the 16-bit red color component.
+
+ \sa setRed()
+*/
+
+/*!
+ \fn QRgba64::setRed(quint16 red)
+
+ Sets the red color component of this color to \a red.
+
+ \sa red()
+*/
+
+/*!
+ \fn quint16 QRgba64::green() const
+
+ Returns the 16-bit green color component.
+
+ \sa setGreen()
+*/
+
+/*!
+ \fn QRgba64::setGreen(quint16 green)
+
+ Sets the green color component of this color to \a green.
+
+ \sa green()
+*/
+
+/*!
+ \fn quint16 QRgba64::blue() const
+
+ Returns the 16-bit blue color component.
+
+ \sa setBlue()
+*/
+
+/*!
+ \fn QRgba64::setBlue(quint16 blue)
+
+ Sets the blue color component of this color to \a blue.
+
+ \sa blue()
+*/
+
+/*!
+ \fn quint16 QRgba64::alpha() const
+
+ Returns the 16-bit alpha channel.
+
+ \sa setAlpha()
+*/
+
+/*!
+ \fn QRgba64::setAlpha(quint16 alpha)
+
+ Sets the alpha of this color to \a alpha.
+
+ \sa alpha()
+*/
+
+/*!
+ \fn quint8 QRgba64::red8() const
+
+ Returns the red color component as an 8-bit.
+*/
+
+/*!
+ \fn quint8 QRgba64::green8() const
+
+ Returns the green color component as an 8-bit.
+*/
+
+/*!
+ \fn quint8 QRgba64::blue8() const
+
+ Returns the blue color component as an 8-bit.
+*/
+
+/*!
+ \fn quint8 QRgba64::alpha8() const
+
+ Returns the alpha channel as an 8-bit.
+*/
+
+/*!
+ \fn uint QRgba64::toArgb32() const
+
+ Returns the color as a 32-bit ARGB value.
+
+ \sa fromArgb32()
+*/
+
+/*!
+ \fn ushort QRgba64::toRgb16() const
+
+ Returns the color as a 16-bit RGB value.
+
+ \sa toArgb32()
+*/
+
+/*!
+ \fn QRgba64 QRgba64::premultiplied() const
+
+ Returns the color with the alpha premultiplied.
+
+ \sa unpremultiplied()
+*/
+
+/*!
+ \fn QRgba64 QRgba64::unpremultiplied() const
+
+ Returns the color with the alpha unpremultiplied.
+
+ \sa premultiplied()
+*/
+
+/*!
+ \fn QRgba64::operator quint64() const
+
+ Returns the color as a 64bit unsigned integer
+*/
+
+/*!
+ \fn QRgba64 qRgba64(quint16 r, quint16 g, quint16 b, quint16 a)
+ \relates QColor
+ \since 5.6
+
+ Returns the QRgba64 quadruplet (\a{r}, \a{g}, \a{b}, \a{a}).
+
+ \sa qRgba()
+*/
+
+/*!
+ \fn QRgba64 qRgba64(quint64 c)
+ \relates QColor
+ \since 5.6
+
+ Returns \a c as a QRgba64 struct.
+
+ \sa qRgba()
+*/
+
+/*!
+ \fn QRgba64 qPremultiply(QRgba64 rgba64)
+ \since 5.6
+ \relates QColor
+
+ Converts an unpremultiplied QRgba64 quadruplet \a rgba64 into a premultiplied QRgba64 quadruplet.
+
+ \sa QRgba64::premultiplied(), qUnpremultiply()
+*/
+
+/*!
+ \fn QRgba64 qUnpremultiply(QRgba64 rgba64)
+ \since 5.6
+ \relates QColor
+
+ Converts a premultiplied QRgba64 quadruplet \a rgba64 into an unpremultiplied QRgba64 quadruplet.
+
+ \sa QRgba64::unpremultiplied(), qPremultiply()
+*/
+
+/*!
+ \fn uint qRed(QRgba64 rgba64)
+ \since 5.6
+ \relates QColor
+
+ Returns the red component of \a rgba64 as an 8-bit value.
+
+ \sa QRgba64::red8(), QColor::red()
+*/
+
+/*!
+ \fn uint qGreen(QRgba64 rgba64)
+ \since 5.6
+ \relates QColor
+
+ Returns the green component of \a rgba64 as an 8-bit value.
+
+ \sa QRgba64::green8(), QColor::green()
+*/
+
+/*!
+ \fn uint qBlue(QRgba64 rgba64)
+ \since 5.6
+ \relates QColor
+
+ Returns the blue component of \a rgba64 as an 8-bit value.
+
+ \sa QRgba64::blue8(), QColor::blue()
+*/
+
+/*!
+ \fn uint qAlpha(QRgba64 rgba64)
+ \since 5.6
+ \relates QColor
+
+ Returns the alpha component of \a rgba64 as an 8-bit value.
+
+ \sa QRgba64::alpha8(), QColor::alpha()
+*/
diff --git a/src/gui/painting/qrgba64_p.h b/src/gui/painting/qrgba64_p.h
new file mode 100644
index 0000000000..724658ad94
--- /dev/null
+++ b/src/gui/painting/qrgba64_p.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QRGBA64_P_H
+#define QRGBA64_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtGui/qrgba64.h>
+#include <QtGui/private/qdrawhelper_p.h>
+#include <private/qsimd_p.h>
+
+QT_BEGIN_NAMESPACE
+
+inline QRgba64 combineAlpha256(QRgba64 rgba64, uint alpha256)
+{
+ return QRgba64::fromRgba64(rgba64.red(), rgba64.green(), rgba64.blue(), (rgba64.alpha() * alpha256) >> 8);
+}
+
+inline QRgba64 multiplyAlpha256(QRgba64 rgba64, uint alpha256)
+{
+ return QRgba64::fromRgba64((rgba64.red() * alpha256) >> 8,
+ (rgba64.green() * alpha256) >> 8,
+ (rgba64.blue() * alpha256) >> 8,
+ (rgba64.alpha() * alpha256) >> 8);
+}
+
+inline QRgba64 multiplyAlpha65535(QRgba64 rgba64, uint alpha65535)
+{
+#ifdef __SSE2__
+ const __m128i va = _mm_shufflelo_epi16(_mm_cvtsi32_si128(alpha65535), _MM_SHUFFLE(0, 0, 0, 0));
+ __m128i vs = _mm_loadl_epi64((__m128i*)&rgba64);
+ vs = _mm_unpacklo_epi16(_mm_mullo_epi16(vs, va), _mm_mulhi_epu16(vs, va));
+ vs = _mm_add_epi32(vs, _mm_srli_epi32(vs, 16));
+ vs = _mm_add_epi32(vs, _mm_set1_epi32(0x8000));
+ vs = _mm_srai_epi32(vs, 16);
+ vs = _mm_packs_epi32(vs, _mm_setzero_si128());
+ _mm_storel_epi64((__m128i*)&rgba64, vs);
+ return rgba64;
+#else
+ return QRgba64::fromRgba64(qt_div_65535(rgba64.red() * alpha65535),
+ qt_div_65535(rgba64.green() * alpha65535),
+ qt_div_65535(rgba64.blue() * alpha65535),
+ qt_div_65535(rgba64.alpha() * alpha65535));
+#endif
+}
+
+inline QRgba64 multiplyAlpha255(QRgba64 rgba64, uint alpha255)
+{
+#ifdef __SSE2__
+ return multiplyAlpha65535(rgba64, alpha255 * 257);
+#else
+ return QRgba64::fromRgba64(qt_div_255(rgba64.red() * alpha255),
+ qt_div_255(rgba64.green() * alpha255),
+ qt_div_255(rgba64.blue() * alpha255),
+ qt_div_255(rgba64.alpha() * alpha255));
+#endif
+}
+
+inline QRgba64 interpolate256(QRgba64 x, uint alpha1, QRgba64 y, uint alpha2)
+{
+ return QRgba64::fromRgba64(multiplyAlpha256(x, alpha1) + multiplyAlpha256(y, alpha2));
+}
+
+inline QRgba64 interpolate255(QRgba64 x, uint alpha1, QRgba64 y, uint alpha2)
+{
+ return QRgba64::fromRgba64(multiplyAlpha255(x, alpha1) + multiplyAlpha255(y, alpha2));
+}
+
+inline QRgba64 interpolate65535(QRgba64 x, uint alpha1, QRgba64 y, uint alpha2)
+{
+ return QRgba64::fromRgba64(multiplyAlpha65535(x, alpha1) + multiplyAlpha65535(y, alpha2));
+}
+
+inline QRgba64 addWithSaturation(QRgba64 a, QRgba64 b)
+{
+#if defined(__SSE2__) && defined(Q_PROCESSOR_X86_64)
+ __m128i va = _mm_cvtsi64_si128((quint64)a);
+ __m128i vb = _mm_cvtsi64_si128((quint64)b);
+ va = _mm_adds_epu16(va, vb);
+ return QRgba64::fromRgba64(_mm_cvtsi128_si64(va));
+#else
+ return QRgba64::fromRgba64(qMin(a.red() + b.red(), 65535),
+ qMin(a.green() + b.green(), 65535),
+ qMin(a.blue() + b.blue(), 65535),
+ qMin(a.alpha() + b.alpha(), 65535));
+#endif
+}
+
+QT_END_NAMESPACE
+
+#endif // QRGBA64_P_H
diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp
index 4c879cf05d..97f82d16d3 100644
--- a/src/gui/painting/qtextureglyphcache.cpp
+++ b/src/gui/painting/qtextureglyphcache.cpp
@@ -42,16 +42,24 @@ QT_BEGIN_NAMESPACE
// #define CACHE_DEBUG
+// out-of-line to avoid vtable duplication, breaking e.g. RTTI
+QTextureGlyphCache::~QTextureGlyphCache()
+{
+}
+
int QTextureGlyphCache::calculateSubPixelPositionCount(glyph_t glyph) const
{
// Test 12 different subpixel positions since it factors into 3*4 so it gives
// the coverage we need.
- QList<QImage> images;
- for (int i=0; i<12; ++i) {
+ const int NumSubpixelPositions = 12;
+
+ QImage images[NumSubpixelPositions];
+ int numImages = 0;
+ for (int i = 0; i < NumSubpixelPositions; ++i) {
QImage img = textureMapForGlyph(glyph, QFixed::fromReal(i / 12.0));
- if (images.isEmpty()) {
+ if (numImages == 0) {
QPainterPath path;
QFixedPoint point;
m_current_fontengine->addGlyphsToPath(&glyph, &point, 1, &path, QTextItem::RenderFlags());
@@ -60,21 +68,21 @@ int QTextureGlyphCache::calculateSubPixelPositionCount(glyph_t glyph) const
if (path.isEmpty())
break;
- images.append(img);
+ images[numImages++] = qMove(img);
} else {
bool found = false;
- for (int j=0; j<images.size(); ++j) {
- if (images.at(j) == img) {
+ for (int j = 0; j < numImages; ++j) {
+ if (images[j] == img) {
found = true;
break;
}
}
if (!found)
- images.append(img);
+ images[numImages++] = qMove(img);
}
}
- return images.size();
+ return numImages;
}
bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const glyph_t *glyphs,
@@ -262,6 +270,11 @@ QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g, QFixed subPixelPosition
* QImageTextureGlyphCache
*/
+// out-of-line to avoid vtable duplication, breaking e.g. RTTI
+QImageTextureGlyphCache::~QImageTextureGlyphCache()
+{
+}
+
void QImageTextureGlyphCache::resizeTextureData(int width, int height)
{
m_image = m_image.copy(0, 0, width, height);
@@ -273,9 +286,9 @@ void QImageTextureGlyphCache::createTextureData(int width, int height)
case QFontEngine::Format_Mono:
m_image = QImage(width, height, QImage::Format_Mono);
break;
- case QFontEngine::Format_A8: {
+ case QFontEngine::Format_A8:
m_image = QImage(width, height, QImage::Format_Alpha8);
- break; }
+ break;
case QFontEngine::Format_A32:
m_image = QImage(width, height, QImage::Format_RGB32);
break;
diff --git a/src/gui/painting/qtextureglyphcache_p.h b/src/gui/painting/qtextureglyphcache_p.h
index c9e7060b0d..7dd8277a45 100644
--- a/src/gui/painting/qtextureglyphcache_p.h
+++ b/src/gui/painting/qtextureglyphcache_p.h
@@ -72,7 +72,7 @@ public:
m_w(0), m_h(0), m_cx(0), m_cy(0), m_currentRowHeight(0)
{ }
- virtual ~QTextureGlyphCache() { }
+ ~QTextureGlyphCache();
struct GlyphAndSubPixelPosition
{
@@ -158,6 +158,8 @@ class Q_GUI_EXPORT QImageTextureGlyphCache : public QTextureGlyphCache
public:
QImageTextureGlyphCache(QFontEngine::GlyphFormat format, const QTransform &matrix)
: QTextureGlyphCache(format, matrix) { }
+ ~QImageTextureGlyphCache();
+
virtual void createTextureData(int width, int height) Q_DECL_OVERRIDE;
virtual void resizeTextureData(int width, int height) Q_DECL_OVERRIDE;
virtual void fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition) Q_DECL_OVERRIDE;
diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp
index a3e9db2057..a23aabe559 100644
--- a/src/gui/painting/qtransform.cpp
+++ b/src/gui/painting/qtransform.cpp
@@ -34,6 +34,7 @@
#include "qdatastream.h"
#include "qdebug.h"
+#include "qhashfunctions.h"
#include "qmatrix.h"
#include "qregion.h"
#include "qpainterpath.h"
@@ -776,6 +777,29 @@ bool QTransform::operator==(const QTransform &o) const
}
/*!
+ \since 5.6
+ \relates QTransform
+
+ Returns the hash value for \a key, using
+ \a seed to seed the calculation.
+*/
+uint qHash(const QTransform &key, uint seed) Q_DECL_NOTHROW
+{
+ QtPrivate::QHashCombine hash;
+ seed = hash(key.m11(), seed);
+ seed = hash(key.m12(), seed);
+ seed = hash(key.m21(), seed);
+ seed = hash(key.m22(), seed);
+ seed = hash(key.dx(), seed);
+ seed = hash(key.dy(), seed);
+ seed = hash(key.m13(), seed);
+ seed = hash(key.m23(), seed);
+ seed = hash(key.m33(), seed);
+ return seed;
+}
+
+
+/*!
\fn bool QTransform::operator!=(const QTransform &matrix) const
Returns \c true if this matrix is not equal to the given \a matrix,
otherwise returns \c false.
@@ -1357,7 +1381,9 @@ static QPolygonF mapProjective(const QTransform &transform, const QPolygonF &pol
path = transform.map(path);
QPolygonF result;
- for (int i = 0; i < path.elementCount(); ++i)
+ const int elementCount = path.elementCount();
+ result.reserve(elementCount);
+ for (int i = 0; i < elementCount; ++i)
result << path.elementAt(i);
return result;
}
diff --git a/src/gui/painting/qtransform.h b/src/gui/painting/qtransform.h
index cf8d4d1970..8874996e19 100644
--- a/src/gui/painting/qtransform.h
+++ b/src/gui/painting/qtransform.h
@@ -96,7 +96,7 @@ public:
qreal m21, qreal m22, qreal m23,
qreal m31, qreal m32, qreal m33);
- QTransform inverted(bool *invertible = 0) const Q_REQUIRED_RESULT;
+ QTransform inverted(bool *invertible = Q_NULLPTR) const Q_REQUIRED_RESULT;
QTransform adjoint() const Q_REQUIRED_RESULT;
QTransform transposed() const Q_REQUIRED_RESULT;
@@ -180,6 +180,8 @@ private:
};
Q_DECLARE_TYPEINFO(QTransform, Q_MOVABLE_TYPE);
+Q_GUI_EXPORT Q_DECL_CONST_FUNCTION uint qHash(const QTransform &key, uint seed = 0) Q_DECL_NOTHROW;
+
/******* inlines *****/
inline QTransform::TransformationType QTransform::inline_type() const
{
diff --git a/src/gui/text/qabstracttextdocumentlayout.cpp b/src/gui/text/qabstracttextdocumentlayout.cpp
index 70be92535d..7735fd6b46 100644
--- a/src/gui/text/qabstracttextdocumentlayout.cpp
+++ b/src/gui/text/qabstracttextdocumentlayout.cpp
@@ -40,6 +40,15 @@
QT_BEGIN_NAMESPACE
+QAbstractTextDocumentLayoutPrivate::~QAbstractTextDocumentLayoutPrivate()
+{
+}
+
+QTextObjectInterface::~QTextObjectInterface()
+{
+ // must be empty until ### Qt 6
+}
+
/*!
\class QAbstractTextDocumentLayout
\reentrant
diff --git a/src/gui/text/qabstracttextdocumentlayout.h b/src/gui/text/qabstracttextdocumentlayout.h
index 27135b0476..cdcfed7535 100644
--- a/src/gui/text/qabstracttextdocumentlayout.h
+++ b/src/gui/text/qabstracttextdocumentlayout.h
@@ -90,7 +90,7 @@ public:
QTextDocument *document() const;
void registerHandler(int objectType, QObject *component);
- void unregisterHandler(int objectType, QObject *component = 0);
+ void unregisterHandler(int objectType, QObject *component = Q_NULLPTR);
QTextObjectInterface *handlerForObject(int objectType) const;
Q_SIGNALS:
@@ -126,7 +126,7 @@ private:
class Q_GUI_EXPORT QTextObjectInterface
{
public:
- virtual ~QTextObjectInterface() {}
+ virtual ~QTextObjectInterface();
virtual QSizeF intrinsicSize(QTextDocument *doc, int posInDocument, const QTextFormat &format) = 0;
virtual void drawObject(QPainter *painter, const QRectF &rect, QTextDocument *doc, int posInDocument, const QTextFormat &format) = 0;
};
diff --git a/src/gui/text/qabstracttextdocumentlayout_p.h b/src/gui/text/qabstracttextdocumentlayout_p.h
index 505135fa4b..a7f28ebf96 100644
--- a/src/gui/text/qabstracttextdocumentlayout_p.h
+++ b/src/gui/text/qabstracttextdocumentlayout_p.h
@@ -58,13 +58,14 @@ struct QTextObjectHandler
};
typedef QHash<int, QTextObjectHandler> HandlerHash;
-class QAbstractTextDocumentLayoutPrivate : public QObjectPrivate
+class Q_GUI_EXPORT QAbstractTextDocumentLayoutPrivate : public QObjectPrivate
{
public:
Q_DECLARE_PUBLIC(QAbstractTextDocumentLayout)
inline QAbstractTextDocumentLayoutPrivate()
: paintDevice(0) {}
+ ~QAbstractTextDocumentLayoutPrivate();
inline void setDocument(QTextDocument *doc) {
document = doc;
diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp
index 3c98cb568d..adbb3df3bf 100644
--- a/src/gui/text/qcssparser.cpp
+++ b/src/gui/text/qcssparser.cpp
@@ -461,6 +461,7 @@ void ValueExtractor::lengthValues(const Declaration &decl, int *m)
}
QList<QVariant> v;
+ v.reserve(4);
for (i = 0; i < 4; i++) {
v += QVariant::fromValue<LengthData>(datas[i]);
m[i] = lengthValueFromData(datas[i], f);
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index 16550c0b3c..bc9da5b564 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -1860,14 +1860,9 @@ void QFont::removeSubstitutions(const QString &familyName)
*/
QStringList QFont::substitutions()
{
- typedef QFontSubst::const_iterator QFontSubstConstIterator;
-
QFontSubst *fontSubst = globalFontSubst();
Q_ASSERT(fontSubst != 0);
- QStringList ret;
- const QFontSubstConstIterator cend = fontSubst->constEnd();
- for (QFontSubstConstIterator it = fontSubst->constBegin(); it != cend; ++it)
- ret.append(it.key());
+ QStringList ret = fontSubst->keys();
ret.sort();
return ret;
@@ -2115,6 +2110,9 @@ QString QFont::lastResortFamily() const
return QString::fromLatin1("helvetica");
}
+extern QStringList qt_fallbacksForFamily(const QString &family, QFont::Style style,
+ QFont::StyleHint styleHint, QChar::Script script);
+
/*!
\fn QString QFont::defaultFamily() const
@@ -2125,8 +2123,7 @@ QString QFont::lastResortFamily() const
*/
QString QFont::defaultFamily() const
{
- QPlatformFontDatabase *fontDB = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
- const QStringList fallbacks = fontDB->fallbacksForFamily(QString(), QFont::StyleNormal
+ const QStringList fallbacks = qt_fallbacksForFamily(QString(), QFont::StyleNormal
, QFont::StyleHint(d->request.styleHint), QChar::Script_Common);
if (!fallbacks.isEmpty())
return fallbacks.first();
@@ -2223,6 +2220,8 @@ QDataStream &operator<<(QDataStream &s, const QFont &font)
}
if (s.version() >= QDataStream::Qt_5_4)
s << (quint8)font.d->request.hintingPreference;
+ if (s.version() >= QDataStream::Qt_5_6)
+ s << (quint8)font.d->capital;
return s;
}
@@ -2313,7 +2312,11 @@ QDataStream &operator>>(QDataStream &s, QFont &font)
s >> value;
font.d->request.hintingPreference = QFont::HintingPreference(value);
}
-
+ if (s.version() >= QDataStream::Qt_5_6) {
+ quint8 value;
+ s >> value;
+ font.d->capital = QFont::Capitalization(value);
+ }
return s;
}
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 85a804acfe..aae84dc988 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -47,6 +47,7 @@
#include <qpa/qplatformfontdatabase.h>
#include <qpa/qplatformtheme.h>
+#include <QtCore/qcache.h>
#include <QtCore/qmath.h>
#include <stdlib.h>
@@ -413,11 +414,45 @@ void QtFontFamily::ensurePopulated()
Q_ASSERT_X(populated, Q_FUNC_INFO, qPrintable(name));
}
+
+struct FallbacksCacheKey {
+ QString family;
+ QFont::Style style;
+ QFont::StyleHint styleHint;
+ QChar::Script script;
+};
+
+inline bool operator==(const FallbacksCacheKey &lhs, const FallbacksCacheKey &rhs) Q_DECL_NOTHROW
+{
+ return lhs.script == rhs.script &&
+ lhs.styleHint == rhs.styleHint &&
+ lhs.style == rhs.style &&
+ lhs.family == rhs.family;
+}
+
+inline bool operator!=(const FallbacksCacheKey &lhs, const FallbacksCacheKey &rhs) Q_DECL_NOTHROW
+{
+ return !operator==(lhs, rhs);
+}
+
+inline uint qHash(const FallbacksCacheKey &key, uint seed = 0) Q_DECL_NOTHROW
+{
+ QtPrivate::QHashCombine hash;
+ seed = hash(seed, key.family);
+ seed = hash(seed, int(key.style));
+ seed = hash(seed, int(key.styleHint));
+ seed = hash(seed, int(key.script));
+ return seed;
+}
+
+
class QFontDatabasePrivate
{
public:
QFontDatabasePrivate()
- : count(0), families(0), reregisterAppFonts(false)
+ : count(0), families(0),
+ fallbacksCache(64),
+ reregisterAppFonts(false)
{ }
~QFontDatabasePrivate() {
@@ -443,6 +478,7 @@ public:
int count;
QtFontFamily **families;
+ QCache<FallbacksCacheKey, QStringList> fallbacksCache;
struct ApplicationFont {
@@ -461,6 +497,8 @@ public:
void QFontDatabasePrivate::invalidate()
{
QFontCache::instance()->clear();
+
+ fallbacksCache.clear();
free();
QGuiApplicationPrivate::platformIntegration()->fontDatabase()->invalidate();
emit static_cast<QGuiApplication *>(QCoreApplication::instance())->fontDatabaseChanged();
@@ -680,8 +718,10 @@ Q_GLOBAL_STATIC_WITH_ARGS(QMutex, fontDatabaseMutex, (QMutex::Recursive))
void qt_cleanupFontDatabase()
{
QFontDatabasePrivate *db = privateDb();
- if (db)
+ if (db) {
+ db->fallbacksCache.clear();
db->free();
+ }
}
// used in qfontengine_x11.cpp
@@ -798,11 +838,17 @@ QStringList QPlatformFontDatabase::fallbacksForFamily(const QString &family, QFo
return retList;
}
-QStringList qt_fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script)
+static QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script)
{
+ QFontDatabasePrivate *db = privateDb();
+
+ const FallbacksCacheKey cacheKey = { family, style, styleHint, script };
+
+ if (const QStringList *fallbacks = db->fallbacksCache.object(cacheKey))
+ return *fallbacks;
+
// make sure that the db has all fallback families
QStringList retList = QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fallbacksForFamily(family,style,styleHint,script);
- QFontDatabasePrivate *db = privateDb();
QStringList::iterator i;
for (i = retList.begin(); i != retList.end(); ++i) {
@@ -818,9 +864,18 @@ QStringList qt_fallbacksForFamily(const QString &family, QFont::Style style, QFo
--i;
}
}
+
+ db->fallbacksCache.insert(cacheKey, new QStringList(retList));
+
return retList;
}
+QStringList qt_fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script)
+{
+ QMutexLocker locker(fontDatabaseMutex());
+ return fallbacksForFamily(family, style, styleHint, script);
+}
+
static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt);
static void initializeDb()
@@ -935,7 +990,7 @@ QFontEngine *loadEngine(int script, const QFontDef &request,
if (styleHint == QFont::AnyStyle && request.fixedPitch)
styleHint = QFont::TypeWriter;
- fallbacks += qt_fallbacksForFamily(family->name, QFont::Style(style->key.style), styleHint, QChar::Script(script));
+ fallbacks += fallbacksForFamily(family->name, QFont::Style(style->key.style), styleHint, QChar::Script(script));
pfMultiEngine->setFallbackFamiliesList(fallbacks);
}
@@ -1413,22 +1468,30 @@ QList<QFontDatabase::WritingSystem> QFontDatabase::writingSystems() const
QT_PREPEND_NAMESPACE(load)();
- QList<WritingSystem> list;
+ quint64 writingSystemsFound = 0;
+ Q_STATIC_ASSERT(WritingSystemsCount < 64);
+
for (int i = 0; i < d->count; ++i) {
QtFontFamily *family = d->families[i];
family->ensurePopulated();
if (family->count == 0)
continue;
- for (int x = Latin; x < WritingSystemsCount; ++x) {
- const WritingSystem writingSystem = WritingSystem(x);
- if (!(family->writingSystems[writingSystem] & QtFontFamily::Supported))
- continue;
- if (!list.contains(writingSystem))
- list.append(writingSystem);
+ for (uint x = Latin; x < uint(WritingSystemsCount); ++x) {
+ if (family->writingSystems[x] & QtFontFamily::Supported)
+ writingSystemsFound |= quint64(1) << x;
}
}
- std::sort(list.begin(), list.end());
+
+ // mutex protection no longer needed - just working on local data now:
+ locker.unlock();
+
+ QList<WritingSystem> list;
+ list.reserve(qPopulationCount(writingSystemsFound));
+ for (uint x = Latin ; x < uint(WritingSystemsCount); ++x) {
+ if (writingSystemsFound & (quint64(1) << x))
+ list.push_back(WritingSystem(x));
+ }
return list;
}
@@ -2607,10 +2670,10 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script)
styleHint = QFont::TypeWriter;
QStringList fallbacks = request.fallBackFamilies
- + qt_fallbacksForFamily(request.family,
- QFont::Style(request.style),
- styleHint,
- QChar::Script(script));
+ + fallbacksForFamily(request.family,
+ QFont::Style(request.style),
+ styleHint,
+ QChar::Script(script));
if (script > QChar::Script_Common)
fallbacks += QString(); // Find the first font matching the specified script.
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index 2087bad9f6..f267b2d147 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -54,6 +54,7 @@
#include <private/qharfbuzz_p.h>
#include <algorithm>
+#include <limits.h>
QT_BEGIN_NAMESPACE
@@ -235,10 +236,14 @@ Q_AUTOTEST_EXPORT QList<QFontEngine *> QFontEngine_stopCollectingEngines()
// QFontEngine
+#define kBearingNotInitialized std::numeric_limits<qreal>::max()
+
QFontEngine::QFontEngine(Type type)
: m_type(type), ref(0),
font_(0), font_destroy_func(0),
- face_(0), face_destroy_func(0)
+ face_(0), face_destroy_func(0),
+ m_minLeftBearing(kBearingNotInitialized),
+ m_minRightBearing(kBearingNotInitialized)
{
faceData.user_data = this;
faceData.get_font_table = qt_get_font_table_default;
@@ -365,17 +370,15 @@ bool QFontEngine::supportsScript(QChar::Script script) const
return true;
}
-#ifdef Q_OS_MAC
- {
+#ifdef QT_ENABLE_HARFBUZZ_NG
+ if (qt_useHarfbuzzNG()) {
+#if defined(Q_OS_DARWIN)
// in AAT fonts, 'gsub' table is effectively replaced by 'mort'/'morx' table
uint len;
if (getSfntTableData(MAKE_TAG('m','o','r','t'), 0, &len) || getSfntTableData(MAKE_TAG('m','o','r','x'), 0, &len))
return true;
- }
#endif
-#ifdef QT_ENABLE_HARFBUZZ_NG
- if (qt_useHarfbuzzNG()) {
bool ret = false;
if (hb_face_t *face = hb_qt_face_get_for_engine(const_cast<QFontEngine *>(this))) {
hb_tag_t script_tag_1, script_tag_2;
@@ -562,11 +565,91 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform
void QFontEngine::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qreal *rightBearing)
{
glyph_metrics_t gi = boundingBox(glyph);
- bool isValid = gi.isValid();
if (leftBearing != 0)
- *leftBearing = isValid ? gi.x.toReal() : 0.0;
+ *leftBearing = gi.leftBearing().toReal();
if (rightBearing != 0)
- *rightBearing = isValid ? (gi.xoff - gi.x - gi.width).toReal() : 0.0;
+ *rightBearing = gi.rightBearing().toReal();
+}
+
+qreal QFontEngine::minLeftBearing() const
+{
+ if (m_minLeftBearing == kBearingNotInitialized)
+ minRightBearing(); // Initializes both (see below)
+
+ return m_minLeftBearing;
+}
+
+#define q16Dot16ToFloat(i) ((i) / 65536.0)
+
+#define kMinLeftSideBearingOffset 12
+#define kMinRightSideBearingOffset 14
+
+qreal QFontEngine::minRightBearing() const
+{
+ if (m_minRightBearing == kBearingNotInitialized) {
+
+ // Try the 'hhea' font table first, which covers the entire font
+ QByteArray hheaTable = getSfntTable(MAKE_TAG('h', 'h', 'e', 'a'));
+ if (hheaTable.size() >= int(kMinRightSideBearingOffset + sizeof(qint16))) {
+ const uchar *tableData = reinterpret_cast<const uchar *>(hheaTable.constData());
+ Q_ASSERT(q16Dot16ToFloat(qFromBigEndian<quint32>(tableData)) == 1.0);
+
+ qint16 minLeftSideBearing = qFromBigEndian<qint16>(tableData + kMinLeftSideBearingOffset);
+ qint16 minRightSideBearing = qFromBigEndian<qint16>(tableData + kMinRightSideBearingOffset);
+
+ // The table data is expressed as FUnits, meaning we have to take the number
+ // of units per em into account. Since pixelSize already has taken DPI into
+ // account we can use that directly instead of the point size.
+ int unitsPerEm = emSquareSize().toInt();
+ qreal funitToPixelFactor = fontDef.pixelSize / unitsPerEm;
+
+ // Some fonts on OS X (such as Gurmukhi Sangam MN, Khmer MN, Lao Sangam MN, etc.), have
+ // invalid values for their NBSPACE left bearing, causing the 'hhea' minimum bearings to
+ // be way off. We detect this by assuming that the minimum bearsings are within a certain
+ // range of the em square size.
+ static const int largestValidBearing = 4 * unitsPerEm;
+
+ if (qAbs(minLeftSideBearing) < largestValidBearing)
+ m_minLeftBearing = minLeftSideBearing * funitToPixelFactor;
+ if (qAbs(minRightSideBearing) < largestValidBearing)
+ m_minRightBearing = minRightSideBearing * funitToPixelFactor;
+ }
+
+ // Fallback in case of missing 'hhea' table (bitmap fonts e.g.) or broken 'hhea' values
+ if (m_minLeftBearing == kBearingNotInitialized || m_minRightBearing == kBearingNotInitialized) {
+
+ // To balance performance and correctness we only look at a subset of the
+ // possible glyphs in the font, based on which characters are more likely
+ // to have a left or right bearing.
+ static const ushort characterSubset[] = {
+ '(', 'C', 'F', 'K', 'V', 'X', 'Y', ']', '_', 'f', 'r', '|',
+ 127, 205, 645, 884, 922, 1070, 12386
+ };
+
+ // The font may have minimum bearings larger than 0, so we have to start at the max
+ m_minLeftBearing = m_minRightBearing = std::numeric_limits<qreal>::max();
+
+ for (uint i = 0; i < (sizeof(characterSubset) / sizeof(ushort)); ++i) {
+ const glyph_t glyph = glyphIndex(characterSubset[i]);
+ if (!glyph)
+ continue;
+
+ glyph_metrics_t glyphMetrics = const_cast<QFontEngine *>(this)->boundingBox(glyph);
+
+ // Glyphs with no contours shouldn't contribute to bearings
+ if (!glyphMetrics.width || !glyphMetrics.height)
+ continue;
+
+ m_minLeftBearing = qMin(m_minLeftBearing, glyphMetrics.leftBearing().toReal());
+ m_minRightBearing = qMin(m_minRightBearing, glyphMetrics.rightBearing().toReal());
+ }
+ }
+
+ if (m_minLeftBearing == kBearingNotInitialized || m_minRightBearing == kBearingNotInitialized)
+ qWarning() << "Failed to compute left/right minimum bearings for" << fontDef.family;
+ }
+
+ return m_minRightBearing;
}
glyph_metrics_t QFontEngine::tightBoundingBox(const QGlyphLayout &glyphs)
@@ -875,7 +958,8 @@ QImage QFontEngine::alphaMapForGlyph(glyph_t glyph)
pt.x = -glyph_x;
pt.y = -glyph_y; // the baseline
QPainterPath path;
- QImage im(glyph_width + 4, glyph_height, QImage::Format_ARGB32_Premultiplied);
+ path.setFillRule(Qt::WindingFill);
+ QImage im(glyph_width, glyph_height, QImage::Format_ARGB32_Premultiplied);
im.fill(Qt::transparent);
QPainter p(&im);
p.setRenderHint(QPainter::Antialiasing);
@@ -1469,8 +1553,7 @@ QFixed QFontEngine::lastRightBearing(const QGlyphLayout &glyphs, bool round)
glyph_t glyph = glyphs.glyphs[glyphs.numGlyphs - 1];
glyph_metrics_t gi = boundingBox(glyph);
if (gi.isValid())
- return round ? QFixed(qRound(gi.xoff - gi.x - gi.width))
- : QFixed(gi.xoff - gi.x - gi.width);
+ return round ? qRound(gi.rightBearing()) : gi.rightBearing();
}
return 0;
}
@@ -1752,7 +1835,10 @@ QFontEngine *QFontEngineMulti::loadEngine(int at)
request.family = fallbackFamilyAt(at - 1);
if (QFontEngine *engine = QFontDatabase::findFont(request, m_script)) {
- engine->fontDef = request;
+ if (request.weight > QFont::Normal)
+ engine->fontDef.weight = request.weight;
+ if (request.style > QFont::StyleNormal)
+ engine->fontDef.style = request.style;
return engine;
}
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index 1177305f6e..de5bec6f93 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -99,6 +99,13 @@ static bool ft_getSfntTable(void *user_data, uint tag, uchar *buffer, uint *leng
static QFontEngineFT::Glyph emptyGlyph = {0, 0, 0, 0, 0, 0, 0, 0};
+static const QFontEngine::HintStyle ftInitialDefaultHintStyle =
+#ifdef Q_OS_WIN
+ QFontEngineFT::HintFull;
+#else
+ QFontEngineFT::HintNone;
+#endif
+
// -------------------------- Freetype support ------------------------------
class QtFreetypeData
@@ -527,69 +534,87 @@ QFontEngineFT::Glyph::~Glyph()
delete [] data;
}
-static const uint subpixel_filter[3][3] = {
- { 180, 60, 16 },
- { 38, 180, 38 },
- { 16, 60, 180 }
+struct LcdFilterDummy
+{
+ static inline void filterPixel(uchar &, uchar &, uchar &)
+ {}
};
-static inline uint filterPixel(uint red, uint green, uint blue, bool legacyFilter)
+struct LcdFilterLegacy
{
- uint res;
- if (legacyFilter) {
- uint high = (red*subpixel_filter[0][0] + green*subpixel_filter[0][1] + blue*subpixel_filter[0][2]) >> 8;
- uint mid = (red*subpixel_filter[1][0] + green*subpixel_filter[1][1] + blue*subpixel_filter[1][2]) >> 8;
- uint low = (red*subpixel_filter[2][0] + green*subpixel_filter[2][1] + blue*subpixel_filter[2][2]) >> 8;
- res = (mid << 24) + (high << 16) + (mid << 8) + low;
- } else {
- uint alpha = green;
- res = (alpha << 24) + (red << 16) + (green << 8) + blue;
+ static inline void filterPixel(uchar &red, uchar &green, uchar &blue)
+ {
+ uint r = red, g = green, b = blue;
+ // intra-pixel filter used by the legacy filter (adopted from _ft_lcd_filter_legacy)
+ red = (r * uint(65538 * 9/13) + g * uint(65538 * 1/6) + b * uint(65538 * 1/13)) / 65536;
+ green = (r * uint(65538 * 3/13) + g * uint(65538 * 4/6) + b * uint(65538 * 3/13)) / 65536;
+ blue = (r * uint(65538 * 1/13) + g * uint(65538 * 1/6) + b * uint(65538 * 9/13)) / 65536;
}
- return res;
-}
+};
-static void convertRGBToARGB(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr, bool legacyFilter)
+template <typename LcdFilter>
+static void convertRGBToARGB_helper(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr)
{
- int h = height;
const int offs = bgr ? -1 : 1;
const int w = width * 3;
- while (h--) {
+ while (height--) {
uint *dd = dst;
for (int x = 0; x < w; x += 3) {
- uint red = src[x+1-offs];
- uint green = src[x+1];
- uint blue = src[x+1+offs];
- *dd = filterPixel(red, green, blue, legacyFilter);
- ++dd;
+ uchar red = src[x + 1 - offs];
+ uchar green = src[x + 1];
+ uchar blue = src[x + 1 + offs];
+ LcdFilter::filterPixel(red, green, blue);
+ // alpha = green
+ *dd++ = (green << 24) | (red << 16) | (green << 8) | blue;
}
dst += width;
src += src_pitch;
}
}
-static void convertRGBToARGB_V(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr, bool legacyFilter)
+static inline void convertRGBToARGB(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr, bool legacyFilter)
+{
+ if (!legacyFilter)
+ convertRGBToARGB_helper<LcdFilterDummy>(src, dst, width, height, src_pitch, bgr);
+ else
+ convertRGBToARGB_helper<LcdFilterLegacy>(src, dst, width, height, src_pitch, bgr);
+}
+
+template <typename LcdFilter>
+static void convertRGBToARGB_V_helper(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr)
{
- int h = height;
const int offs = bgr ? -src_pitch : src_pitch;
- while (h--) {
+ while (height--) {
for (int x = 0; x < width; x++) {
- uint red = src[x+src_pitch-offs];
- uint green = src[x+src_pitch];
- uint blue = src[x+src_pitch+offs];
- dst[x] = filterPixel(red, green, blue, legacyFilter);
+ uchar red = src[x + src_pitch - offs];
+ uchar green = src[x + src_pitch];
+ uchar blue = src[x + src_pitch + offs];
+ LcdFilter::filterPixel(red, green, blue);
+ // alpha = green
+ *dst++ = (green << 24) | (red << 16) | (green << 8) | blue;
}
- dst += width;
src += 3*src_pitch;
}
}
-static void convertGRAYToARGB(const uchar *src, uint *dst, int width, int height, int src_pitch) {
- for (int y = 0; y < height; ++y) {
- int readpos = (y * src_pitch);
- int writepos = (y * width);
- for (int x = 0; x < width; ++x) {
- dst[writepos + x] = (0xFF << 24) + (src[readpos + x] << 16) + (src[readpos + x] << 8) + src[readpos + x];
+static inline void convertRGBToARGB_V(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr, bool legacyFilter)
+{
+ if (!legacyFilter)
+ convertRGBToARGB_V_helper<LcdFilterDummy>(src, dst, width, height, src_pitch, bgr);
+ else
+ convertRGBToARGB_V_helper<LcdFilterLegacy>(src, dst, width, height, src_pitch, bgr);
+}
+
+static inline void convertGRAYToARGB(const uchar *src, uint *dst, int width, int height, int src_pitch)
+{
+ while (height--) {
+ const uchar *p = src;
+ const uchar * const e = p + width;
+ while (p < e) {
+ uchar gray = *p++;
+ *dst++ = (0xFF << 24) | (gray << 16) | (gray << 8) | gray;
}
+ src += src_pitch;
}
}
@@ -629,11 +654,7 @@ QFontEngineFT::QFontEngineFT(const QFontDef &fd)
antialias = true;
freetype = 0;
default_load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
-#ifndef Q_OS_WIN
- default_hint_style = HintNone;
-#else
- default_hint_style = HintFull;
-#endif
+ default_hint_style = ftInitialDefaultHintStyle;
subpixelType = Subpixel_None;
lcdFilterType = 0;
#if defined(FT_LCD_FILTER_H)
@@ -685,7 +706,6 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
symbol = bool(fontDef.family.contains(QLatin1String("symbol"), Qt::CaseInsensitive));
}
- lbearing = rbearing = SHRT_MIN;
freetype->computeSize(fontDef, &xsize, &ysize, &defaultGlyphSet.outline_drawing);
FT_Face face = lockFace();
@@ -697,8 +717,12 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
FT_Set_Transform(face, &matrix, 0);
freetype->matrix = matrix;
// fake bold
- if ((fontDef.weight >= QFont::Bold) && !(face->style_flags & FT_STYLE_FLAG_BOLD) && !FT_IS_FIXED_WIDTH(face))
- embolden = true;
+ if ((fontDef.weight >= QFont::Bold) && !(face->style_flags & FT_STYLE_FLAG_BOLD) && !FT_IS_FIXED_WIDTH(face)) {
+ if (const TT_OS2 *os2 = reinterpret_cast<const TT_OS2 *>(FT_Get_Sfnt_Table(face, ft_sfnt_os2))) {
+ if (os2->usWeightClass < 750)
+ embolden = true;
+ }
+ }
// underline metrics
line_thickness = QFixed::fromFixed(FT_MulFix(face->underline_thickness, face->size->metrics.y_scale));
underline_position = QFixed::fromFixed(-FT_MulFix(face->underline_position, face->size->metrics.y_scale));
@@ -760,6 +784,24 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
return true;
}
+void QFontEngineFT::setQtDefaultHintStyle(QFont::HintingPreference hintingPreference)
+{
+ switch (hintingPreference) {
+ case QFont::PreferNoHinting:
+ setDefaultHintStyle(HintNone);
+ break;
+ case QFont::PreferFullHinting:
+ setDefaultHintStyle(HintFull);
+ break;
+ case QFont::PreferVerticalHinting:
+ setDefaultHintStyle(HintLight);
+ break;
+ case QFont::PreferDefaultHinting:
+ setDefaultHintStyle(ftInitialDefaultHintStyle);
+ break;
+ }
+}
+
void QFontEngineFT::setDefaultHintStyle(HintStyle style)
{
default_hint_style = style;
@@ -1213,7 +1255,7 @@ QFixed QFontEngineFT::xHeight() const
TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2);
if (os2 && os2->sxHeight) {
lockFace();
- QFixed answer = QFixed(os2->sxHeight*freetype->face->size->metrics.y_ppem)/freetype->face->units_per_EM;
+ QFixed answer = QFixed(os2->sxHeight * freetype->face->size->metrics.y_ppem) / emSquareSize();
unlockFace();
return answer;
}
@@ -1225,7 +1267,7 @@ QFixed QFontEngineFT::averageCharWidth() const
TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2);
if (os2 && os2->xAvgCharWidth) {
lockFace();
- QFixed answer = QFixed(os2->xAvgCharWidth*freetype->face->size->metrics.x_ppem)/freetype->face->units_per_EM;
+ QFixed answer = QFixed(os2->xAvgCharWidth * freetype->face->size->metrics.x_ppem) / emSquareSize();
unlockFace();
return answer;
}
@@ -1237,54 +1279,6 @@ qreal QFontEngineFT::maxCharWidth() const
return metrics.max_advance >> 6;
}
-static const ushort char_table[] = {
- 40,
- 67,
- 70,
- 75,
- 86,
- 88,
- 89,
- 91,
- 95,
- 102,
- 114,
- 124,
- 127,
- 205,
- 645,
- 884,
- 922,
- 1070,
- 12386
-};
-
-static const int char_table_entries = sizeof(char_table)/sizeof(ushort);
-
-
-qreal QFontEngineFT::minLeftBearing() const
-{
- if (lbearing == SHRT_MIN)
- (void) minRightBearing(); // calculates both
- return lbearing.toReal();
-}
-
-qreal QFontEngineFT::minRightBearing() const
-{
- if (rbearing == SHRT_MIN) {
- lbearing = rbearing = 0;
- for (int i = 0; i < char_table_entries; ++i) {
- const glyph_t glyph = glyphIndex(char_table[i]);
- if (glyph != 0) {
- glyph_metrics_t gi = const_cast<QFontEngineFT *>(this)->boundingBox(glyph);
- lbearing = qMin(lbearing, gi.x);
- rbearing = qMin(rbearing, (gi.xoff - gi.x - gi.width));
- }
- }
- }
- return rbearing.toReal();
-}
-
QFixed QFontEngineFT::lineThickness() const
{
return line_thickness;
@@ -1301,7 +1295,7 @@ void QFontEngineFT::doKerning(QGlyphLayout *g, QFontEngine::ShaperFlags flags) c
kerning_pairs_loaded = true;
lockFace();
if (freetype->face->size->metrics.x_ppem != 0) {
- QFixed scalingFactor(freetype->face->units_per_EM/freetype->face->size->metrics.x_ppem);
+ QFixed scalingFactor = emSquareSize() / QFixed(freetype->face->size->metrics.x_ppem);
unlockFace();
const_cast<QFontEngineFT *>(this)->loadKerningPairs(scalingFactor);
} else {
diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h
index 7b28a4064f..6f05645a3f 100644
--- a/src/gui/text/qfontengine_ft_p.h
+++ b/src/gui/text/qfontengine_ft_p.h
@@ -189,67 +189,65 @@ private:
mutable int fast_glyph_count;
};
- virtual QFontEngine::FaceId faceId() const Q_DECL_OVERRIDE;
- virtual QFontEngine::Properties properties() const Q_DECL_OVERRIDE;
- virtual QFixed emSquareSize() const Q_DECL_OVERRIDE;
- virtual bool supportsSubPixelPositions() const Q_DECL_OVERRIDE
+ QFontEngine::FaceId faceId() const Q_DECL_OVERRIDE;
+ QFontEngine::Properties properties() const Q_DECL_OVERRIDE;
+ QFixed emSquareSize() const Q_DECL_OVERRIDE;
+ bool supportsSubPixelPositions() const Q_DECL_OVERRIDE
{
return default_hint_style == HintLight ||
default_hint_style == HintNone;
}
- virtual bool getSfntTableData(uint tag, uchar *buffer, uint *length) const Q_DECL_OVERRIDE;
- virtual int synthesized() const Q_DECL_OVERRIDE;
+ bool getSfntTableData(uint tag, uchar *buffer, uint *length) const Q_DECL_OVERRIDE;
+ int synthesized() const Q_DECL_OVERRIDE;
- virtual QFixed ascent() const Q_DECL_OVERRIDE;
- virtual QFixed descent() const Q_DECL_OVERRIDE;
- virtual QFixed leading() const Q_DECL_OVERRIDE;
- virtual QFixed xHeight() const Q_DECL_OVERRIDE;
- virtual QFixed averageCharWidth() const Q_DECL_OVERRIDE;
+ QFixed ascent() const Q_DECL_OVERRIDE;
+ QFixed descent() const Q_DECL_OVERRIDE;
+ QFixed leading() const Q_DECL_OVERRIDE;
+ QFixed xHeight() const Q_DECL_OVERRIDE;
+ QFixed averageCharWidth() const Q_DECL_OVERRIDE;
- virtual qreal maxCharWidth() const Q_DECL_OVERRIDE;
- virtual qreal minLeftBearing() const Q_DECL_OVERRIDE;
- virtual qreal minRightBearing() const Q_DECL_OVERRIDE;
- virtual QFixed lineThickness() const Q_DECL_OVERRIDE;
- virtual QFixed underlinePosition() const Q_DECL_OVERRIDE;
+ qreal maxCharWidth() const Q_DECL_OVERRIDE;
+ QFixed lineThickness() const Q_DECL_OVERRIDE;
+ QFixed underlinePosition() const Q_DECL_OVERRIDE;
- virtual glyph_t glyphIndex(uint ucs4) const Q_DECL_OVERRIDE;
+ glyph_t glyphIndex(uint ucs4) const Q_DECL_OVERRIDE;
void doKerning(QGlyphLayout *, ShaperFlags) const Q_DECL_OVERRIDE;
- virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics) Q_DECL_OVERRIDE;
+ void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics) Q_DECL_OVERRIDE;
- virtual bool supportsTransformation(const QTransform &transform) const Q_DECL_OVERRIDE;
+ bool supportsTransformation(const QTransform &transform) const Q_DECL_OVERRIDE;
- virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
- QPainterPath *path, QTextItem::RenderFlags flags) Q_DECL_OVERRIDE;
- virtual void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs,
- QPainterPath *path, QTextItem::RenderFlags flags) Q_DECL_OVERRIDE;
+ void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
+ QPainterPath *path, QTextItem::RenderFlags flags) Q_DECL_OVERRIDE;
+ void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs,
+ QPainterPath *path, QTextItem::RenderFlags flags) Q_DECL_OVERRIDE;
- virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, ShaperFlags flags) const Q_DECL_OVERRIDE;
+ bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, ShaperFlags flags) const Q_DECL_OVERRIDE;
- virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs) Q_DECL_OVERRIDE;
- virtual glyph_metrics_t boundingBox(glyph_t glyph) Q_DECL_OVERRIDE;
- virtual glyph_metrics_t boundingBox(glyph_t glyph, const QTransform &matrix) Q_DECL_OVERRIDE;
+ glyph_metrics_t boundingBox(const QGlyphLayout &glyphs) Q_DECL_OVERRIDE;
+ glyph_metrics_t boundingBox(glyph_t glyph) Q_DECL_OVERRIDE;
+ glyph_metrics_t boundingBox(glyph_t glyph, const QTransform &matrix) Q_DECL_OVERRIDE;
- virtual void recalcAdvances(QGlyphLayout *glyphs, ShaperFlags flags) const Q_DECL_OVERRIDE;
- virtual QImage alphaMapForGlyph(glyph_t g) Q_DECL_OVERRIDE { return alphaMapForGlyph(g, 0); }
- virtual QImage alphaMapForGlyph(glyph_t, QFixed) Q_DECL_OVERRIDE;
+ void recalcAdvances(QGlyphLayout *glyphs, ShaperFlags flags) const Q_DECL_OVERRIDE;
+ QImage alphaMapForGlyph(glyph_t g) Q_DECL_OVERRIDE { return alphaMapForGlyph(g, 0); }
+ QImage alphaMapForGlyph(glyph_t, QFixed) Q_DECL_OVERRIDE;
QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t) Q_DECL_OVERRIDE;
- virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) Q_DECL_OVERRIDE;
- virtual glyph_metrics_t alphaMapBoundingBox(glyph_t glyph,
- QFixed subPixelPosition,
- const QTransform &matrix,
- QFontEngine::GlyphFormat format) Q_DECL_OVERRIDE;
- virtual QImage *lockedAlphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition,
- GlyphFormat neededFormat, const QTransform &t,
- QPoint *offset) Q_DECL_OVERRIDE;
- virtual bool hasInternalCaching() const Q_DECL_OVERRIDE { return cacheEnabled; }
- virtual void unlockAlphaMapForGlyph() Q_DECL_OVERRIDE;
-
- virtual void removeGlyphFromCache(glyph_t glyph) Q_DECL_OVERRIDE;
- virtual int glyphMargin(QFontEngine::GlyphFormat /* format */) Q_DECL_OVERRIDE { return 0; }
-
- virtual int glyphCount() const Q_DECL_OVERRIDE;
+ QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) Q_DECL_OVERRIDE;
+ glyph_metrics_t alphaMapBoundingBox(glyph_t glyph,
+ QFixed subPixelPosition,
+ const QTransform &matrix,
+ QFontEngine::GlyphFormat format) Q_DECL_OVERRIDE;
+ QImage *lockedAlphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition,
+ GlyphFormat neededFormat, const QTransform &t,
+ QPoint *offset) Q_DECL_OVERRIDE;
+ bool hasInternalCaching() const Q_DECL_OVERRIDE { return cacheEnabled; }
+ void unlockAlphaMapForGlyph() Q_DECL_OVERRIDE;
+
+ void removeGlyphFromCache(glyph_t glyph) Q_DECL_OVERRIDE;
+ int glyphMargin(QFontEngine::GlyphFormat /* format */) Q_DECL_OVERRIDE { return 0; }
+
+ int glyphCount() const Q_DECL_OVERRIDE;
enum Scaling {
Scaled,
@@ -279,12 +277,12 @@ private:
bool init(FaceId faceId, bool antialias, GlyphFormat format,
QFreetypeFace *freetypeFace);
- virtual int getPointInOutline(glyph_t glyph, int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints) Q_DECL_OVERRIDE;
+ int getPointInOutline(glyph_t glyph, int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints) Q_DECL_OVERRIDE;
+ void setQtDefaultHintStyle(QFont::HintingPreference hintingPreference);
+ void setDefaultHintStyle(HintStyle style) Q_DECL_OVERRIDE;
- virtual void setDefaultHintStyle(HintStyle style) Q_DECL_OVERRIDE;
-
- virtual QFontEngine *cloneWithSize(qreal pixelSize) const Q_DECL_OVERRIDE;
+ QFontEngine *cloneWithSize(qreal pixelSize) const Q_DECL_OVERRIDE;
bool initFromFontEngine(const QFontEngineFT *fontEngine);
HintStyle defaultHintStyle() const { return default_hint_style; }
@@ -307,6 +305,7 @@ private:
friend class QFontEngineFTRawFont;
friend class QFontconfigDatabase;
friend class QBasicFontDatabase;
+ friend class QCoreTextFontDatabase;
friend class QFontEngineMultiFontConfig;
int loadFlags(QGlyphSet *set, GlyphFormat format, int flags, bool &hsubpixel, int &vfactor) const;
@@ -323,8 +322,6 @@ private:
int xsize;
int ysize;
- mutable QFixed lbearing;
- mutable QFixed rbearing;
QFixed line_thickness;
QFixed underline_position;
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index 6f4fabe1f6..be9eaa5020 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -49,6 +49,7 @@
#include "QtCore/qatomic.h"
#include <QtCore/qvarlengtharray.h>
#include <QtCore/QLinkedList>
+#include <QtCore/qhashfunctions.h>
#include "private/qtextengine_p.h"
#include "private/qfont_p.h"
@@ -213,8 +214,8 @@ public:
virtual QFixed underlinePosition() const;
virtual qreal maxCharWidth() const = 0;
- virtual qreal minLeftBearing() const { return qreal(); }
- virtual qreal minRightBearing() const { return qreal(); }
+ virtual qreal minLeftBearing() const;
+ virtual qreal minRightBearing() const;
virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
@@ -322,18 +323,28 @@ private:
private:
QVariant m_userData;
+
+ mutable qreal m_minLeftBearing;
+ mutable qreal m_minRightBearing;
+
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QFontEngine::ShaperFlags)
inline bool operator ==(const QFontEngine::FaceId &f1, const QFontEngine::FaceId &f2)
{
- return (f1.index == f2.index) && (f1.encoding == f2.encoding) && (f1.filename == f2.filename);
+ return f1.index == f2.index && f1.encoding == f2.encoding && f1.filename == f2.filename && f1.uuid == f2.uuid;
}
-inline uint qHash(const QFontEngine::FaceId &f)
+inline uint qHash(const QFontEngine::FaceId &f, uint seed = 0)
+ Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(f.filename)))
{
- return qHash((f.index << 16) + f.encoding) + qHash(f.filename + f.uuid);
+ QtPrivate::QHashCombine hash;
+ seed = hash(seed, f.filename);
+ seed = hash(seed, f.uuid);
+ seed = hash(seed, f.index);
+ seed = hash(seed, f.encoding);
+ return seed;
}
diff --git a/src/gui/text/qfontengineglyphcache.cpp b/src/gui/text/qfontengineglyphcache.cpp
new file mode 100644
index 0000000000..f6fdfa3ce3
--- /dev/null
+++ b/src/gui/text/qfontengineglyphcache.cpp
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <private/qfontengineglyphcache_p.h>
+
+QT_BEGIN_NAMESPACE
+
+// out-of-line to avoid vtable duplication, breaking e.g. RTTI
+QFontEngineGlyphCache::~QFontEngineGlyphCache()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/text/qfontengineglyphcache_p.h b/src/gui/text/qfontengineglyphcache_p.h
index 6cf4d2f1ba..def42c22a3 100644
--- a/src/gui/text/qfontengineglyphcache_p.h
+++ b/src/gui/text/qfontengineglyphcache_p.h
@@ -56,7 +56,7 @@
QT_BEGIN_NAMESPACE
-class QFontEngineGlyphCache: public QSharedData
+class Q_GUI_EXPORT QFontEngineGlyphCache: public QSharedData
{
public:
QFontEngineGlyphCache(QFontEngine::GlyphFormat format, const QTransform &matrix) : m_format(format), m_transform(matrix)
@@ -64,7 +64,7 @@ public:
Q_ASSERT(m_format != QFontEngine::Format_None);
}
- virtual ~QFontEngineGlyphCache() { }
+ virtual ~QFontEngineGlyphCache();
QFontEngine::GlyphFormat glyphFormat() const { return m_format; }
const QTransform &transform() const { return m_transform; }
diff --git a/src/gui/text/qfontmetrics.h b/src/gui/text/qfontmetrics.h
index 2031f022d4..4c2c6317ba 100644
--- a/src/gui/text/qfontmetrics.h
+++ b/src/gui/text/qfontmetrics.h
@@ -93,11 +93,11 @@ public:
QRect boundingRect(QChar) const;
QRect boundingRect(const QString &text) const;
- QRect boundingRect(const QRect &r, int flags, const QString &text, int tabstops=0, int *tabarray=0) const;
+ QRect boundingRect(const QRect &r, int flags, const QString &text, int tabstops = 0, int *tabarray = Q_NULLPTR) const;
inline QRect boundingRect(int x, int y, int w, int h, int flags, const QString &text,
- int tabstops=0, int *tabarray=0) const
+ int tabstops = 0, int *tabarray = Q_NULLPTR) const
{ return boundingRect(QRect(x, y, w, h), flags, text, tabstops, tabarray); }
- QSize size(int flags, const QString& str, int tabstops=0, int *tabarray=0) const;
+ QSize size(int flags, const QString& str, int tabstops = 0, int *tabarray = Q_NULLPTR) const;
QRect tightBoundingRect(const QString &text) const;
@@ -161,8 +161,8 @@ public:
QRectF boundingRect(const QString &string) const;
QRectF boundingRect(QChar) const;
- QRectF boundingRect(const QRectF &r, int flags, const QString& string, int tabstops=0, int *tabarray=0) const;
- QSizeF size(int flags, const QString& str, int tabstops=0, int *tabarray=0) const;
+ QRectF boundingRect(const QRectF &r, int flags, const QString& string, int tabstops = 0, int *tabarray = Q_NULLPTR) const;
+ QSizeF size(int flags, const QString& str, int tabstops = 0, int *tabarray = Q_NULLPTR) const;
QRectF tightBoundingRect(const QString &text) const;
diff --git a/src/gui/text/qfontsubset.cpp b/src/gui/text/qfontsubset.cpp
index 9f652084be..dc32405f36 100644
--- a/src/gui/text/qfontsubset.cpp
+++ b/src/gui/text/qfontsubset.cpp
@@ -350,6 +350,7 @@ struct qttf_head_table {
quint16 macStyle;
qint16 indexToLocFormat;
};
+Q_DECLARE_TYPEINFO(qttf_head_table, Q_PRIMITIVE_TYPE);
struct qttf_hhea_table {
@@ -362,6 +363,7 @@ struct qttf_hhea_table {
qint16 xMaxExtent;
quint16 numberOfHMetrics;
};
+Q_DECLARE_TYPEINFO(qttf_hhea_table, Q_PRIMITIVE_TYPE);
struct qttf_maxp_table {
@@ -373,6 +375,7 @@ struct qttf_maxp_table {
quint16 maxComponentElements;
quint16 maxComponentDepth;
};
+Q_DECLARE_TYPEINFO(qttf_maxp_table, Q_PRIMITIVE_TYPE);
struct qttf_name_table {
QString copyright;
@@ -380,6 +383,7 @@ struct qttf_name_table {
QString subfamily;
QString postscript_name;
};
+Q_DECLARE_TYPEINFO(qttf_name_table, Q_MOVABLE_TYPE);
static QTtfTable generateHead(const qttf_head_table &head);
@@ -411,9 +415,9 @@ Q_DECLARE_TYPEINFO(QTtfGlyph, Q_MOVABLE_TYPE);
static QTtfGlyph generateGlyph(int index, const QPainterPath &path, qreal advance, qreal lsb, qreal ppem);
// generates glyf, loca and hmtx
-static QList<QTtfTable> generateGlyphTables(qttf_font_tables &tables, const QList<QTtfGlyph> &_glyphs);
+static QVector<QTtfTable> generateGlyphTables(qttf_font_tables &tables, const QVector<QTtfGlyph> &_glyphs);
-static QByteArray bindFont(const QList<QTtfTable>& _tables);
+static QByteArray bindFont(const QVector<QTtfTable>& _tables);
static quint32 checksum(const QByteArray &table)
@@ -607,12 +611,13 @@ struct QTtfNameRecord {
quint16 nameId;
QString value;
};
+Q_DECLARE_TYPEINFO(QTtfNameRecord, Q_MOVABLE_TYPE);
-static QTtfTable generateName(const QList<QTtfNameRecord> &name);
+static QTtfTable generateName(const QVector<QTtfNameRecord> &name);
static QTtfTable generateName(const qttf_name_table &name)
{
- QList<QTtfNameRecord> list;
+ QVector<QTtfNameRecord> list;
QTtfNameRecord rec;
rec.nameId = 0;
rec.value = name.copyright;
@@ -636,7 +641,7 @@ static QTtfTable generateName(const qttf_name_table &name)
}
// ####### should probably generate Macintosh/Roman name entries as well
-static QTtfTable generateName(const QList<QTtfNameRecord> &name)
+static QTtfTable generateName(const QVector<QTtfNameRecord> &name)
{
const int char_size = 2;
@@ -707,7 +712,7 @@ struct TTF_POINT {
};
Q_DECLARE_TYPEINFO(TTF_POINT, Q_PRIMITIVE_TYPE);
-static void convertPath(const QPainterPath &path, QList<TTF_POINT> *points, QList<int> *endPoints, qreal ppem)
+static void convertPath(const QPainterPath &path, QVector<TTF_POINT> *points, QVector<int> *endPoints, qreal ppem)
{
int numElements = path.elementCount();
for (int i = 0; i < numElements - 1; ++i) {
@@ -829,7 +834,7 @@ static void convertPath(const QPainterPath &path, QList<TTF_POINT> *points, QLis
endPoints->append(points->size() - 1);
}
-static void getBounds(const QList<TTF_POINT> &points, qint16 *xmin, qint16 *xmax, qint16 *ymin, qint16 *ymax)
+static void getBounds(const QVector<TTF_POINT> &points, qint16 *xmin, qint16 *xmax, qint16 *ymin, qint16 *ymax)
{
*xmin = points.at(0).x;
*xmax = *xmin;
@@ -844,7 +849,7 @@ static void getBounds(const QList<TTF_POINT> &points, qint16 *xmin, qint16 *xmax
}
}
-static int convertToRelative(QList<TTF_POINT> *points)
+static int convertToRelative(QVector<TTF_POINT> *points)
{
// convert points to relative and setup flags
// qDebug() << "relative points:";
@@ -897,7 +902,7 @@ static int convertToRelative(QList<TTF_POINT> *points)
return point_array_size;
}
-static void getGlyphData(QTtfGlyph *glyph, const QList<TTF_POINT> &points, const QList<int> &endPoints, int point_array_size)
+static void getGlyphData(QTtfGlyph *glyph, const QVector<TTF_POINT> &points, const QVector<int> &endPoints, int point_array_size)
{
const int max_size = 5*sizeof(qint16) // header
+ endPoints.size()*sizeof(quint16) // end points of contours
@@ -947,8 +952,8 @@ static void getGlyphData(QTtfGlyph *glyph, const QList<TTF_POINT> &points, const
static QTtfGlyph generateGlyph(int index, const QPainterPath &path, qreal advance, qreal lsb, qreal ppem)
{
- QList<TTF_POINT> points;
- QList<int> endPoints;
+ QVector<TTF_POINT> points;
+ QVector<int> endPoints;
QTtfGlyph glyph;
glyph.index = index;
glyph.advanceWidth = qRound(advance * 2048. / ppem);
@@ -983,10 +988,10 @@ static bool operator <(const QTtfGlyph &g1, const QTtfGlyph &g2)
return g1.index < g2.index;
}
-static QList<QTtfTable> generateGlyphTables(qttf_font_tables &tables, const QList<QTtfGlyph> &_glyphs)
+static QVector<QTtfTable> generateGlyphTables(qttf_font_tables &tables, const QVector<QTtfGlyph> &_glyphs)
{
const int max_size_small = 65536*2;
- QList<QTtfGlyph> glyphs = _glyphs;
+ QVector<QTtfGlyph> glyphs = _glyphs;
std::sort(glyphs.begin(), glyphs.end());
Q_ASSERT(tables.maxp.numGlyphs == glyphs.at(glyphs.size()-1).index + 1);
@@ -1049,7 +1054,7 @@ static QList<QTtfTable> generateGlyphTables(qttf_font_tables &tables, const QLis
Q_ASSERT(loca.data.size() == ls.offset());
Q_ASSERT(hmtx.data.size() == hs.offset());
- QList<QTtfTable> list;
+ QVector<QTtfTable> list;
list.append(glyf);
list.append(loca);
list.append(hmtx);
@@ -1061,9 +1066,9 @@ static bool operator <(const QTtfTable &t1, const QTtfTable &t2)
return t1.tag < t2.tag;
}
-static QByteArray bindFont(const QList<QTtfTable>& _tables)
+static QByteArray bindFont(const QVector<QTtfTable>& _tables)
{
- QList<QTtfTable> tables = _tables;
+ QVector<QTtfTable> tables = _tables;
std::sort(tables.begin(), tables.end());
@@ -1154,7 +1159,7 @@ QByteArray QFontSubset::toTruetype() const
qreal ppem = fontEngine->fontDef.pixelSize;
#define TO_TTF(x) qRound(x * 2048. / ppem)
- QList<QTtfGlyph> glyphs;
+ QVector<QTtfGlyph> glyphs;
QFontEngine::Properties properties = fontEngine->properties();
// initialize some stuff needed in createWidthArray
@@ -1225,7 +1230,7 @@ QByteArray QFontSubset::toTruetype() const
}
- QList<QTtfTable> tables = generateGlyphTables(font, glyphs);
+ QVector<QTtfTable> tables = generateGlyphTables(font, glyphs);
tables.append(generateHead(font.head));
tables.append(generateHhea(font.hhea));
tables.append(generateMaxp(font.maxp));
diff --git a/src/gui/text/qfontsubset_p.h b/src/gui/text/qfontsubset_p.h
index da8589de3f..4abdb48c0d 100644
--- a/src/gui/text/qfontsubset_p.h
+++ b/src/gui/text/qfontsubset_p.h
@@ -79,7 +79,7 @@ public:
const int object_id;
bool noEmbed;
QFontEngine *fontEngine;
- QList<int> glyph_indices;
+ QVector<int> glyph_indices;
mutable int downloaded_glyphs;
mutable bool standard_font;
int nGlyphs() const { return glyph_indices.size(); }
diff --git a/src/gui/text/qglyphrun.cpp b/src/gui/text/qglyphrun.cpp
index e6d6863134..642313d340 100644
--- a/src/gui/text/qglyphrun.cpp
+++ b/src/gui/text/qglyphrun.cpp
@@ -49,7 +49,6 @@ QT_BEGIN_NAMESPACE
\ingroup text
\ingroup shared
- \mainclass
When Qt displays a string of text encoded in Unicode, it will first convert the Unicode points
into a list of glyph indexes and a list of positions based on one or more fonts. The Unicode
diff --git a/src/gui/text/qglyphrun.h b/src/gui/text/qglyphrun.h
index d3034b7546..9f51a49a6d 100644
--- a/src/gui/text/qglyphrun.h
+++ b/src/gui/text/qglyphrun.h
@@ -59,9 +59,13 @@ public:
QGlyphRun();
QGlyphRun(const QGlyphRun &other);
+#ifdef Q_COMPILER_RVALUE_REFS
+ QGlyphRun &operator=(QGlyphRun &&other) Q_DECL_NOTHROW { swap(other); return *this; }
+#endif
+ QGlyphRun &operator=(const QGlyphRun &other);
~QGlyphRun();
- void swap(QGlyphRun &other) { qSwap(d, other.d); }
+ void swap(QGlyphRun &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
QRawFont rawFont() const;
void setRawFont(const QRawFont &rawFont);
@@ -78,8 +82,6 @@ public:
void clear();
- QGlyphRun &operator=(const QGlyphRun &other);
-
bool operator==(const QGlyphRun &other) const;
inline bool operator!=(const QGlyphRun &other) const
{ return !operator==(other); }
diff --git a/src/gui/text/qharfbuzzng.cpp b/src/gui/text/qharfbuzzng.cpp
index 102c62ea8a..b2edfc00a0 100644
--- a/src/gui/text/qharfbuzzng.cpp
+++ b/src/gui/text/qharfbuzzng.cpp
@@ -188,7 +188,15 @@ static const hb_script_t _qtscript_to_hbscript[] = {
HB_SCRIPT_SIDDHAM,
HB_SCRIPT_KHUDAWADI,
HB_SCRIPT_TIRHUTA,
- HB_SCRIPT_WARANG_CITI
+ HB_SCRIPT_WARANG_CITI,
+
+ // Unicode 8.0 additions
+ HB_SCRIPT_AHOM,
+ HB_SCRIPT_ANATOLIAN_HIEROGLYPHS,
+ HB_SCRIPT_HATRAN,
+ HB_SCRIPT_MULTANI,
+ HB_SCRIPT_OLD_HUNGARIAN,
+ HB_SCRIPT_SIGNWRITING
};
Q_STATIC_ASSERT(QChar::ScriptCount == sizeof(_qtscript_to_hbscript) / sizeof(_qtscript_to_hbscript[0]));
diff --git a/src/gui/text/qplatformfontdatabase.cpp b/src/gui/text/qplatformfontdatabase.cpp
index 8764c8cebf..0695c2eff4 100644
--- a/src/gui/text/qplatformfontdatabase.cpp
+++ b/src/gui/text/qplatformfontdatabase.cpp
@@ -40,6 +40,9 @@
#include <QtCore/QLibraryInfo>
#include <QtCore/QDir>
+#include <algorithm>
+#include <iterator>
+
QT_BEGIN_NAMESPACE
void qt_registerFont(const QString &familyname, const QString &stylename,
@@ -450,11 +453,11 @@ bool QPlatformFontDatabase::fontsAlwaysScalable() const
QList<int> QPlatformFontDatabase::standardSizes() const
{
QList<int> ret;
- static const unsigned short standard[] =
- { 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72, 0 };
- ret.reserve(int(sizeof(standard) / sizeof(standard[0])));
- const unsigned short *sizes = standard;
- while (*sizes) ret << *sizes++;
+ static const quint8 standard[] =
+ { 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72 };
+ static const int num_standards = int(sizeof standard / sizeof *standard);
+ ret.reserve(num_standards);
+ std::copy(standard, standard + num_standards, std::back_inserter(ret));
return ret;
}
@@ -471,7 +474,7 @@ QFontEngine::SubpixelAntialiasingType QPlatformFontDatabase::subpixelAntialiasin
// ### copied to tools/makeqpf/qpf2.cpp
// see the Unicode subset bitfields in the MSDN docs
-static const ushort requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = {
+static const quint8 requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = {
{ 127, 127 }, // Any
{ 0, 127 }, // Latin
{ 7, 127 }, // Greek
diff --git a/src/gui/text/qplatformfontdatabase.h b/src/gui/text/qplatformfontdatabase.h
index 0615df65d6..3331d96f8b 100644
--- a/src/gui/text/qplatformfontdatabase.h
+++ b/src/gui/text/qplatformfontdatabase.h
@@ -47,7 +47,9 @@
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QList>
+#if QT_DEPRECATED_SINCE(5, 5)
#include <QtCore/QHash>
+#endif
#include <QtGui/QFontDatabase>
#include <QtGui/private/qfontengine_p.h>
#include <QtGui/private/qfont_p.h>
diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp
index fedf58872b..0fd5f510c7 100644
--- a/src/gui/text/qrawfont.cpp
+++ b/src/gui/text/qrawfont.cpp
@@ -55,7 +55,6 @@ QT_BEGIN_NAMESPACE
\ingroup text
\ingroup shared
- \mainclass
\note QRawFont is a low level class. For most purposes QFont is a more appropriate class.
diff --git a/src/gui/text/qrawfont.h b/src/gui/text/qrawfont.h
index 3798555de5..d710658a9b 100644
--- a/src/gui/text/qrawfont.h
+++ b/src/gui/text/qrawfont.h
@@ -72,13 +72,15 @@ public:
qreal pixelSize,
QFont::HintingPreference hintingPreference = QFont::PreferDefaultHinting);
QRawFont(const QRawFont &other);
+#ifdef Q_COMPILER_RVALUE_REFS
+ QRawFont &operator=(QRawFont &&other) Q_DECL_NOTHROW { swap(other); return *this; }
+#endif
+ QRawFont &operator=(const QRawFont &other);
~QRawFont();
- bool isValid() const;
+ void swap(QRawFont &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
- QRawFont &operator=(const QRawFont &other);
-
- void swap(QRawFont &other) { qSwap(d, other.d); }
+ bool isValid() const;
bool operator==(const QRawFont &other) const;
inline bool operator!=(const QRawFont &other) const
diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp
index fc95a859e7..74f4b10305 100644
--- a/src/gui/text/qstatictext.cpp
+++ b/src/gui/text/qstatictext.cpp
@@ -39,6 +39,10 @@
QT_BEGIN_NAMESPACE
+QStaticTextUserData::~QStaticTextUserData()
+{
+}
+
/*!
\class QStaticText
\brief The QStaticText class enables optimized drawing of text when the text and its layout
@@ -49,7 +53,6 @@ QT_BEGIN_NAMESPACE
\ingroup multimedia
\ingroup text
\ingroup shared
- \mainclass
QStaticText provides a way to cache layout data for a block of text so that it can be drawn
more efficiently than by using QPainter::drawText() in which the layout information is
@@ -555,6 +558,9 @@ namespace {
case PdmDevicePixelRatio:
val = 1;
break;
+ case PdmDevicePixelRatioScaled:
+ val = devicePixelRatioFScale();
+ break;
default:
val = 0;
qWarning("DrawTextItemDevice::metric: Invalid metric command");
diff --git a/src/gui/text/qstatictext.h b/src/gui/text/qstatictext.h
index d2825e73ac..0a1d9429b4 100644
--- a/src/gui/text/qstatictext.h
+++ b/src/gui/text/qstatictext.h
@@ -57,9 +57,13 @@ public:
QStaticText();
QStaticText(const QString &text);
QStaticText(const QStaticText &other);
+#ifdef Q_COMPILER_RVALUE_REFS
+ QStaticText &operator=(QStaticText &&other) Q_DECL_NOTHROW { swap(other); return *this; }
+#endif
+ QStaticText &operator=(const QStaticText &);
~QStaticText();
- void swap(QStaticText &other) { qSwap(data, other.data); }
+ void swap(QStaticText &other) Q_DECL_NOTHROW { qSwap(data, other.data); }
void setText(const QString &text);
QString text() const;
@@ -80,7 +84,6 @@ public:
void setPerformanceHint(PerformanceHint performanceHint);
PerformanceHint performanceHint() const;
- QStaticText &operator=(const QStaticText &);
bool operator==(const QStaticText &) const;
bool operator!=(const QStaticText &) const;
diff --git a/src/gui/text/qstatictext_p.h b/src/gui/text/qstatictext_p.h
index 088e49e2fc..49ca24d51c 100644
--- a/src/gui/text/qstatictext_p.h
+++ b/src/gui/text/qstatictext_p.h
@@ -52,7 +52,8 @@
QT_BEGIN_NAMESPACE
-class QStaticTextUserData
+// ### Qt 6: Unexport again, if QOpenGLStaticTextUserData (the one from QtOpenGL) is gone by then
+class Q_GUI_EXPORT QStaticTextUserData
{
public:
enum Type {
@@ -61,7 +62,7 @@ public:
};
QStaticTextUserData(Type t) : ref(0), type(t) {}
- virtual ~QStaticTextUserData() {}
+ virtual ~QStaticTextUserData();
QAtomicInt ref;
Type type;
diff --git a/src/gui/text/qsyntaxhighlighter.cpp b/src/gui/text/qsyntaxhighlighter.cpp
index 162c646a98..f180a839b7 100644
--- a/src/gui/text/qsyntaxhighlighter.cpp
+++ b/src/gui/text/qsyntaxhighlighter.cpp
@@ -90,13 +90,13 @@ void QSyntaxHighlighterPrivate::applyFormatChanges()
QTextLayout *layout = currentBlock.layout();
- QList<QTextLayout::FormatRange> ranges = layout->additionalFormats();
+ QVector<QTextLayout::FormatRange> ranges = layout->formats();
const int preeditAreaStart = layout->preeditAreaPosition();
const int preeditAreaLength = layout->preeditAreaText().length();
if (preeditAreaLength != 0) {
- QList<QTextLayout::FormatRange>::Iterator it = ranges.begin();
+ QVector<QTextLayout::FormatRange>::Iterator it = ranges.begin();
while (it != ranges.end()) {
if (it->start >= preeditAreaStart
&& it->start + it->length <= preeditAreaStart + preeditAreaLength) {
@@ -142,7 +142,7 @@ void QSyntaxHighlighterPrivate::applyFormatChanges()
}
if (formatsChanged) {
- layout->setAdditionalFormats(ranges);
+ layout->setFormats(ranges);
doc->markContentsDirty(currentBlock.position(), currentBlock.length());
}
}
@@ -329,7 +329,7 @@ void QSyntaxHighlighter::setDocument(QTextDocument *doc)
QTextCursor cursor(d->doc);
cursor.beginEditBlock();
for (QTextBlock blk = d->doc->begin(); blk.isValid(); blk = blk.next())
- blk.layout()->clearAdditionalFormats();
+ blk.layout()->clearFormats();
cursor.endEditBlock();
}
d->doc = doc;
diff --git a/src/gui/text/qtextcursor.h b/src/gui/text/qtextcursor.h
index f04055603c..d42d7a1a70 100644
--- a/src/gui/text/qtextcursor.h
+++ b/src/gui/text/qtextcursor.h
@@ -62,14 +62,17 @@ public:
QTextCursor();
explicit QTextCursor(QTextDocument *document);
QTextCursor(QTextDocumentPrivate *p, int pos);
+ explicit QTextCursor(QTextCursorPrivate *d);
explicit QTextCursor(QTextFrame *frame);
explicit QTextCursor(const QTextBlock &block);
- explicit QTextCursor(QTextCursorPrivate *d);
QTextCursor(const QTextCursor &cursor);
+#ifdef Q_COMPILER_RVALUE_REFS
+ QTextCursor &operator=(QTextCursor &&other) Q_DECL_NOTHROW { swap(other); return *this; }
+#endif
QTextCursor &operator=(const QTextCursor &other);
~QTextCursor();
- void swap(QTextCursor &other) { qSwap(d, other.d); }
+ void swap(QTextCursor &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
bool isNull() const;
@@ -220,6 +223,7 @@ public:
private:
QSharedDataPointer<QTextCursorPrivate> d;
friend class QTextCursorPrivate;
+ friend class QTextDocumentPrivate;
friend class QTextDocumentFragmentPrivate;
friend class QTextCopyHelper;
friend class QWidgetTextControlPrivate;
diff --git a/src/gui/text/qtextcursor_p.h b/src/gui/text/qtextcursor_p.h
index 51fb92d37c..d3cb52d94f 100644
--- a/src/gui/text/qtextcursor_p.h
+++ b/src/gui/text/qtextcursor_p.h
@@ -100,6 +100,9 @@ public:
void aboutToRemoveCell(int from, int to);
+ static QTextCursor fromPosition(QTextDocumentPrivate *d, int pos)
+ { return QTextCursor(d, pos); }
+
QTextDocumentPrivate *priv;
qreal x;
int position;
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index 29e00d481e..3edf652f35 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -33,6 +33,7 @@
#include "qtextdocument.h"
#include <qtextformat.h>
+#include "qtextcursor_p.h"
#include "qtextdocumentlayout_p.h"
#include "qtextdocumentfragment.h"
#include "qtextdocumentfragment_p.h"
@@ -532,7 +533,7 @@ QTextOption QTextDocument::defaultTextOption() const
/*!
\since 4.3
- Sets the default text option.
+ Sets the default text option to \a option.
*/
void QTextDocument::setDefaultTextOption(const QTextOption &option)
{
@@ -1273,7 +1274,7 @@ static bool findInBlock(const QTextBlock &block, const QString &expression, int
}
}
//we have a hit, return the cursor for that.
- *cursor = QTextCursor(block.docHandle(), block.position() + idx);
+ *cursor = QTextCursorPrivate::fromPosition(block.docHandle(), block.position() + idx);
cursor->setPosition(cursor->position() + expression.length(), QTextCursor::KeepAnchor);
return true;
}
@@ -1391,7 +1392,7 @@ static bool findInBlock(const QTextBlock &block, const QRegExp &expression, int
}
}
//we have a hit, return the cursor for that.
- *cursor = QTextCursor(block.docHandle(), block.position() + idx);
+ *cursor = QTextCursorPrivate::fromPosition(block.docHandle(), block.position() + idx);
cursor->setPosition(cursor->position() + expr.matchedLength(), QTextCursor::KeepAnchor);
return true;
}
@@ -1401,7 +1402,9 @@ static bool findInBlock(const QTextBlock &block, const QRegExp &expression, int
/*!
\overload
- Finds the next occurrence, matching the regular expression, \a expr, in the document.
+ Finds the next occurrence that matches the given regular expression,
+ \a expr, within the same paragraph in the document.
+
The search starts at the given \a from position, and proceeds forwards
through the document unless specified otherwise in the search options.
The \a options control the type of search performed. The FindCaseSensitively
@@ -1454,7 +1457,9 @@ QTextCursor QTextDocument::find(const QRegExp & expr, int from, FindFlags option
/*!
\overload
- Finds the next occurrence, matching the regular expression, \a expr, in the document.
+ Finds the next occurrence that matches the given regular expression,
+ \a expr, within the same paragraph in the document.
+
The search starts at the position of the given from \a cursor, and proceeds
forwards through the document unless specified otherwise in the search
options. The \a options control the type of search performed. The FindCaseSensitively
@@ -1463,7 +1468,7 @@ QTextCursor QTextDocument::find(const QRegExp & expr, int from, FindFlags option
Returns a cursor with the match selected if a match was found; otherwise
returns a null cursor.
- If the given \a from cursor has a selection, the search begins after the
+ If the given \a cursor has a selection, the search begins after the
selection; otherwise it begins at the cursor's position.
By default the search is case-sensitive, and can match text anywhere in the
@@ -1515,7 +1520,7 @@ static bool findInBlock(const QTextBlock &block, const QRegularExpression &expre
}
}
//we have a hit, return the cursor for that.
- *cursor = QTextCursor(block.docHandle(), block.position() + idx);
+ *cursor = QTextCursorPrivate::fromPosition(block.docHandle(), block.position() + idx);
cursor->setPosition(cursor->position() + match.capturedLength(), QTextCursor::KeepAnchor);
return true;
}
@@ -1525,7 +1530,9 @@ static bool findInBlock(const QTextBlock &block, const QRegularExpression &expre
/*!
\since 5.5
- Finds the next occurrence, matching the regular expression, \a expr, in the document.
+ Finds the next occurrence that matches the given regular expression,
+ \a expr, within the same paragraph in the document.
+
The search starts at the given \a from position, and proceeds forwards
through the document unless specified otherwise in the search options.
The \a options control the type of search performed.
@@ -1578,7 +1585,9 @@ QTextCursor QTextDocument::find(const QRegularExpression &expr, int from, FindFl
/*!
\since 5.5
- Finds the next occurrence, matching the regular expression, \a expr, in the document.
+ Finds the next occurrence that matches the given regular expression,
+ \a expr, within the same paragraph in the document.
+
The search starts at the position of the given \a cursor, and proceeds
forwards through the document unless specified otherwise in the search
options. The \a options control the type of search performed.
@@ -1948,7 +1957,7 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
for (QTextBlock srcBlock = firstBlock(), dstBlock = clonedDoc->firstBlock();
srcBlock.isValid() && dstBlock.isValid();
srcBlock = srcBlock.next(), dstBlock = dstBlock.next()) {
- dstBlock.layout()->setAdditionalFormats(srcBlock.layout()->additionalFormats());
+ dstBlock.layout()->setFormats(srcBlock.layout()->formats());
}
QAbstractTextDocumentLayout *layout = doc->documentLayout();
diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h
index ca80a88033..f05b624704 100644
--- a/src/gui/text/qtextdocument.h
+++ b/src/gui/text/qtextdocument.h
@@ -109,11 +109,11 @@ class Q_GUI_EXPORT QTextDocument : public QObject
Q_PROPERTY(QUrl baseUrl READ baseUrl WRITE setBaseUrl NOTIFY baseUrlChanged)
public:
- explicit QTextDocument(QObject *parent = 0);
- explicit QTextDocument(const QString &text, QObject *parent = 0);
+ explicit QTextDocument(QObject *parent = Q_NULLPTR);
+ explicit QTextDocument(const QString &text, QObject *parent = Q_NULLPTR);
~QTextDocument();
- QTextDocument *clone(QObject *parent = 0) const;
+ QTextDocument *clone(QObject *parent = Q_NULLPTR) const;
bool isEmpty() const;
virtual void clear();
@@ -157,17 +157,17 @@ public:
};
Q_DECLARE_FLAGS(FindFlags, FindFlag)
- QTextCursor find(const QString &subString, int from = 0, FindFlags options = 0) const;
- QTextCursor find(const QString &subString, const QTextCursor &cursor, FindFlags options = 0) const;
+ QTextCursor find(const QString &subString, int from = 0, FindFlags options = FindFlags()) const;
+ QTextCursor find(const QString &subString, const QTextCursor &cursor, FindFlags options = FindFlags()) const;
#ifndef QT_NO_REGEXP
- QTextCursor find(const QRegExp &expr, int from = 0, FindFlags options = 0) const;
- QTextCursor find(const QRegExp &expr, const QTextCursor &cursor, FindFlags options = 0) const;
+ QTextCursor find(const QRegExp &expr, int from = 0, FindFlags options = FindFlags()) const;
+ QTextCursor find(const QRegExp &expr, const QTextCursor &cursor, FindFlags options = FindFlags()) const;
#endif
#ifndef QT_NO_REGULAREXPRESSION
- QTextCursor find(const QRegularExpression &expr, int from = 0, FindFlags options = 0) const;
- QTextCursor find(const QRegularExpression &expr, const QTextCursor &cursor, FindFlags options = 0) const;
+ QTextCursor find(const QRegularExpression &expr, int from = 0, FindFlags options = FindFlags()) const;
+ QTextCursor find(const QRegularExpression &expr, const QTextCursor &cursor, FindFlags options = FindFlags()) const;
#endif
QTextFrame *frameAt(int pos) const;
diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp
index 5864ca0b1a..c7bbcea4f4 100644
--- a/src/gui/text/qtextdocumentlayout.cpp
+++ b/src/gui/text/qtextdocumentlayout.cpp
@@ -106,7 +106,7 @@ public:
bool sizeDirty;
bool layoutDirty;
- QList<QPointer<QTextFrame> > floats;
+ QVector<QPointer<QTextFrame> > floats;
};
QTextFrameData::QTextFrameData()
@@ -467,9 +467,9 @@ public:
void drawFlow(const QPointF &offset, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &context,
QTextFrame::Iterator it, const QList<QTextFrame *> &floats, QTextBlock *cursorBlockNeedingRepaint) const;
void drawBlock(const QPointF &offset, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &context,
- QTextBlock bl, bool inRootFrame) const;
+ const QTextBlock &bl, bool inRootFrame) const;
void drawListItem(const QPointF &offset, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &context,
- QTextBlock bl, const QTextCharFormat *selectionFormat) const;
+ const QTextBlock &bl, const QTextCharFormat *selectionFormat) const;
void drawTableCell(const QRectF &cellRect, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &cell_context,
QTextTable *table, QTextTableData *td, int r, int c,
QTextBlock *cursorBlockNeedingRepaint, QPointF *cursorBlockOffset) const;
@@ -487,7 +487,7 @@ public:
HitPoint hitTest(QTextFrame::Iterator it, HitPoint hit, const QFixedPoint &p,
int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const;
HitPoint hitTest(QTextTable *table, const QFixedPoint &point, int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const;
- HitPoint hitTest(QTextBlock bl, const QFixedPoint &point, int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const;
+ HitPoint hitTest(const QTextBlock &bl, const QFixedPoint &point, int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const;
QTextLayoutStruct layoutCell(QTextTable *t, const QTextTableCell &cell, QFixed width,
int layoutFrom, int layoutTo, QTextTableData *tableData, QFixed absoluteTableY,
@@ -749,7 +749,7 @@ QTextDocumentLayoutPrivate::hitTest(QTextTable *table, const QFixedPoint &point,
}
QTextDocumentLayoutPrivate::HitPoint
-QTextDocumentLayoutPrivate::hitTest(QTextBlock bl, const QFixedPoint &point, int *position, QTextLayout **l,
+QTextDocumentLayoutPrivate::hitTest(const QTextBlock &bl, const QFixedPoint &point, int *position, QTextLayout **l,
Qt::HitTestAccuracy accuracy) const
{
QTextLayout *tl = bl.layout();
@@ -1071,7 +1071,9 @@ void QTextDocumentLayoutPrivate::drawFrame(const QPointF &offset, QPainter *pain
it = frameIteratorForYPosition(QFixed::fromReal(context.clip.top()));
QList<QTextFrame *> floats;
- for (int i = 0; i < fd->floats.count(); ++i)
+ const int numFloats = fd->floats.count();
+ floats.reserve(numFloats);
+ for (int i = 0; i < numFloats; ++i)
floats.append(fd->floats.at(i));
drawFlow(off, painter, context, it, floats, &cursorBlockNeedingRepaint);
@@ -1283,7 +1285,7 @@ void QTextDocumentLayoutPrivate::drawFlow(const QPointF &offset, QPainter *paint
void QTextDocumentLayoutPrivate::drawBlock(const QPointF &offset, QPainter *painter,
const QAbstractTextDocumentLayout::PaintContext &context,
- QTextBlock bl, bool inRootFrame) const
+ const QTextBlock &bl, bool inRootFrame) const
{
const QTextLayout *tl = bl.layout();
QRectF r = tl->boundingRect();
@@ -1377,7 +1379,7 @@ void QTextDocumentLayoutPrivate::drawBlock(const QPointF &offset, QPainter *pain
void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *painter,
const QAbstractTextDocumentLayout::PaintContext &context,
- QTextBlock bl, const QTextCharFormat *selectionFormat) const
+ const QTextBlock &bl, const QTextCharFormat *selectionFormat) const
{
Q_Q(const QTextDocumentLayout);
const QTextBlockFormat blockFormat = bl.blockFormat();
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 29a633f350..1c924175e2 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -918,10 +918,11 @@ void QTextEngine::shapeLine(const QScriptLine &line)
{
QFixed x;
bool first = true;
- const int end = findItem(line.from + line.length - 1);
int item = findItem(line.from);
if (item == -1)
return;
+
+ const int end = findItem(line.from + line.length - 1, item);
for ( ; item <= end; ++item) {
QScriptItem &si = layoutData->items[item];
if (si.analysis.flags == QScriptAnalysis::Tab) {
@@ -1172,7 +1173,23 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
};
const int num_features = 1;
- bool shapedOk = hb_shape_full(hb_font, buffer, features, num_features, 0);
+ const char *const *shaper_list = Q_NULLPTR;
+#if defined(Q_OS_DARWIN)
+ // What's behind QFontEngine::FaceData::user_data isn't compatible between different font engines
+ // - specifically functions in hb-coretext.cc would run into undefined behavior with data
+ // from non-CoreText engine. The other shapers works with that engine just fine.
+ if (actualFontEngine->type() != QFontEngine::Mac) {
+ static const char *s_shaper_list_without_coretext[] = {
+ "graphite2",
+ "ot",
+ "fallback",
+ Q_NULLPTR
+ };
+ shaper_list = s_shaper_list_without_coretext;
+ }
+#endif
+
+ bool shapedOk = hb_shape_full(hb_font, buffer, features, num_features, shaper_list);
if (Q_UNLIKELY(!shapedOk)) {
hb_buffer_destroy(buffer);
return 0;
@@ -1251,21 +1268,22 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
g.glyphs[i] |= (engineIdx << 24);
}
-#ifdef Q_OS_MAC
- // CTRunGetPosition has a bug which applies matrix on 10.6, so we disable
- // scaling the advances for this particular version
- if (actualFontEngine->fontDef.stretch != 100
- && QSysInfo::MacintoshVersion != QSysInfo::MV_10_6) {
- QFixed stretch = QFixed(int(actualFontEngine->fontDef.stretch)) / QFixed(100);
- for (uint i = 0; i < num_glyphs; ++i)
- g.advances[i] *= stretch;
+#ifdef Q_OS_DARWIN
+ if (actualFontEngine->type() == QFontEngine::Mac) {
+ // CTRunGetPosition has a bug which applies matrix on 10.6, so we disable
+ // scaling the advances for this particular version
+ if (QSysInfo::MacintoshVersion != QSysInfo::MV_10_6 && actualFontEngine->fontDef.stretch != 100) {
+ QFixed stretch = QFixed(int(actualFontEngine->fontDef.stretch)) / QFixed(100);
+ for (uint i = 0; i < num_glyphs; ++i)
+ g.advances[i] *= stretch;
+ }
}
+#endif
- if (actualFontEngine->fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
+ if (!actualFontEngine->supportsSubPixelPositions() || (actualFontEngine->fontDef.styleStrategy & QFont::ForceIntegerMetrics)) {
for (uint i = 0; i < num_glyphs; ++i)
g.advances[i] = g.advances[i].round();
}
-#endif
glyphs_shaped += num_glyphs;
}
@@ -1730,13 +1748,13 @@ bool QTextEngine::isRightToLeft() const
}
-int QTextEngine::findItem(int strPos) const
+int QTextEngine::findItem(int strPos, int firstItem) const
{
itemize();
- if (strPos < 0 || strPos >= layoutData->string.size())
+ if (strPos < 0 || strPos >= layoutData->string.size() || firstItem < 0)
return -1;
- int left = 1;
+ int left = firstItem + 1;
int right = layoutData->items.size()-1;
while(left <= right) {
int middle = ((right-left)/2)+left;
@@ -2155,7 +2173,7 @@ void QTextEngine::justify(const QScriptLine &line)
return;
int firstItem = findItem(line.from);
- int lastItem = findItem(line.from + line_length - 1);
+ int lastItem = findItem(line.from + line_length - 1, firstItem);
int nItems = (firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0;
QVarLengthArray<QJustificationPoint> justificationPoints;
@@ -2571,7 +2589,7 @@ void QTextEngine::setPreeditArea(int position, const QString &preeditText)
clearLineData();
}
-void QTextEngine::setFormats(const QList<QTextLayout::FormatRange> &formats)
+void QTextEngine::setFormats(const QVector<QTextLayout::FormatRange> &formats)
{
if (formats.isEmpty()) {
if (!specialData)
@@ -2863,6 +2881,7 @@ QFixed QTextEngine::calculateTabWidth(int item, QFixed x) const
if (!tabArray.isEmpty()) {
if (isRightToLeft()) { // rebase the tabArray positions.
QList<QTextOption::Tab> newTabs;
+ newTabs.reserve(tabArray.count());
QList<QTextOption::Tab>::Iterator iter = tabArray.begin();
while(iter != tabArray.end()) {
QTextOption::Tab tab = *iter;
@@ -2946,17 +2965,17 @@ QFixed QTextEngine::calculateTabWidth(int item, QFixed x) const
namespace {
class FormatRangeComparatorByStart {
- const QList<QTextLayout::FormatRange> &list;
+ const QVector<QTextLayout::FormatRange> &list;
public:
- FormatRangeComparatorByStart(const QList<QTextLayout::FormatRange> &list) : list(list) { }
+ FormatRangeComparatorByStart(const QVector<QTextLayout::FormatRange> &list) : list(list) { }
bool operator()(int a, int b) {
return list.at(a).start < list.at(b).start;
}
};
class FormatRangeComparatorByEnd {
- const QList<QTextLayout::FormatRange> &list;
+ const QVector<QTextLayout::FormatRange> &list;
public:
- FormatRangeComparatorByEnd(const QList<QTextLayout::FormatRange> &list) : list(list) { }
+ FormatRangeComparatorByEnd(const QVector<QTextLayout::FormatRange> &list) : list(list) { }
bool operator()(int a, int b) {
return list.at(a).start + list.at(a).length < list.at(b).start + list.at(b).length;
}
@@ -3511,7 +3530,7 @@ QTextLineItemIterator::QTextLineItemIterator(QTextEngine *_eng, int _lineNum, co
lineNum(_lineNum),
lineEnd(line.from + line.length),
firstItem(eng->findItem(line.from)),
- lastItem(eng->findItem(lineEnd - 1)),
+ lastItem(eng->findItem(lineEnd - 1, firstItem)),
nItems((firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0),
logicalItem(-1),
item(-1),
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index 39b9e0cb5a..39c228fd52 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -107,6 +107,22 @@ struct Q_GUI_EXPORT glyph_metrics_t
glyph_metrics_t transformed(const QTransform &xform) const;
inline bool isValid() const {return x != 100000 && y != 100000;}
+
+ inline QFixed leftBearing() const
+ {
+ if (!isValid())
+ return QFixed();
+
+ return x;
+ }
+
+ inline QFixed rightBearing() const
+ {
+ if (!isValid())
+ return QFixed();
+
+ return xoff - x - width;
+ }
};
Q_DECLARE_TYPEINFO(glyph_metrics_t, Q_PRIMITIVE_TYPE);
@@ -351,8 +367,7 @@ struct Q_AUTOTEST_EXPORT QScriptLine
uint leadingIncluded : 1;
QFixed height() const { return ascent + descent
+ (leadingIncluded? qMax(QFixed(),leading) : QFixed()); }
- QFixed base() const { return ascent
- + (leadingIncluded ? qMax(QFixed(),leading) : QFixed()); }
+ QFixed base() const { return ascent; }
void setDefaultHeight(QTextEngine *eng);
void operator+=(const QScriptLine &other);
};
@@ -400,6 +415,7 @@ public:
};
struct ItemDecoration {
+ ItemDecoration() {} // for QVector, don't use
ItemDecoration(qreal x1, qreal x2, qreal y, const QPen &pen):
x1(x1), x2(x2), y(y), pen(pen) {}
@@ -409,7 +425,7 @@ public:
QPen pen;
};
- typedef QList<ItemDecoration> ItemDecorationList;
+ typedef QVector<ItemDecoration> ItemDecorationList;
QTextEngine();
QTextEngine(const QString &str, const QFont &f);
@@ -496,7 +512,7 @@ public:
void freeMemory();
- int findItem(int strPos) const;
+ int findItem(int strPos, int firstItem = 0) const;
inline QTextFormatCollection *formatCollection() const {
if (block.docHandle())
return block.docHandle()->formatCollection();
@@ -570,9 +586,9 @@ public:
inline bool hasFormats() const
{ return block.docHandle() || (specialData && !specialData->formats.isEmpty()); }
- inline QList<QTextLayout::FormatRange> formats() const
- { return specialData ? specialData->formats : QList<QTextLayout::FormatRange>(); }
- void setFormats(const QList<QTextLayout::FormatRange> &formats);
+ inline QVector<QTextLayout::FormatRange> formats() const
+ { return specialData ? specialData->formats : QVector<QTextLayout::FormatRange>(); }
+ void setFormats(const QVector<QTextLayout::FormatRange> &formats);
private:
static void init(QTextEngine *e);
@@ -580,7 +596,7 @@ private:
struct SpecialData {
int preeditPosition;
QString preeditText;
- QList<QTextLayout::FormatRange> formats;
+ QVector<QTextLayout::FormatRange> formats;
QVector<QTextCharFormat> resolvedFormats;
// only used when no docHandle is available
QScopedPointer<QTextFormatCollection> formatCollection;
@@ -643,6 +659,7 @@ public:
LayoutData _layoutData;
void *_memory[MemSize];
};
+Q_DECLARE_TYPEINFO(QTextEngine::ItemDecoration, Q_MOVABLE_TYPE);
struct QTextLineItemIterator
{
diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp
index ba4bdcc5ad..7dcd060ba1 100644
--- a/src/gui/text/qtextformat.cpp
+++ b/src/gui/text/qtextformat.cpp
@@ -38,7 +38,7 @@
#include <qdatastream.h>
#include <qdebug.h>
#include <qmap.h>
-#include <qhash.h>
+#include <qhashfunctions.h>
QT_BEGIN_NAMESPACE
@@ -1115,7 +1115,9 @@ void QTextFormat::setProperty(int propertyId, const QVector<QTextLength> &value)
if (!d)
d = new QTextFormatPrivate;
QVariantList list;
- for (int i=0; i<value.size(); ++i)
+ const int numValues = value.size();
+ list.reserve(numValues);
+ for (int i = 0; i < numValues; ++i)
list << value.at(i);
d->insertProperty(propertyId, list);
}
@@ -2041,6 +2043,7 @@ QTextBlockFormat::QTextBlockFormat(const QTextFormat &fmt)
void QTextBlockFormat::setTabPositions(const QList<QTextOption::Tab> &tabs)
{
QList<QVariant> list;
+ list.reserve(tabs.count());
QList<QTextOption::Tab>::ConstIterator iter = tabs.constBegin();
while (iter != tabs.constEnd()) {
QVariant v;
@@ -2065,6 +2068,7 @@ QList<QTextOption::Tab> QTextBlockFormat::tabPositions() const
QList<QTextOption::Tab> answer;
QList<QVariant> variantsList = qvariant_cast<QList<QVariant> >(variant);
QList<QVariant>::Iterator iter = variantsList.begin();
+ answer.reserve(variantsList.count());
while(iter != variantsList.end()) {
answer.append( qvariant_cast<QTextOption::Tab>(*iter));
++iter;
diff --git a/src/gui/text/qtextformat_p.h b/src/gui/text/qtextformat_p.h
index 29656bbafe..928cef6488 100644
--- a/src/gui/text/qtextformat_p.h
+++ b/src/gui/text/qtextformat_p.h
@@ -47,7 +47,6 @@
#include "QtGui/qtextformat.h"
#include "QtCore/qvector.h"
-#include "QtCore/qhash.h"
QT_BEGIN_NAMESPACE
diff --git a/src/gui/text/qtextimagehandler.cpp b/src/gui/text/qtextimagehandler.cpp
index e85890baf2..16d81a7d6d 100644
--- a/src/gui/text/qtextimagehandler.cpp
+++ b/src/gui/text/qtextimagehandler.cpp
@@ -44,7 +44,10 @@
QT_BEGIN_NAMESPACE
-static QString resolveFileName(QString fileName, QUrl *url, qreal targetDevicePixelRatio)
+extern QString qt_findAtNxFile(const QString &baseFileName, qreal targetDevicePixelRatio,
+ qreal *sourceDevicePixelRatio);
+static QString resolveFileName(QString fileName, QUrl *url, qreal targetDevicePixelRatio,
+ qreal *sourceDevicePixelRatio)
{
// We might use the fileName for loading if url loading fails
// try to make sure it is a valid file path.
@@ -62,19 +65,8 @@ static QString resolveFileName(QString fileName, QUrl *url, qreal targetDevicePi
if (targetDevicePixelRatio <= 1.0)
return fileName;
- // try to find a 2x version
-
- const int dotIndex = fileName.lastIndexOf(QLatin1Char('.'));
- if (dotIndex != -1) {
- QString at2xfileName = fileName;
- at2xfileName.insert(dotIndex, QStringLiteral("@2x"));
- if (QFile::exists(at2xfileName)) {
- fileName = at2xfileName;
- *url = QUrl(fileName);
- }
- }
-
- return fileName;
+ // try to find a Nx version
+ return qt_findAtNxFile(fileName, targetDevicePixelRatio, sourceDevicePixelRatio);
}
@@ -86,7 +78,8 @@ static QPixmap getPixmap(QTextDocument *doc, const QTextImageFormat &format, con
if (name.startsWith(QLatin1String(":/"))) // auto-detect resources and convert them to url
name.prepend(QLatin1String("qrc"));
QUrl url = QUrl(name);
- name = resolveFileName(name, &url, devicePixelRatio);
+ qreal sourcePixelRatio = 1.0;
+ name = resolveFileName(name, &url, devicePixelRatio, &sourcePixelRatio);
const QVariant data = doc->resource(QTextDocument::ImageResource, url);
if (data.type() == QVariant::Pixmap || data.type() == QVariant::Image) {
pm = qvariant_cast<QPixmap>(data);
@@ -112,7 +105,7 @@ static QPixmap getPixmap(QTextDocument *doc, const QTextImageFormat &format, con
}
if (name.contains(QStringLiteral("@2x")))
- pm.setDevicePixelRatio(2.0);
+ pm.setDevicePixelRatio(sourcePixelRatio);
return pm;
}
@@ -167,7 +160,8 @@ static QImage getImage(QTextDocument *doc, const QTextImageFormat &format, const
if (name.startsWith(QLatin1String(":/"))) // auto-detect resources
name.prepend(QLatin1String("qrc"));
QUrl url = QUrl(name);
- name = resolveFileName(name, &url, devicePixelRatio);
+ qreal sourcePixelRatio = 1.0;
+ name = resolveFileName(name, &url, devicePixelRatio, &sourcePixelRatio);
const QVariant data = doc->resource(QTextDocument::ImageResource, url);
if (data.type() == QVariant::Image) {
image = qvariant_cast<QImage>(data);
@@ -191,8 +185,8 @@ static QImage getImage(QTextDocument *doc, const QTextImageFormat &format, const
doc->addResource(QTextDocument::ImageResource, url, image);
}
- if (name.contains(QStringLiteral("@2x")))
- image.setDevicePixelRatio(2.0);
+ if (sourcePixelRatio != 1.0)
+ image.setDevicePixelRatio(sourcePixelRatio);
return image;
}
@@ -256,10 +250,10 @@ void QTextImageHandler::drawObject(QPainter *p, const QRectF &rect, QTextDocumen
const QTextImageFormat imageFormat = format.toImageFormat();
if (QCoreApplication::instance()->thread() != QThread::currentThread()) {
- const QImage image = getImage(doc, imageFormat, p->device()->devicePixelRatio());
+ const QImage image = getImage(doc, imageFormat, p->device()->devicePixelRatioF());
p->drawImage(rect, image, image.rect());
} else {
- const QPixmap pixmap = getPixmap(doc, imageFormat, p->device()->devicePixelRatio());
+ const QPixmap pixmap = getPixmap(doc, imageFormat, p->device()->devicePixelRatioF());
p->drawPixmap(rect, pixmap, pixmap.rect());
}
}
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index 013cd8ae0f..9e2a23a7f7 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -69,7 +69,7 @@ QT_BEGIN_NAMESPACE
for a specified area in the text layout's content.
\inmodule QtGui
- \sa QTextLayout::setAdditionalFormats(), QTextLayout::draw()
+ \sa QTextLayout::setFormats(), QTextLayout::draw()
*/
/*!
@@ -87,6 +87,20 @@ QT_BEGIN_NAMESPACE
Specifies the format to apply.
*/
+/*! \fn bool operator==(const FormatRange &lhs, const FormatRange &rhs)
+ \relates QTextLayout::FormatRange
+
+ Returns true if the \c {start}, \c {length}, and \c {format} fields
+ in \a lhs and \a rhs contain the same values respectively.
+ */
+
+/*! \fn bool operator!=(const FormatRange &lhs, const FormatRange &rhs)
+ \relates QTextLayout::FormatRange
+
+ Returns true if any of the \c {start}, \c {length}, or \c {format} fields
+ in \a lhs and \a rhs contain different values respectively.
+ */
+
/*!
\class QTextInlineObject
\reentrant
@@ -485,39 +499,76 @@ QString QTextLayout::preeditAreaText() const
return d->preeditAreaText();
}
+#if QT_DEPRECATED_SINCE(5, 6)
+/*!
+ \obsolete Use setFormats() instead.
+*/
+void QTextLayout::setAdditionalFormats(const QList<FormatRange> &formatList)
+{
+ setFormats(formatList.toVector());
+}
+#endif // deprecated since 5.6
/*!
- Sets the additional formats supported by the text layout to \a formatList.
+ \since 5.6
+
+ Sets the additional formats supported by the text layout to \a formats.
The formats are applied with preedit area text in place.
- \sa additionalFormats(), clearAdditionalFormats()
+ \sa formats(), clearFormats()
*/
-void QTextLayout::setAdditionalFormats(const QList<FormatRange> &formatList)
+void QTextLayout::setFormats(const QVector<FormatRange> &formats)
{
- d->setFormats(formatList);
+ d->setFormats(formats);
if (d->block.docHandle())
d->block.docHandle()->documentChange(d->block.position(), d->block.length());
}
+#if QT_DEPRECATED_SINCE(5, 6)
/*!
- Returns the list of additional formats supported by the text layout.
+ \obsolete Use formats() instead.
\sa setAdditionalFormats(), clearAdditionalFormats()
*/
QList<QTextLayout::FormatRange> QTextLayout::additionalFormats() const
{
+ return formats().toList();
+}
+#endif // deprecated since 5.6
+
+/*!
+ \since 5.6
+
+ Returns the list of additional formats supported by the text layout.
+
+ \sa setFormats(), clearFormats()
+*/
+QVector<QTextLayout::FormatRange> QTextLayout::formats() const
+{
return d->formats();
}
+#if QT_DEPRECATED_SINCE(5, 6)
/*!
+ \obsolete Use clearFormats() instead.
+*/
+void QTextLayout::clearAdditionalFormats()
+{
+ clearFormats();
+}
+#endif // deprecated since 5.6
+
+/*!
+ \since 5.6
+
Clears the list of additional formats supported by the text layout.
- \sa additionalFormats(), setAdditionalFormats()
+ \sa formats(), setFormats()
*/
-void QTextLayout::clearAdditionalFormats()
+void QTextLayout::clearFormats()
{
- setAdditionalFormats(QList<FormatRange>());
+ setFormats(QVector<FormatRange>());
}
/*!
@@ -1007,12 +1058,15 @@ QList<QGlyphRun> QTextLayout::glyphRuns(int from, int length) const
QVector<quint32> indexes = oldGlyphRun.glyphIndexes();
QVector<QPointF> positions = oldGlyphRun.positions();
+ QRectF boundingRect = oldGlyphRun.boundingRect();
indexes += glyphRun.glyphIndexes();
positions += glyphRun.positions();
+ boundingRect = boundingRect.united(glyphRun.boundingRect());
oldGlyphRun.setGlyphIndexes(indexes);
oldGlyphRun.setPositions(positions);
+ oldGlyphRun.setBoundingRect(boundingRect);
} else {
glyphRunHash[key] = glyphRun;
}
@@ -1915,9 +1969,16 @@ void QTextLine::layout_helper(int maxGlyphs)
// end up breaking due to the current glyph being too wide.
QFixed previousRightBearing = lbh.rightBearing;
- // We ignore the right bearing if the minimum negative bearing is too little to
- // expand the text beyond the edge.
- if (lbh.calculateNewWidth(line) - lbh.minimumRightBearing > line.width)
+ // We skip calculating the right bearing if the minimum negative bearing is too
+ // small to possibly expand the text beyond the edge. Note that this optimization
+ // will in some cases fail, as the minimum right bearing reported by the font
+ // engine may not cover all the glyphs in the font. The result is that we think
+ // we don't need to break at the current glyph (because the right bearing is 0),
+ // and when we then end up breaking on the next glyph we compute the right bearing
+ // and end up with a line width that is slightly larger width than what was requested.
+ // Unfortunately we can't remove this optimization as it will slow down text
+ // layouting significantly, so we accept the slight correctnes issue.
+ if ((lbh.calculateNewWidth(line) + qAbs(lbh.minimumRightBearing)) > line.width)
lbh.calculateRightBearing();
if (lbh.checkFullOtherwiseExtend(line)) {
@@ -2559,33 +2620,31 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR
inside the line, taking account of the \a edge.
If \a cursorPos is not a valid cursor position, the nearest valid
- cursor position will be used instead, and cpos will be modified to
+ cursor position will be used instead, and \a cursorPos will be modified to
point to this valid cursor position.
\sa xToCursor()
*/
qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
{
- if (!eng->layoutData)
- eng->itemize();
-
const QScriptLine &line = eng->lines[index];
bool lastLine = index >= eng->lines.size() - 1;
- QFixed x = line.x;
- x += eng->alignLine(line) - eng->leadingSpaceWidth(line);
+ QFixed x = line.x + eng->alignLine(line) - eng->leadingSpaceWidth(line);
- if (!index && !eng->layoutData->items.size()) {
- *cursorPos = 0;
+ if (!eng->layoutData)
+ eng->itemize();
+ if (!eng->layoutData->items.size()) {
+ *cursorPos = line.from;
return x.toReal();
}
int lineEnd = line.from + line.length + line.trailingSpaces;
- int pos = qBound(0, *cursorPos, lineEnd);
+ int pos = qBound(line.from, *cursorPos, lineEnd);
int itm;
const QCharAttributes *attributes = eng->attributes();
if (!attributes) {
- *cursorPos = 0;
+ *cursorPos = line.from;
return x.toReal();
}
while (pos < lineEnd && !attributes[pos].graphemeBoundary)
@@ -2597,7 +2656,7 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
else
itm = eng->findItem(pos);
if (itm < 0) {
- *cursorPos = 0;
+ *cursorPos = line.from;
return x.toReal();
}
eng->shapeLine(line);
@@ -2605,18 +2664,14 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
const QScriptItem *si = &eng->layoutData->items[itm];
if (!si->num_glyphs)
eng->shape(itm);
- pos -= si->position;
+
+ const int l = eng->length(itm);
+ pos = qBound(0, pos - si->position, l);
QGlyphLayout glyphs = eng->shapedGlyphs(si);
unsigned short *logClusters = eng->logClusters(si);
Q_ASSERT(logClusters);
- int l = eng->length(itm);
- if (pos > l)
- pos = l;
- if (pos < 0)
- pos = 0;
-
int glyph_pos = pos == l ? si->num_glyphs : logClusters[pos];
if (edge == Trailing && glyph_pos < si->num_glyphs) {
// trailing edge is leading edge of next cluster
@@ -2625,13 +2680,13 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
glyph_pos++;
}
- bool reverse = eng->layoutData->items[itm].analysis.bidiLevel % 2;
+ bool reverse = si->analysis.bidiLevel % 2;
// add the items left of the cursor
int firstItem = eng->findItem(line.from);
- int lastItem = eng->findItem(lineEnd - 1);
+ int lastItem = eng->findItem(lineEnd - 1, itm);
int nItems = (firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0;
QVarLengthArray<int> visualOrder(nItems);
@@ -2652,13 +2707,15 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
x += si.width;
continue;
}
+
+ const int itemLength = eng->length(item);
int start = qMax(line.from, si.position);
- int end = qMin(lineEnd, si.position + eng->length(item));
+ int end = qMin(lineEnd, si.position + itemLength);
logClusters = eng->logClusters(&si);
int gs = logClusters[start-si.position];
- int ge = (end == si.position + eng->length(item)) ? si.num_glyphs-1 : logClusters[end-si.position-1];
+ int ge = (end == si.position + itemLength) ? si.num_glyphs-1 : logClusters[end-si.position-1];
QGlyphLayout glyphs = eng->shapedGlyphs(&si);
@@ -2730,7 +2787,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
return line.from;
int firstItem = eng->findItem(line.from);
- int lastItem = eng->findItem(line.from + line_length - 1);
+ int lastItem = eng->findItem(line.from + line_length - 1, firstItem);
int nItems = (firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0;
if (!nItems)
diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h
index 47dcd388e2..f74d4d4229 100644
--- a/src/gui/text/qtextlayout.h
+++ b/src/gui/text/qtextlayout.h
@@ -62,7 +62,7 @@ class Q_GUI_EXPORT QTextInlineObject
{
public:
QTextInlineObject(int i, QTextEngine *e) : itm(i), eng(e) {}
- inline QTextInlineObject() : itm(0), eng(0) {}
+ inline QTextInlineObject() : itm(0), eng(Q_NULLPTR) {}
inline bool isValid() const { return eng; }
QRectF rect() const;
@@ -100,7 +100,7 @@ public:
// does itemization
QTextLayout();
QTextLayout(const QString& text);
- QTextLayout(const QString& text, const QFont &font, QPaintDevice *paintdevice = 0);
+ QTextLayout(const QString& text, const QFont &font, QPaintDevice *paintdevice = Q_NULLPTR);
QTextLayout(const QTextBlock &b);
~QTextLayout();
@@ -125,10 +125,20 @@ public:
int start;
int length;
QTextCharFormat format;
+
+ friend bool operator==(const FormatRange &lhs, const FormatRange &rhs)
+ { return lhs.start == rhs.start && lhs.length == rhs.length && lhs.format == rhs.format; }
+ friend bool operator!=(const FormatRange &lhs, const FormatRange &rhs)
+ { return !operator==(lhs, rhs); }
};
- void setAdditionalFormats(const QList<FormatRange> &overrides);
- QList<FormatRange> additionalFormats() const;
- void clearAdditionalFormats();
+#if QT_DEPRECATED_SINCE(5, 6)
+ QT_DEPRECATED_X("Use setFormats()") void setAdditionalFormats(const QList<FormatRange> &overrides);
+ QT_DEPRECATED_X("Use formats()") QList<FormatRange> additionalFormats() const;
+ QT_DEPRECATED_X("Use clearFormats()") void clearAdditionalFormats();
+#endif
+ void setFormats(const QVector<FormatRange> &overrides);
+ QVector<FormatRange> formats() const;
+ void clearFormats();
void setCacheEnabled(bool enable);
bool cacheEnabled() const;
@@ -192,7 +202,7 @@ private:
class Q_GUI_EXPORT QTextLine
{
public:
- inline QTextLine() : index(0), eng(0) {}
+ inline QTextLine() : index(0), eng(Q_NULLPTR) {}
inline bool isValid() const { return eng; }
QRectF rect() const;
@@ -237,7 +247,7 @@ public:
int lineNumber() const { return index; }
- void draw(QPainter *p, const QPointF &point, const QTextLayout::FormatRange *selection = 0) const;
+ void draw(QPainter *p, const QPointF &point, const QTextLayout::FormatRange *selection = Q_NULLPTR) const;
#if !defined(QT_NO_RAWFONT)
QList<QGlyphRun> glyphRuns(int from = -1, int length = -1) const;
diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp
index df7c8b9c71..e70b8ed300 100644
--- a/src/gui/text/qtextobject.cpp
+++ b/src/gui/text/qtextobject.cpp
@@ -33,6 +33,7 @@
#include "qtextobject.h"
#include "qtextobject_p.h"
+#include "qtextcursor_p.h"
#include "qtextdocument.h"
#include "qtextformat_p.h"
#include "qtextdocument_p.h"
@@ -461,7 +462,7 @@ QTextFrame *QTextFrame::parentFrame() const
QTextCursor QTextFrame::firstCursorPosition() const
{
Q_D(const QTextFrame);
- return QTextCursor(d->pieceTable, firstPosition());
+ return QTextCursorPrivate::fromPosition(d->pieceTable, firstPosition());
}
/*!
@@ -472,7 +473,7 @@ QTextCursor QTextFrame::firstCursorPosition() const
QTextCursor QTextFrame::lastCursorPosition() const
{
Q_D(const QTextFrame);
- return QTextCursor(d->pieceTable, lastPosition());
+ return QTextCursorPrivate::fromPosition(d->pieceTable, lastPosition());
}
/*!
diff --git a/src/gui/text/qtextobject.h b/src/gui/text/qtextobject.h
index 9ad912d992..fbb90e42b0 100644
--- a/src/gui/text/qtextobject.h
+++ b/src/gui/text/qtextobject.h
@@ -190,7 +190,7 @@ class Q_GUI_EXPORT QTextBlock
friend class QSyntaxHighlighter;
public:
inline QTextBlock(QTextDocumentPrivate *priv, int b) : p(priv), n(b) {}
- inline QTextBlock() : p(0), n(0) {}
+ inline QTextBlock() : p(Q_NULLPTR), n(0) {}
inline QTextBlock(const QTextBlock &o) : p(o.p), n(o.n) {}
inline QTextBlock &operator=(const QTextBlock &o) { p = o.p; n = o.n; return *this; }
@@ -247,7 +247,7 @@ public:
friend class QTextBlock;
iterator(const QTextDocumentPrivate *priv, int begin, int end, int f) : p(priv), b(begin), e(end), n(f) {}
public:
- iterator() : p(0), b(0), e(0), n(0) {}
+ iterator() : p(Q_NULLPTR), b(0), e(0), n(0) {}
iterator(const iterator &o) : p(o.p), b(o.b), e(o.e), n(o.n) {}
QTextFragment fragment() const;
@@ -289,7 +289,7 @@ class Q_GUI_EXPORT QTextFragment
{
public:
inline QTextFragment(const QTextDocumentPrivate *priv, int f, int fe) : p(priv), n(f), ne(fe) {}
- inline QTextFragment() : p(0), n(0), ne(0) {}
+ inline QTextFragment() : p(Q_NULLPTR), n(0), ne(0) {}
inline QTextFragment(const QTextFragment &o) : p(o.p), n(o.n), ne(o.ne) {}
inline QTextFragment &operator=(const QTextFragment &o) { p = o.p; n = o.n; ne = o.ne; return *this; }
diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp
index 6b17a264b1..1fd20cfbef 100644
--- a/src/gui/text/qtextodfwriter.cpp
+++ b/src/gui/text/qtextodfwriter.cpp
@@ -279,6 +279,12 @@ void QTextOdfWriter::writeBlock(QXmlStreamWriter &writer, const QTextBlock &bloc
writer.writeAttribute(textNS, QString::fromLatin1("style-name"), QString::fromLatin1("p%1")
.arg(block.blockFormatIndex()));
for (QTextBlock::Iterator frag = block.begin(); !frag.atEnd(); ++frag) {
+ bool isHyperlink = frag.fragment().charFormat().hasProperty(QTextFormat::AnchorHref);
+ if (isHyperlink) {
+ QString value = frag.fragment().charFormat().property(QTextFormat::AnchorHref).toString();
+ writer.writeStartElement(textNS, QString::fromLatin1("a"));
+ writer.writeAttribute(xlinkNS, QString::fromLatin1("href"), value);
+ }
writer.writeCharacters(QString()); // Trick to make sure that the span gets no linefeed in front of it.
writer.writeStartElement(textNS, QString::fromLatin1("span"));
@@ -335,6 +341,9 @@ void QTextOdfWriter::writeBlock(QXmlStreamWriter &writer, const QTextBlock &bloc
writer.writeCharacters(fragmentText.mid(exportedIndex));
writer.writeEndElement(); // span
+ writer.writeCharacters(QString()); // Trick to make sure that the span gets no linefeed behind it.
+ if (isHyperlink)
+ writer.writeEndElement(); // a
}
writer.writeCharacters(QString()); // Trick to make sure that the span gets no linefeed behind it.
writer.writeEndElement(); // p
@@ -396,7 +405,7 @@ void QTextOdfWriter::writeInlineCharacter(QXmlStreamWriter &writer, const QTextF
writer.writeEndElement(); // frame
}
-void QTextOdfWriter::writeFormats(QXmlStreamWriter &writer, QSet<int> formats) const
+void QTextOdfWriter::writeFormats(QXmlStreamWriter &writer, const QSet<int> &formats) const
{
writer.writeStartElement(officeNS, QString::fromLatin1("automatic-styles"));
QVector<QTextFormat> allStyles = m_document->allFormats();
diff --git a/src/gui/text/qtextodfwriter_p.h b/src/gui/text/qtextodfwriter_p.h
index 20805a8d27..15a4b40796 100644
--- a/src/gui/text/qtextodfwriter_p.h
+++ b/src/gui/text/qtextodfwriter_p.h
@@ -83,7 +83,7 @@ public:
bool createArchive() const { return m_createArchive; }
void writeBlock(QXmlStreamWriter &writer, const QTextBlock &block);
- void writeFormats(QXmlStreamWriter &writer, QSet<int> formatIds) const;
+ void writeFormats(QXmlStreamWriter &writer, const QSet<int> &formatIds) const;
void writeBlockFormat(QXmlStreamWriter &writer, QTextBlockFormat format, int formatIndex) const;
void writeCharacterFormat(QXmlStreamWriter &writer, QTextCharFormat format, int formatIndex) const;
void writeListFormat(QXmlStreamWriter &writer, QTextListFormat format, int formatIndex) const;
diff --git a/src/gui/text/qtextoption.cpp b/src/gui/text/qtextoption.cpp
index dbafcfd58e..5a4f6b7954 100644
--- a/src/gui/text/qtextoption.cpp
+++ b/src/gui/text/qtextoption.cpp
@@ -146,6 +146,7 @@ void QTextOption::setTabArray(const QList<qreal> &tabStops)
d = new QTextOptionPrivate;
QList<QTextOption::Tab> tabs;
QTextOption::Tab tab;
+ tabs.reserve(tabStops.count());
foreach (qreal pos, tabStops) {
tab.position = pos;
tabs.append(tab);
@@ -174,10 +175,11 @@ void QTextOption::setTabs(const QList<QTextOption::Tab> &tabStops)
*/
QList<qreal> QTextOption::tabArray() const
{
+ QList<qreal> answer;
if (!d)
- return QList<qreal>();
+ return answer;
- QList<qreal> answer;
+ answer.reserve(d->tabStops.count());
QList<QTextOption::Tab>::ConstIterator iter = d->tabStops.constBegin();
while(iter != d->tabStops.constEnd()) {
answer.append( (*iter).position);
diff --git a/src/gui/text/qtexttable.cpp b/src/gui/text/qtexttable.cpp
index a75a1aae54..553dc3c772 100644
--- a/src/gui/text/qtexttable.cpp
+++ b/src/gui/text/qtexttable.cpp
@@ -35,6 +35,7 @@
#include "qtextcursor.h"
#include "qtextformat.h"
#include <qdebug.h>
+#include "qtextcursor_p.h"
#include "qtexttable_p.h"
#include "qvarlengtharray.h"
@@ -220,7 +221,7 @@ int QTextTableCell::columnSpan() const
*/
QTextCursor QTextTableCell::firstCursorPosition() const
{
- return QTextCursor(table->d_func()->pieceTable, firstPosition());
+ return QTextCursorPrivate::fromPosition(table->d_func()->pieceTable, firstPosition());
}
/*!
@@ -230,7 +231,7 @@ QTextCursor QTextTableCell::firstCursorPosition() const
*/
QTextCursor QTextTableCell::lastCursorPosition() const
{
- return QTextCursor(table->d_func()->pieceTable, lastPosition());
+ return QTextCursorPrivate::fromPosition(table->d_func()->pieceTable, lastPosition());
}
@@ -986,8 +987,8 @@ void QTextTable::removeColumns(int pos, int num)
Merges the cell at the specified \a row and \a column with the adjacent cells
into one cell. The new cell will span \a numRows rows and \a numCols columns.
- If \a numRows or \a numCols is less than the current number of rows or columns
- the cell spans then this method does nothing.
+ This method does nothing if \a numRows or \a numCols is less than the current
+ number of rows or columns spanned by the cell.
\sa splitCell()
*/
@@ -1103,10 +1104,10 @@ void QTextTable::mergeCells(int row, int column, int numRows, int numCols)
if (nextPos > pos) {
if (needsParagraph) {
needsParagraph = false;
- QTextCursor(p, insertPos++).insertBlock();
+ QTextCursorPrivate::fromPosition(p, insertPos++).insertBlock();
p->move(pos + 1, insertPos, nextPos - pos);
} else if (rowHasText) {
- QTextCursor(p, insertPos++).insertText(QLatin1String(" "));
+ QTextCursorPrivate::fromPosition(p, insertPos++).insertText(QLatin1String(" "));
p->move(pos + 1, insertPos, nextPos - pos);
} else {
p->move(pos, insertPos, nextPos - pos);
@@ -1282,7 +1283,7 @@ QTextCursor QTextTable::rowStart(const QTextCursor &c) const
int row = cell.row();
QTextDocumentPrivate *p = d->pieceTable;
QTextDocumentPrivate::FragmentIterator it(&p->fragmentMap(), d->grid[row*d->nCols]);
- return QTextCursor(p, it.position());
+ return QTextCursorPrivate::fromPosition(p, it.position());
}
/*!
@@ -1304,7 +1305,7 @@ QTextCursor QTextTable::rowEnd(const QTextCursor &c) const
int fragment = row < d->nRows ? d->grid[row*d->nCols] : d->fragment_end;
QTextDocumentPrivate *p = d->pieceTable;
QTextDocumentPrivate::FragmentIterator it(&p->fragmentMap(), fragment);
- return QTextCursor(p, it.position() - 1);
+ return QTextCursorPrivate::fromPosition(p, it.position() - 1);
}
/*!
diff --git a/src/gui/text/qtexttable.h b/src/gui/text/qtexttable.h
index 6ceb1fdd0f..4ff7d19e85 100644
--- a/src/gui/text/qtexttable.h
+++ b/src/gui/text/qtexttable.h
@@ -48,7 +48,7 @@ class QTextTablePrivate;
class Q_GUI_EXPORT QTextTableCell
{
public:
- QTextTableCell() : table(0) {}
+ QTextTableCell() : table(Q_NULLPTR) {}
~QTextTableCell() {}
QTextTableCell(const QTextTableCell &o) : table(o.table), fragment(o.fragment) {}
QTextTableCell &operator=(const QTextTableCell &o)
@@ -63,7 +63,7 @@ public:
int rowSpan() const;
int columnSpan() const;
- inline bool isValid() const { return table != 0; }
+ inline bool isValid() const { return table != Q_NULLPTR; }
QTextCursor firstCursorPosition() const;
QTextCursor lastCursorPosition() const;
diff --git a/src/gui/text/qzip.cpp b/src/gui/text/qzip.cpp
index 1d621db0e6..31ef8f87be 100644
--- a/src/gui/text/qzip.cpp
+++ b/src/gui/text/qzip.cpp
@@ -243,11 +243,11 @@ static QFile::Permissions modeToPermissions(quint32 mode)
static quint32 permissionsToMode(QFile::Permissions perms)
{
quint32 mode = 0;
- if (mode & (QFile::ReadOwner | QFile::ReadUser))
+ if (perms & (QFile::ReadOwner | QFile::ReadUser))
mode |= UnixFileAttributes::ReadUser;
- if (mode & (QFile::WriteOwner | QFile::WriteUser))
+ if (perms & (QFile::WriteOwner | QFile::WriteUser))
mode |= UnixFileAttributes::WriteUser;
- if (mode & (QFile::ExeOwner | QFile::ExeUser))
+ if (perms & (QFile::ExeOwner | QFile::ExeUser))
mode |= UnixFileAttributes::WriteUser;
if (perms & QFile::ReadGroup)
mode |= UnixFileAttributes::ReadGroup;
@@ -303,6 +303,7 @@ enum HostOS {
HostOS400 = 18,
HostOSX = 19
};
+Q_DECLARE_TYPEINFO(HostOS, Q_PRIMITIVE_TYPE);
enum GeneralPurposeFlag {
Encrypted = 0x01,
@@ -314,6 +315,7 @@ enum GeneralPurposeFlag {
Utf8Names = 0x0800,
CentralDirectoryEncrypted = 0x2000
};
+Q_DECLARE_TYPEINFO(GeneralPurposeFlag, Q_PRIMITIVE_TYPE);
enum CompressionMethod {
CompressionMethodStored = 0,
@@ -340,6 +342,7 @@ enum CompressionMethod {
CompressionMethodPPMd = 98,
CompressionMethodWzAES = 99
};
+Q_DECLARE_TYPEINFO(CompressionMethod, Q_PRIMITIVE_TYPE);
struct LocalFileHeader
{
@@ -354,6 +357,7 @@ struct LocalFileHeader
uchar file_name_length[2];
uchar extra_field_length[2];
};
+Q_DECLARE_TYPEINFO(LocalFileHeader, Q_PRIMITIVE_TYPE);
struct DataDescriptor
{
@@ -361,6 +365,7 @@ struct DataDescriptor
uchar compressed_size[4];
uchar uncompressed_size[4];
};
+Q_DECLARE_TYPEINFO(DataDescriptor, Q_PRIMITIVE_TYPE);
struct CentralFileHeader
{
@@ -382,6 +387,7 @@ struct CentralFileHeader
uchar offset_local_header[4];
LocalFileHeader toLocalHeader() const;
};
+Q_DECLARE_TYPEINFO(CentralFileHeader, Q_PRIMITIVE_TYPE);
struct EndOfDirectory
{
@@ -394,6 +400,7 @@ struct EndOfDirectory
uchar dir_start_offset[4];
uchar comment_length[2];
};
+Q_DECLARE_TYPEINFO(EndOfDirectory, Q_PRIMITIVE_TYPE);
struct FileHeader
{
@@ -402,38 +409,7 @@ struct FileHeader
QByteArray extra_field;
QByteArray file_comment;
};
-
-QZipReader::FileInfo::FileInfo()
- : isDir(false), isFile(false), isSymLink(false), crc(0), size(0)
-{
-}
-
-QZipReader::FileInfo::~FileInfo()
-{
-}
-
-QZipReader::FileInfo::FileInfo(const FileInfo &other)
-{
- operator=(other);
-}
-
-QZipReader::FileInfo& QZipReader::FileInfo::operator=(const FileInfo &other)
-{
- filePath = other.filePath;
- isDir = other.isDir;
- isFile = other.isFile;
- isSymLink = other.isSymLink;
- permissions = other.permissions;
- crc = other.crc;
- size = other.size;
- lastModified = other.lastModified;
- return *this;
-}
-
-bool QZipReader::FileInfo::isValid() const
-{
- return isDir || isFile || isSymLink;
-}
+Q_DECLARE_TYPEINFO(FileHeader, Q_MOVABLE_TYPE);
class QZipPrivate
{
@@ -449,18 +425,19 @@ public:
delete device;
}
- void fillFileInfo(int index, QZipReader::FileInfo &fileInfo) const;
+ QZipReader::FileInfo fillFileInfo(int index) const;
QIODevice *device;
bool ownDevice;
bool dirtyFileTree;
- QList<FileHeader> fileHeaders;
+ QVector<FileHeader> fileHeaders;
QByteArray comment;
uint start_of_directory;
};
-void QZipPrivate::fillFileInfo(int index, QZipReader::FileInfo &fileInfo) const
+QZipReader::FileInfo QZipPrivate::fillFileInfo(int index) const
{
+ QZipReader::FileInfo fileInfo;
FileHeader header = fileHeaders.at(index);
quint32 mode = readUInt(header.h.external_file_attributes);
const HostOS hostOS = HostOS(readUShort(header.h.version_made) >> 8);
@@ -502,7 +479,7 @@ void QZipPrivate::fillFileInfo(int index, QZipReader::FileInfo &fileInfo) const
break;
default:
qWarning("QZip: Zip entry format at %d is not supported.", index);
- return; // we don't support anything else
+ return fileInfo; // we don't support anything else
}
ushort general_purpose_bits = readUShort(header.h.general_purpose_bits);
@@ -519,6 +496,8 @@ void QZipPrivate::fillFileInfo(int index, QZipReader::FileInfo &fileInfo) const
fileInfo.filePath = fileInfo.filePath.mid(1);
while (!fileInfo.filePath.isEmpty() && fileInfo.filePath.at(fileInfo.filePath.size() - 1) == QLatin1Char('/'))
fileInfo.filePath.chop(1);
+
+ return fileInfo;
}
class QZipReaderPrivate : public QZipPrivate
@@ -816,12 +795,6 @@ void QZipWriterPrivate::addEntry(EntryType type, const QString &fileName, const
*/
/*!
- \variable FileInfo::d
- \internal
- private pointer.
-*/
-
-/*!
\class QZipReader
\internal
\since 4.5
@@ -913,15 +886,14 @@ bool QZipReader::exists() const
/*!
Returns the list of files the archive contains.
*/
-QList<QZipReader::FileInfo> QZipReader::fileInfoList() const
+QVector<QZipReader::FileInfo> QZipReader::fileInfoList() const
{
d->scanFiles();
- QList<QZipReader::FileInfo> files;
- for (int i = 0; i < d->fileHeaders.size(); ++i) {
- QZipReader::FileInfo fi;
- d->fillFileInfo(i, fi);
- files.append(fi);
- }
+ QVector<FileInfo> files;
+ const int numFileHeaders = d->fileHeaders.size();
+ files.reserve(numFileHeaders);
+ for (int i = 0; i < numFileHeaders; ++i)
+ files.append(d->fillFileInfo(i));
return files;
}
@@ -945,10 +917,9 @@ int QZipReader::count() const
QZipReader::FileInfo QZipReader::entryInfoAt(int index) const
{
d->scanFiles();
- QZipReader::FileInfo fi;
if (index >= 0 && index < d->fileHeaders.count())
- d->fillFileInfo(index, fi);
- return fi;
+ return d->fillFileInfo(index);
+ return QZipReader::FileInfo();
}
/*!
@@ -1044,7 +1015,7 @@ bool QZipReader::extractAll(const QString &destinationDir) const
QDir baseDir(destinationDir);
// create directories first
- QList<FileInfo> allFiles = fileInfoList();
+ const QVector<FileInfo> allFiles = fileInfoList();
foreach (const FileInfo &fi, allFiles) {
const QString absPath = destinationDir + QDir::separator() + fi.filePath;
if (fi.isDir) {
diff --git a/src/gui/text/qzipreader_p.h b/src/gui/text/qzipreader_p.h
index df7e2d26e9..7f26bfb184 100644
--- a/src/gui/text/qzipreader_p.h
+++ b/src/gui/text/qzipreader_p.h
@@ -70,13 +70,14 @@ public:
bool isReadable() const;
bool exists() const;
- struct Q_GUI_EXPORT FileInfo
+ struct FileInfo
{
- FileInfo();
- FileInfo(const FileInfo &other);
- ~FileInfo();
- FileInfo &operator=(const FileInfo &other);
- bool isValid() const;
+ FileInfo() Q_DECL_NOTHROW
+ : isDir(false), isFile(false), isSymLink(false), crc(0), size(0)
+ {}
+
+ bool isValid() const Q_DECL_NOTHROW { return isDir || isFile || isSymLink; }
+
QString filePath;
uint isDir : 1;
uint isFile : 1;
@@ -85,10 +86,9 @@ public:
uint crc;
qint64 size;
QDateTime lastModified;
- void *d;
};
- QList<FileInfo> fileInfoList() const;
+ QVector<FileInfo> fileInfoList() const;
int count() const;
FileInfo entryInfoAt(int index) const;
@@ -111,6 +111,8 @@ private:
QZipReaderPrivate *d;
Q_DISABLE_COPY(QZipReader)
};
+Q_DECLARE_TYPEINFO(QZipReader::FileInfo, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(QZipReader::Status, Q_PRIMITIVE_TYPE);
QT_END_NAMESPACE
diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri
index 61e239f678..be60ba72cc 100644
--- a/src/gui/text/text.pri
+++ b/src/gui/text/text.pri
@@ -21,6 +21,7 @@ HEADERS += \
text/qtextdocument_p.h \
text/qtexthtmlparser_p.h \
text/qabstracttextdocumentlayout.h \
+ text/qabstracttextdocumentlayout_p.h \
text/qtextdocumentlayout_p.h \
text/qtextcursor.h \
text/qtextcursor_p.h \
@@ -47,6 +48,7 @@ HEADERS += \
SOURCES += \
text/qfont.cpp \
text/qfontengine.cpp \
+ text/qfontengineglyphcache.cpp \
text/qfontsubset.cpp \
text/qfontmetrics.cpp \
text/qfontdatabase.cpp \
diff --git a/src/gui/util/qdesktopservices.cpp b/src/gui/util/qdesktopservices.cpp
index 4c92e5d000..70daf55b61 100644
--- a/src/gui/util/qdesktopservices.cpp
+++ b/src/gui/util/qdesktopservices.cpp
@@ -197,7 +197,7 @@ bool QDesktopServices::openUrl(const QUrl &url)
QPlatformServices *platformServices = platformIntegration->services();
if (!platformServices) {
- qWarning("%s: The platform plugin does not support services.", Q_FUNC_INFO);
+ qWarning("The platform plugin does not support services.");
return false;
}
return url.scheme() == QLatin1String("file") ?
@@ -231,13 +231,13 @@ void QDesktopServices::setUrlHandler(const QString &scheme, QObject *receiver, c
QOpenUrlHandlerRegistry *registry = handlerRegistry();
QMutexLocker locker(&registry->mutex);
if (!receiver) {
- registry->handlers.remove(scheme);
+ registry->handlers.remove(scheme.toLower());
return;
}
QOpenUrlHandlerRegistry::Handler h;
h.receiver = receiver;
h.name = method;
- registry->handlers.insert(scheme, h);
+ registry->handlers.insert(scheme.toLower(), h);
QObject::connect(receiver, SIGNAL(destroyed(QObject*)),
registry, SLOT(handlerDestroyed(QObject*)));
}
diff --git a/src/gui/util/qvalidator.h b/src/gui/util/qvalidator.h
index 0435e4e9ff..a979a268aa 100644
--- a/src/gui/util/qvalidator.h
+++ b/src/gui/util/qvalidator.h
@@ -52,7 +52,7 @@ class Q_GUI_EXPORT QValidator : public QObject
{
Q_OBJECT
public:
- explicit QValidator(QObject * parent = 0);
+ explicit QValidator(QObject * parent = Q_NULLPTR);
~QValidator();
enum State {
@@ -86,8 +86,8 @@ class Q_GUI_EXPORT QIntValidator : public QValidator
Q_PROPERTY(int top READ top WRITE setTop NOTIFY topChanged)
public:
- explicit QIntValidator(QObject * parent = 0);
- QIntValidator(int bottom, int top, QObject *parent = 0);
+ explicit QIntValidator(QObject * parent = Q_NULLPTR);
+ QIntValidator(int bottom, int top, QObject *parent = Q_NULLPTR);
~QIntValidator();
QValidator::State validate(QString &, int &) const Q_DECL_OVERRIDE;
@@ -123,8 +123,8 @@ class Q_GUI_EXPORT QDoubleValidator : public QValidator
Q_PROPERTY(Notation notation READ notation WRITE setNotation NOTIFY notationChanged)
public:
- explicit QDoubleValidator(QObject * parent = 0);
- QDoubleValidator(double bottom, double top, int decimals, QObject *parent = 0);
+ explicit QDoubleValidator(QObject * parent = Q_NULLPTR);
+ QDoubleValidator(double bottom, double top, int decimals, QObject *parent = Q_NULLPTR);
~QDoubleValidator();
enum Notation {
@@ -167,8 +167,8 @@ class Q_GUI_EXPORT QRegExpValidator : public QValidator
Q_PROPERTY(QRegExp regExp READ regExp WRITE setRegExp NOTIFY regExpChanged)
public:
- explicit QRegExpValidator(QObject *parent = 0);
- explicit QRegExpValidator(const QRegExp& rx, QObject *parent = 0);
+ explicit QRegExpValidator(QObject *parent = Q_NULLPTR);
+ explicit QRegExpValidator(const QRegExp& rx, QObject *parent = Q_NULLPTR);
~QRegExpValidator();
virtual QValidator::State validate(QString& input, int& pos) const Q_DECL_OVERRIDE;
@@ -197,8 +197,8 @@ class Q_GUI_EXPORT QRegularExpressionValidator : public QValidator
Q_PROPERTY(QRegularExpression regularExpression READ regularExpression WRITE setRegularExpression NOTIFY regularExpressionChanged)
public:
- explicit QRegularExpressionValidator(QObject *parent = 0);
- explicit QRegularExpressionValidator(const QRegularExpression &re, QObject *parent = 0);
+ explicit QRegularExpressionValidator(QObject *parent = Q_NULLPTR);
+ explicit QRegularExpressionValidator(const QRegularExpression &re, QObject *parent = Q_NULLPTR);
~QRegularExpressionValidator();
virtual QValidator::State validate(QString &input, int &pos) const Q_DECL_OVERRIDE;