summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/accessible/qaccessible.cpp130
-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/image/qbitmap.h2
-rw-r--r--src/gui/image/qicon.cpp41
-rw-r--r--src/gui/image/qicon.h9
-rw-r--r--src/gui/image/qicon_p.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.cpp121
-rw-r--r--src/gui/image/qimage.h37
-rw-r--r--src/gui/image/qimageiohandler.h2
-rw-r--r--src/gui/image/qimagereader.cpp44
-rw-r--r--src/gui/image/qimagereader.h3
-rw-r--r--src/gui/image/qimagewriter.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.h16
-rw-r--r--src/gui/image/qpixmap_blitter.cpp2
-rw-r--r--src/gui/image/qpixmap_raster.cpp3
-rw-r--r--src/gui/image/qpixmapcache.cpp38
-rw-r--r--src/gui/image/qpixmapcache.h12
-rw-r--r--src/gui/image/qpnghandler.cpp22
-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.cpp37
-rw-r--r--src/gui/kernel/qevent.h13
-rw-r--r--src/gui/kernel/qgenericplugin.h2
-rw-r--r--src/gui/kernel/qguiapplication.cpp42
-rw-r--r--src/gui/kernel/qhighdpiscaling.cpp322
-rw-r--r--src/gui/kernel/qhighdpiscaling_p.h514
-rw-r--r--src/gui/kernel/qinputmethod.h2
-rw-r--r--src/gui/kernel/qkeymapper_p.h1
-rw-r--r--src/gui/kernel/qkeysequence.cpp80
-rw-r--r--src/gui/kernel/qkeysequence.h12
-rw-r--r--src/gui/kernel/qkeysequence_p.h13
-rw-r--r--src/gui/kernel/qoffscreensurface.h2
-rw-r--r--src/gui/kernel/qopenglcontext.cpp32
-rw-r--r--src/gui/kernel/qopenglcontext.h7
-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/qplatformcursor.cpp2
-rw-r--r--src/gui/kernel/qplatformcursor.h2
-rw-r--r--src/gui/kernel/qplatformdialoghelper.cpp14
-rw-r--r--src/gui/kernel/qplatformdialoghelper.h3
-rw-r--r--src/gui/kernel/qplatforminputcontextfactory.cpp44
-rw-r--r--src/gui/kernel/qplatforminputcontextfactory_p.h1
-rw-r--r--src/gui/kernel/qplatformintegration.cpp8
-rw-r--r--src/gui/kernel/qplatformintegrationfactory.cpp7
-rw-r--r--src/gui/kernel/qplatformscreen.cpp75
-rw-r--r--src/gui/kernel/qplatformscreen.h17
-rw-r--r--src/gui/kernel/qplatformthemefactory.cpp4
-rw-r--r--src/gui/kernel/qplatformwindow.cpp95
-rw-r--r--src/gui/kernel/qplatformwindow.h12
-rw-r--r--src/gui/kernel/qrasterwindow.cpp2
-rw-r--r--src/gui/kernel/qrasterwindow.h2
-rw-r--r--src/gui/kernel/qscreen.cpp79
-rw-r--r--src/gui/kernel/qscreen.h8
-rw-r--r--src/gui/kernel/qscreen_p.h25
-rw-r--r--src/gui/kernel/qsimpledrag.cpp47
-rw-r--r--src/gui/kernel/qsimpledrag_p.h10
-rw-r--r--src/gui/kernel/qtouchdevice.cpp14
-rw-r--r--src/gui/kernel/qtouchdevice_p.h5
-rw-r--r--src/gui/kernel/qwindow.cpp94
-rw-r--r--src/gui/kernel/qwindow.h13
-rw-r--r--src/gui/kernel/qwindow_p.h1
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp205
-rw-r--r--src/gui/kernel/qwindowsysteminterface.h6
-rw-r--r--src/gui/kernel/qwindowsysteminterface_p.h27
-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.cpp120
-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.cpp495
-rw-r--r--src/gui/opengl/qopenglframebufferobject.h22
-rw-r--r--src/gui/opengl/qopenglframebufferobject_p.h27
-rw-r--r--src/gui/opengl/qopenglfunctions.cpp4283
-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/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.cpp289
-rw-r--r--src/gui/opengl/qopengltexture.h33
-rw-r--r--src/gui/opengl/qopengltexture_p.h2
-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.pri3
-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.cpp92
-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/qdrawhelper.cpp3575
-rw-r--r--src/gui/painting/qdrawhelper_neon.cpp7
-rw-r--r--src/gui/painting/qdrawhelper_neon_p.h2
-rw-r--r--src/gui/painting/qdrawhelper_p.h243
-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.qdoc21
-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.cpp104
-rw-r--r--src/gui/painting/qpainter.cpp15
-rw-r--r--src/gui/painting/qpainter.h10
-rw-r--r--src/gui/painting/qpainter_p.h3
-rw-r--r--src/gui/painting/qpathclipper.cpp6
-rw-r--r--src/gui/painting/qpdf.cpp39
-rw-r--r--src/gui/painting/qpdf_p.h4
-rw-r--r--src/gui/painting/qpen.cpp1
-rw-r--r--src/gui/painting/qplatformbackingstore.cpp6
-rw-r--r--src/gui/painting/qpolygon.h22
-rw-r--r--src/gui/painting/qrgba64.h228
-rw-r--r--src/gui/painting/qrgba64.qdoc241
-rw-r--r--src/gui/painting/qrgba64_p.h120
-rw-r--r--src/gui/painting/qtextureglyphcache.cpp29
-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.cpp7
-rw-r--r--src/gui/text/qfontdatabase.cpp24
-rw-r--r--src/gui/text/qfontengine_ft.cpp31
-rw-r--r--src/gui/text/qfontengine_ft_p.h3
-rw-r--r--src/gui/text/qfontengine_p.h13
-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/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.h5
-rw-r--r--src/gui/text/qtextdocument.cpp22
-rw-r--r--src/gui/text/qtextdocument.h18
-rw-r--r--src/gui/text/qtextdocumentlayout.cpp18
-rw-r--r--src/gui/text/qtextengine.cpp30
-rw-r--r--src/gui/text/qtextengine_p.h12
-rw-r--r--src/gui/text/qtextformat.cpp8
-rw-r--r--src/gui/text/qtextformat_p.h1
-rw-r--r--src/gui/text/qtextimagehandler.cpp4
-rw-r--r--src/gui/text/qtextlayout.cpp69
-rw-r--r--src/gui/text/qtextlayout.h24
-rw-r--r--src/gui/text/qtextobject.h6
-rw-r--r--src/gui/text/qtextodfwriter.cpp2
-rw-r--r--src/gui/text/qtextodfwriter_p.h2
-rw-r--r--src/gui/text/qtextoption.cpp6
-rw-r--r--src/gui/text/qtexttable.h4
-rw-r--r--src/gui/text/qzip.cpp71
-rw-r--r--src/gui/text/qzipreader_p.h18
-rw-r--r--src/gui/text/text.pri2
-rw-r--r--src/gui/util/qvalidator.h18
204 files changed, 14885 insertions, 3787 deletions
diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp
index e0ebcd18ce..e9995045b1 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
@@ -1254,10 +1259,6 @@ QColor QAccessibleInterface::backgroundColor() const
return QColor();
}
-QAccessibleInterface::~QAccessibleInterface()
-{
-}
-
/*!
\fn QAccessibleTextInterface *QAccessibleInterface::textInterface()
*/
@@ -1329,9 +1330,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 +1405,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 +1449,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 +1530,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 +1558,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 +1599,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 +1643,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 +1704,14 @@ QAccessible::Id QAccessibleEvent::uniqueId() const
Returns the removed text.
*/
+/*!
+ \internal
+*/
+QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent()
+{
+ // must be empty until ### Qt 6
+}
+
/*!
\class QAccessibleTextSelectionEvent
@@ -1682,6 +1739,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 +1984,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 +2373,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 +2418,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 +2483,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 +2502,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 +2570,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 +2746,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/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..7a59adffb8 100644
--- a/src/gui/image/qicon.cpp
+++ b/src/gui/image/qicon.cpp
@@ -46,11 +46,6 @@
#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 "private/qhexstring_p.h"
#include "private/qguiapplication_p.h"
#include "qpa/qplatformtheme.h"
@@ -134,7 +129,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 +358,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 +422,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 +595,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}
*/
@@ -1185,8 +1183,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 +1204,31 @@ 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)
+{
+ 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
+{
+ return d->is_mask;
+}
/*****************************************************************************
QIcon stream functions
diff --git a/src/gui/image/qicon.h b/src/gui/image/qicon.h
index 63e77eef99..ccddf69101 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);
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/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 176cdfe09f..045e36323f 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -476,6 +476,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
@@ -1770,11 +1774,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()));
@@ -2191,9 +2195,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}
*/
@@ -2243,25 +2248,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}
*/
@@ -2349,6 +2352,102 @@ 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();
+ }
+
+ const uchar * s = constScanLine(y);
+ switch (d->format) {
+ case Format_BGR30:
+ case Format_A2BGR30_Premultiplied:
+ return QColor(qConvertA2rgb30ToRgb64<PixelOrderBGR>(reinterpret_cast<const quint32 *>(s)[x]));
+ case Format_RGB30:
+ case Format_A2RGB30_Premultiplied:
+ return QColor(qConvertA2rgb30ToRgb64<PixelOrderRGB>(reinterpret_cast<const quint32 *>(s)[x]));
+ default:
+ return QColor(pixel(x, y));
+ }
+}
+
+/*!
+ \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;
+ }
+ // 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>(color.rgba64()) | 0xc0000000;
+ return;
+ case Format_A2BGR30_Premultiplied:
+ ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderBGR>(color.rgba64());
+ return;
+ case Format_RGB30:
+ ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderRGB>(color.rgba64()) | 0xc0000000;
+ return;
+ case Format_A2RGB30_Premultiplied:
+ ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderRGB>(color.rgba64());
+ return;
+ default:
+ setPixel(x, y, color.rgba());
+ 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.
@@ -3793,6 +3892,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;
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/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 ba79bf40e5..618352d363 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,9 +1168,10 @@ 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(), transform(), read()
+ \sa autoTransform(), read()
*/
void QImageReader::setAutoTransform(bool enabled)
{
@@ -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/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.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..a2b84b358e 100644
--- a/src/gui/image/qpixmap_raster.cpp
+++ b/src/gui/image/qpixmap_raster.cpp
@@ -288,6 +288,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;
diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp
index 3836976975..71a79745e8 100644
--- a/src/gui/image/qpixmapcache.cpp
+++ b/src/gui/image/qpixmapcache.cpp
@@ -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()
@@ -656,10 +659,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 +666,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..776a61d8fe 100644
--- a/src/gui/image/qpnghandler.cpp
+++ b/src/gui/image/qpnghandler.cpp
@@ -108,10 +108,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 +235,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 +555,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 +584,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 +1067,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/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 6ed750eda1..dbf2b3c21f 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..780a102644 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()
@@ -1987,6 +2019,11 @@ QInputMethodEvent::QInputMethodEvent(const QInputMethodEvent &other)
{
}
+QInputMethodEvent::~QInputMethodEvent()
+{
+ // must be empty until ### Qt 6
+}
+
/*!
Sets the commit string to \a commitString.
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 7dc8444163..d0aab734dd 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -958,8 +958,10 @@ QWindow *QGuiApplication::topLevelAt(const QPoint &pos)
QList<QScreen *>::const_iterator end = screens.constEnd();
while (screen != end) {
- if ((*screen)->geometry().contains(pos))
- return (*screen)->handle()->topLevelAt(pos);
+ if ((*screen)->geometry().contains(pos)) {
+ const QPoint devicePosition = QHighDpi::toNativePixels(pos, *screen);
+ return (*screen)->handle()->topLevelAt(devicePosition);
+ }
++screen;
}
return 0;
@@ -1115,6 +1117,9 @@ void QGuiApplicationPrivate::createPlatformIntegration()
// this flag.
QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, true);
+
+ QHighDpiScaling::initHighDpiScaling();
+
// Load the platform integration
QString platformPluginPath = QLatin1String(qgetenv("QT_QPA_PLATFORM_PLUGIN_PATH"));
@@ -1204,6 +1209,10 @@ void QGuiApplicationPrivate::eventDispatcherReady()
createPlatformIntegration();
platform_integration->initialize();
+
+ // Do this here in order to play nice with platforms that add screens only
+ // in initialize().
+ QHighDpiScaling::updateHighDpiScaling();
}
void QGuiApplicationPrivate::init()
@@ -1328,6 +1337,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()) {
@@ -1342,6 +1354,8 @@ void QGuiApplicationPrivate::init()
qCritical() << "Library qttestability load failed:" << testLib.errorString();
}
}
+#else
+ Q_UNUSED(loadTestability);
#endif // QT_NO_LIBRARY
}
@@ -1691,12 +1705,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(
+ QWindowSystemInterfacePrivate::MouseEvent mouseButtonEvent(
e->window.data(), e->timestamp, e->type, e->localPos, e->globalPos, e->buttons, e->modifiers);
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();
@@ -1765,9 +1781,8 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
if (!window)
return;
- QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, buttons, e->modifiers);
+ QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, buttons, e->modifiers, e->source);
ev.setTimestamp(e->timestamp);
- setMouseEventSource(&ev, e->source);
#ifndef QT_NO_CURSOR
if (!e->synthetic()) {
if (const QScreen *screen = window->screen())
@@ -1815,7 +1830,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;
@@ -1826,9 +1841,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);
}
}
@@ -1920,6 +1934,7 @@ void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyE
}
}
#endif
+ e->eventAccepted = ev.isAccepted();
}
void QGuiApplicationPrivate::processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent *e)
@@ -2032,6 +2047,11 @@ void QGuiApplicationPrivate::processWindowScreenChangedEvent(QWindowSystemInterf
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);
+ }
}
}
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
new file mode 100644
index 0000000000..de586ac46c
--- /dev/null
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -0,0 +1,322 @@
+/****************************************************************************
+**
+** 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 initialScaleFactor()
+{
+
+ 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:";
+ qWarning() << " " << autoScreenEnvVar << "to enable platform plugin controlled per-screen factors.";
+ qWarning() << " " << screenFactorsEnvVar << "to set per-screen factors.";
+ qWarning() << " " << 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.
+
+ The coordinate system scaling is enabled by setting one or more scale
+ factors. These will then be factored into the value returned by the
+ devicePixelRatio() accessors (any native scale factor will also be
+ included in this value). Several setters are available:
+
+ - A process-global scale factor
+ - QT_SCALE_FACTOR (environment variable)
+ - QHighDpiScaling::setGlobalFactor()
+
+ - A per-screen scale factor
+ - QT_AUTO_SCALE_FACTOR (environment variable)
+ Setting this to a true-ish value will make QHighDpiScaling
+ call QPlatformScreen::pixelDensity()
+ - QHighDpiScaling::setScreenFactor(screen, factor);
+ - QT_SCREEN_SCALE_FACTORS (environment variable)
+ 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()).
+
+ All scale factors are of type qreal.
+
+ The main scaling functions for use in QtGui are:
+ T toNativePixels(T, QWindow *)
+ T fromNativePixels(T, QWindow*)
+ Where T is QPoint, QSize, QRect etc.
+*/
+
+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.
+*/
+void QHighDpiScaling::initHighDpiScaling()
+{
+ if (QCoreApplication::testAttribute(Qt::AA_NoHighDpiScaling)) {
+ m_factor = 1;
+ m_active = false;
+ return;
+ }
+ m_factor = initialScaleFactor();
+ bool usePlatformPluginPixelDensity = qEnvironmentVariableIsSet(autoScreenEnvVar)
+ || qgetenv(legacyDevicePixelEnvVar).toLower() == "auto";
+
+ m_globalScalingActive = !qFuzzyCompare(m_factor, qreal(1));
+ m_usePixelDensity = usePlatformPluginPixelDensity;
+ 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_NoHighDpiScaling))
+ 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() << Q_FUNC_INFO << "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.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..ffa9b87147 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
@@ -818,6 +819,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 +878,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 +982,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 +1017,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 +1036,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 +1072,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 +1096,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 +1362,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 +1405,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 +1430,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 +1527,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 +1570,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 +1592,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..d6171c86f2 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
@@ -177,10 +180,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 +207,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..9e5767658f 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;
@@ -719,6 +719,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()
diff --git a/src/gui/kernel/qopenglcontext.h b/src/gui/kernel/qopenglcontext.h
index a529957ad6..85e7abfa26 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;
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/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..25894fd504 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>
@@ -423,6 +422,7 @@ public:
QUrl initialDirectory;
QString initiallySelectedNameFilter;
QList<QUrl> initiallySelectedFiles;
+ QStringList supportedSchemes;
};
QFileDialogOptions::QFileDialogOptions() : d(new QFileDialogOptionsPrivate)
@@ -614,6 +614,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();
diff --git a/src/gui/kernel/qplatformdialoghelper.h b/src/gui/kernel/qplatformdialoghelper.h
index 8b2b9881b7..ec88770862 100644
--- a/src/gui/kernel/qplatformdialoghelper.h
+++ b/src/gui/kernel/qplatformdialoghelper.h
@@ -348,6 +348,9 @@ public:
QList<QUrl> initiallySelectedFiles() const;
void setInitiallySelectedFiles(const QList<QUrl> &);
+ void setSupportedSchemes(const QStringList &schemes);
+ QStringList supportedSchemes() const;
+
private:
QSharedDataPointer<QFileDialogOptionsPrivate> d;
};
diff --git a/src/gui/kernel/qplatforminputcontextfactory.cpp b/src/gui/kernel/qplatforminputcontextfactory.cpp
index a7660e76ae..9d55b778ce 100644
--- a/src/gui/kernel/qplatforminputcontextfactory.cpp
+++ b/src/gui/kernel/qplatforminputcontextfactory.cpp
@@ -56,48 +56,32 @@ 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;
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+ QStringList paramList = key.split(QLatin1Char(':'));
+ const QString platform = paramList.takeFirst().toLower();
- ic = create(icString);
+ QPlatformInputContext *ic = qLoadPlugin1<QPlatformInputContext, QPlatformInputContextPlugin>
+ (loader(), platform, paramList);
if (ic && ic->isValid())
return ic;
delete ic;
- ic = 0;
-
- QStringList k = keys();
- for (int i = 0; i < k.size(); ++i) {
- if (k.at(i) == icString)
- continue;
- ic = create(k.at(i));
- 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..e935907a62 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>
@@ -450,7 +449,7 @@ 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 {
@@ -469,8 +468,9 @@ 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();
+ QGuiApplicationPrivate::screen_list.removeOne(qScreen);
+ delete qScreen;
delete screen;
}
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/qplatformscreen.cpp b/src/gui/kernel/qplatformscreen.cpp
index edf546799f..2fb53fe16b 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
@@ -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) {
@@ -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/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..0430d5a4c6 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,25 @@ 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;
+ QPoint center = 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 +579,7 @@ void QPlatformWindow::invalidateSurface()
QRect QPlatformWindow::initialGeometry(const QWindow *w,
const QRect &initialGeometry, int defaultWidth, int defaultHeight)
{
- QRect rect(initialGeometry);
+ QRect rect(QHighDpi::fromNativePixels(initialGeometry, w));
if (rect.width() == 0) {
const int minWidth = w->minimumWidth();
rect.setWidth(minWidth > 0 ? minWidth : defaultWidth);
@@ -593,7 +607,7 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w,
}
}
}
- return rect;
+ return QHighDpi::toNativePixels(rect, w);
}
/*!
@@ -627,6 +641,77 @@ 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::windowClosestAcceptableGeometry(const QRectF &nativeRect) const
+{
+ QWindow *qWindow = window();
+ const QRectF rectF = QHighDpi::fromNativePixels(nativeRect, qWindow);
+ const QRectF correctedGeometryF = qt_window_private(qWindow)->closestAcceptableGeometry(rectF);
+ return !correctedGeometryF.isEmpty() && rectF != correctedGeometryF
+ ? QHighDpi::toNativePixels(correctedGeometryF, qWindow) : nativeRect;
+}
+
+/*!
\class QPlatformWindow
\since 4.8
\internal
diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h
index c7c1efdc58..1b283dbb4f 100644
--- a/src/gui/kernel/qplatformwindow.h
+++ b/src/gui/kernel/qplatformwindow.h
@@ -130,9 +130,21 @@ 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;
+
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..b6b50372ae 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();
}
@@ -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()
*/
@@ -654,4 +686,41 @@ QPixmap QScreen::grabWindow(WId window, int x, int y, int width, int height)
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/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp
index b850f53014..6e574d82e4 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
@@ -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,19 +146,21 @@ bool QBasicDrag::eventFilter(QObject *o, QEvent *e)
}
case QEvent::MouseMove:
- move(static_cast<QMouseEvent *>(e));
+ {
+ QPoint nativePosition = getNativeMousePos(e, o);
+ move(nativePosition);
return true; // Eat all mouse 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:
case QEvent::MouseButtonDblClick:
case QEvent::Wheel:
@@ -227,13 +236,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 +344,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 +360,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..a011475381 100644
--- a/src/gui/kernel/qsimpledrag_p.h
+++ b/src/gui/kernel/qsimpledrag_p.h
@@ -73,10 +73,12 @@ 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 updateCursor(Qt::DropAction action);
@@ -111,8 +113,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/qtouchdevice.cpp b/src/gui/kernel/qtouchdevice.cpp
index 1a6e9deba8..9d19fa4b92 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())
diff --git a/src/gui/kernel/qtouchdevice_p.h b/src/gui/kernel/qtouchdevice_p.h
index 9c0bcf3414..4aff8f2f33 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,8 @@ public:
QString name;
int maxTouchPoints;
- static void registerDevice(QTouchDevice *dev);
- static bool isRegistered(QTouchDevice *dev);
+ static void registerDevice(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 b54e85a1d3..89bd119564 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>
@@ -1085,13 +1086,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);
}
/*!
@@ -1431,7 +1432,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;
@@ -1446,6 +1453,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.
@@ -1455,7 +1486,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;
}
@@ -1468,7 +1499,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();
}
@@ -1482,7 +1513,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;
}
@@ -1499,7 +1530,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();
}
@@ -1515,7 +1546,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);
}
@@ -1575,7 +1606,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);
@@ -2471,6 +2502,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..23a6d800c0 100644
--- a/src/gui/kernel/qwindow_p.h
+++ b/src/gui/kernel/qwindow_p.h
@@ -136,6 +136,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;
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 9a9eab2fe7..88cf2dac93 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -40,14 +40,16 @@
#include <qpa/qplatformdrag.h>
#include <qpa/qplatformintegration.h>
#include <qdebug.h>
+#include "qhighdpiscaling_p.h"
QT_BEGIN_NAMESPACE
QElapsedTimer QWindowSystemInterfacePrivate::eventTime;
-bool QWindowSystemInterfacePrivate::synchronousWindowsSystemEvents = false;
+bool QWindowSystemInterfacePrivate::synchronousWindowSystemEvents = false;
QWaitCondition QWindowSystemInterfacePrivate::eventsFlushed;
QMutex QWindowSystemInterfacePrivate::flushEventMutex;
+QWindowSystemEventHandler *QWindowSystemInterfacePrivate::eventHandler;
//------------------------------------------------------------
//
@@ -93,14 +95,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 +140,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 +169,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,7 +186,7 @@ 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);
}
@@ -301,24 +303,24 @@ bool QWindowSystemInterface::tryHandleExtendedShortcutEvent(QWindow *w, ulong ti
}
-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;
+ return true;
#endif // Q_OS_OSX
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,
@@ -381,14 +383,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;
}
@@ -396,12 +398,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);
}
@@ -439,16 +441,20 @@ void QWindowSystemInterfacePrivate::removeWindowSystemEvent(WindowSystemEvent *e
windowSystemEventQueue.remove(event);
}
-void QWindowSystemInterfacePrivate::handleWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *ev)
+bool QWindowSystemInterfacePrivate::handleWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *ev)
{
- if (synchronousWindowsSystemEvents) {
+ bool accepted = true;
+ if (synchronousWindowSystemEvents) {
QGuiApplicationPrivate::processWindowSystemEvent(ev);
+ accepted = ev->eventAccepted;
+ delete ev;
} else {
windowSystemEventQueue.append(ev);
QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::qt_qpa_core_dispatcher();
if (dispatcher)
dispatcher->wakeUp();
}
+ return accepted;
}
void QWindowSystemInterface::registerTouchDevice(QTouchDevice *device)
@@ -463,12 +469,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) {
@@ -478,16 +488,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;
@@ -505,6 +515,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)
{
@@ -515,7 +546,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);
@@ -548,14 +579,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);
}
@@ -574,7 +605,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);
}
@@ -583,7 +614,7 @@ void QWindowSystemInterface::deferredFlushWindowSystemEvents(QEventLoop::Process
Q_ASSERT(QThread::currentThread() == QGuiApplication::instance()->thread());
QMutexLocker locker(&QWindowSystemInterfacePrivate::flushEventMutex);
- flushWindowSystemEvents(flags);
+ sendWindowSystemEvents(flags);
QWindowSystemInterfacePrivate::eventsFlushed.wakeOne();
}
@@ -620,17 +651,35 @@ 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);
+ }
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()
@@ -641,12 +690,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
@@ -680,8 +729,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);
}
@@ -806,13 +858,26 @@ 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);
+Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *w, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods, int timestamp)
+{
+ QWindowSystemInterfacePrivate::MouseEvent e(w, timestamp, local, global, b, mods, Qt::MouseEventNotSynthesized);
+ QGuiApplicationPrivate::processWindowSystemEvent(&e);
}
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)
{
- QWindowSystemInterface::handleKeyEvent(w, t, k, mods, text, autorep, count);
+ unsigned long timestamp = QWindowSystemInterfacePrivate::eventTime.elapsed();
+
+ // 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(w, timestamp, k, mods, text))
+ return;
+#endif // Q_OS_OSX
+
+ QWindowSystemInterfacePrivate::KeyEvent e(w, timestamp, t, k, mods, text, autorep, count);
+ QGuiApplicationPrivate::processWindowSystemEvent(&e);
}
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)
@@ -820,35 +885,49 @@ Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int
return QWindowSystemInterface::tryHandleShortcutEventToObject(o, timestamp, k, mods, text, autorep, count);
}
-static QWindowSystemInterface::TouchPoint touchPoint(const QTouchEvent::TouchPoint& pt)
-{
- QWindowSystemInterface::TouchPoint p;
- p.id = pt.id();
- p.flags = pt.flags();
- p.normalPosition = pt.normalizedPos();
- p.area = pt.screenRect();
- p.pressure = pt.pressure();
- p.state = pt.state();
- p.velocity = pt.velocity();
- p.rawPositions = pt.rawScreenPositions();
- return p;
-}
-static QList<struct QWindowSystemInterface::TouchPoint> touchPointList(const QList<QTouchEvent::TouchPoint>& pointList)
+Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *w, QTouchDevice *device,
+ const QList<QTouchEvent::TouchPoint> &points,
+ Qt::KeyboardModifiers mods = Qt::NoModifier)
{
- QList<struct QWindowSystemInterface::TouchPoint> newList;
+ unsigned long timestamp = QWindowSystemInterfacePrivate::eventTime.elapsed();
+
+ if (!points.size()) // Touch events must have at least one point
+ return;
+
+ if (!QTouchDevicePrivate::isRegistered(device)) // Disallow passing bogus, non-registered devices.
+ return;
+
+ QEvent::Type type;
+ Qt::TouchPointStates states;
- Q_FOREACH (QTouchEvent::TouchPoint p, pointList)
- {
- newList.append(touchPoint(p));
+ QList<QTouchEvent::TouchPoint>::const_iterator point = points.constBegin();
+ QList<QTouchEvent::TouchPoint>::const_iterator end = points.constEnd();
+ while (point != end) {
+ states |= point->state();
+ ++point;
}
- return newList;
+
+ // Determine the event type based on the combined point states.
+ type = QEvent::TouchUpdate;
+ if (states == Qt::TouchPointPressed)
+ type = QEvent::TouchBegin;
+ else if (states == Qt::TouchPointReleased)
+ type = QEvent::TouchEnd;
+
+ QWindowSystemInterfacePrivate::TouchEvent e(w, timestamp, type, device, points, mods);
+ QGuiApplicationPrivate::processWindowSystemEvent(&e);
}
-Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *w, QTouchDevice *device,
- const QList<QTouchEvent::TouchPoint> &points,
- Qt::KeyboardModifiers mods = Qt::NoModifier)
+QWindowSystemEventHandler::~QWindowSystemEventHandler()
+{
+ QWindowSystemInterfacePrivate::removeWindowSystemEventhandler(this);
+}
+
+bool QWindowSystemEventHandler::sendEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e)
{
- QWindowSystemInterface::handleTouchEvent(w, device, touchPointList(points), mods);
+ QGuiApplicationPrivate::processWindowSystemEvent(e);
+ return true;
}
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
index 448c5d0893..ace1a4fe24 100644
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ b/src/gui/kernel/qwindowsysteminterface.h
@@ -95,8 +95,8 @@ public:
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 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 void handleExtendedKeyEvent(QWindow *w, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
quint32 nativeScanCode, quint32 nativeVirtualKey,
@@ -212,7 +212,7 @@ public:
// For event dispatcher implementations
static bool sendWindowSystemEvents(QEventLoop::ProcessEventsFlags flags);
- static void setSynchronousWindowsSystemEvents(bool enable);
+ static void setSynchronousWindowSystemEvents(bool enable);
static void 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..cc0ca6bf81 100644
--- a/src/gui/kernel/qwindowsysteminterface_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_p.h
@@ -54,6 +54,8 @@
QT_BEGIN_NAMESPACE
+class QWindowSystemEventHandler;
+
class Q_GUI_EXPORT QWindowSystemInterfacePrivate {
public:
enum EventType {
@@ -99,7 +101,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 +109,7 @@ public:
EventType type;
int flags;
+ bool eventAccepted;
};
class CloseEvent : public WindowSystemEvent {
@@ -478,15 +481,31 @@ public:
static WindowSystemEvent *getNonUserInputWindowSystemEvent();
static WindowSystemEvent *peekWindowSystemEvent(EventType t);
static void removeWindowSystemEvent(WindowSystemEvent *event);
- static void handleWindowSystemEvent(WindowSystemEvent *ev);
+ static bool handleWindowSystemEvent(WindowSystemEvent *ev);
static QElapsedTimer eventTime;
- static bool synchronousWindowsSystemEvents;
+ static bool synchronousWindowSystemEvents;
static QWaitCondition eventsFlushed;
static QMutex flushEventMutex;
- static QList<QTouchEvent::TouchPoint> convertTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points, QEvent::Type *type);
+ 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;
+};
+
+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..68cd8a82b4 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);
@@ -206,9 +228,38 @@ 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";
@@ -216,11 +267,17 @@ struct OsTypeTerm
}
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 8d298496df..3596591cf6 100644
--- a/src/gui/opengl/qopenglframebufferobject.cpp
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -166,7 +166,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()
@@ -436,10 +436,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();
@@ -458,9 +458,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
@@ -471,64 +475,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;
@@ -541,37 +511,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
@@ -608,10 +617,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,
@@ -636,25 +645,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,
@@ -678,9 +687,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);
@@ -756,6 +765,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().
@@ -785,6 +799,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)
@@ -814,13 +838,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
@@ -834,13 +852,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
@@ -877,7 +889,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.
@@ -885,17 +897,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
@@ -904,7 +910,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.
@@ -912,17 +918,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));
}
/*!
@@ -936,10 +936,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)
@@ -949,6 +951,70 @@ QOpenGLFramebufferObject::~QOpenGLFramebufferObject()
}
/*!
+ Creates and attaches an additional texture or renderbuffer of size \a width
+ and \a 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.
@@ -1002,10 +1068,16 @@ 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);
+ }
+ }
+
+ d->valid = d->checkFramebufferStatus(current);
+
return d->valid;
}
@@ -1052,12 +1124,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 takeTextures(), 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;
}
/*!
@@ -1076,34 +1172,72 @@ GLuint QOpenGLFramebufferObject::texture() const
\since 5.3
- \sa texture(), bind(), release()
+ \sa texture(), bind(), release(), takeTextures()
*/
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;
}
/*!
@@ -1232,6 +1366,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();
@@ -1242,6 +1407,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);
@@ -1249,16 +1419,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())
@@ -1268,19 +1455,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
@@ -1366,7 +1540,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);
}
/*!
@@ -1428,6 +1602,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.
@@ -1456,12 +1642,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)
@@ -1489,10 +1681,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..d614ad8401 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.
@@ -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/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 5271826015..301b2ad13d 100644
--- a/src/gui/opengl/qopengltexture.cpp
+++ b/src/gui/opengl/qopengltexture.cpp
@@ -401,6 +401,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 +445,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 +669,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 +847,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 +865,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 +1329,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 +2025,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 +2563,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:
@@ -3458,6 +3628,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)
@@ -3483,6 +3655,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()
@@ -3490,6 +3665,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);
}
@@ -3510,6 +3690,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..ac9d44db42 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;
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..791b5f1a9a 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -43,6 +43,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 +60,7 @@ SOURCES += \
painting/qbrush.cpp \
painting/qcolor.cpp \
painting/qcolor_p.cpp \
+ painting/qcompositionfunctions.cpp \
painting/qcosmeticstroker.cpp \
painting/qcssutil.cpp \
painting/qdrawhelper.cpp \
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..1012ed7c6d 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
@@ -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 8fb5f4fd3f..61d57ca3f8 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/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index d74b48a3ca..0cf7e20605 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -51,6 +51,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 +185,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 +250,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 *)
{
@@ -320,7 +386,8 @@ template<QImage::Format Format> Q_DECL_CONSTEXPR static inline QPixelLayout pixe
false, bitsPerPixel<Format>(),
convertToRGB32<Format>,
convertRGBFromARGB32PM<Format>,
- convertRGBFromRGB32<Format>
+ convertRGBFromRGB32<Format>,
+ convertToRGB64<Format>
};
}
@@ -334,7 +401,8 @@ template<QImage::Format Format> Q_DECL_CONSTEXPR static inline QPixelLayout pixe
true, bitsPerPixel<Format>(),
convertARGBPMToARGB32PM<Format>,
convertARGBPMFromARGB32PM<Format>,
- convertARGBPMFromRGB32<Format>
+ convertARGBPMFromRGB32<Format>,
+ convertARGBPMToARGB64PM<Format>
};
}
@@ -349,6 +417,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 +467,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 +499,111 @@ 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)
+{
+ const __m128i amask = _mm_set1_epi32(0xff000000);
+ int i = 0;
+ if (((uintptr_t)buffer & 0xf) && count > 0) {
+ uint s = *src++;
+ if (RGBA)
+ s = RGBA2ARGB(s);
+ *buffer++ = QRgba64::fromArgb32(s);
+ i++;
+ }
+ 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 +637,60 @@ 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)
+{
+ 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;
+ if (((uintptr_t)buffer & 0xf) && count > 0) {
+ *buffer++ = qConvertA2rgb30ToRgb64<PixelOrder>(*src++);
+ i++;
+ }
+ 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,126 @@ 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;
+ if (i < count && (const uintptr_t)buffer & 0x8) {
+ *dest++ = qConvertRgb64ToRgb30<PixelOrder>(*buffer++);
+ ++i;
+ }
+
+ 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 +1365,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 +1449,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 +1631,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 +1826,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 +2747,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 +3258,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 +3454,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
{
- const uint *b = buffer;
+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 BlendType *b = buffer;
qreal t, inc;
bool affine = true;
@@ -2343,10 +3517,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 +3528,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 +3548,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 +3562,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 +3588,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 +3616,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 +3629,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 +3654,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 +3677,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 +3691,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 +3743,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 +3778,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 +3799,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 +3827,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 +3850,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 +3871,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() << Q_FUNC_INFO << "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 +3913,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 +3939,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 +4003,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 +4028,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 +4042,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 +4069,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 +4111,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 +4155,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() << Q_FUNC_INFO << "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 +4396,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 +5332,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 +5360,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 +5388,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 +5415,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 +5443,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 +5471,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 +5630,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 +5646,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),
+ 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, 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 +5786,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 +5882,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 +5980,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(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()),
- ARGB2RGBA(qUnpremultiply(color)), x, y, width, height, rasterBuffer->bytesPerLine());
+ 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 +6193,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 +6294,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)
{
@@ -6646,9 +6326,6 @@ template<QtPixelOrder> const uint *QT_FASTCALL convertA2RGB30PMFromARGB32PM_sse4
void qInitDrawhelperAsm()
{
- CompositionFunction *functionForModeAsm = 0;
- CompositionFunctionSolid *functionForModeSolidAsm = 0;
-
const uint features = qCpuFeatures();
Q_UNUSED(features);
#ifdef __SSE2__
@@ -6735,9 +6412,15 @@ 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)
@@ -6763,9 +6446,9 @@ 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;
+ 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;
destFetchProc[QImage::Format_RGB16] = qt_destFetchRGB16_neon;
destStoreProc[QImage::Format_RGB16] = qt_destStoreRGB16_neon;
@@ -6785,25 +6468,25 @@ void qInitDrawhelperAsm()
#if defined(QT_COMPILER_SUPPORTS_MIPS_DSP) || defined(QT_COMPILER_SUPPORTS_MIPS_DSPR2)
if (features & (DSP | 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 +6513,6 @@ 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;
}
QT_END_NAMESPACE
diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp
index 7e12e62151..08e564f017 100644
--- a/src/gui/painting/qdrawhelper_neon.cpp
+++ b/src/gui/painting/qdrawhelper_neon.cpp
@@ -466,7 +466,7 @@ void qt_blend_rgb32_on_rgb32_neon(uchar *destPixels, int dbpl,
}
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 +475,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);
@@ -985,7 +986,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_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..2fb9e7760c 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,17 +186,27 @@ 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;
@@ -208,7 +219,7 @@ class QRasterPaintEngine;
struct QSolidData
{
- uint color;
+ QRgba64 color;
};
struct QLinearGradientData
@@ -259,7 +270,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 +378,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 +392,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 +456,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 +466,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 +487,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 +552,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) \
@@ -680,19 +706,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 +738,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 +882,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 +956,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;
@@ -1025,89 +1117,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 +1151,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..c360573e78 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 10000000.0; }
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..a83acdd21a 100644
--- a/src/gui/painting/qpaintdevice.qdoc
+++ b/src/gui/painting/qpaintdevice.qdoc
@@ -286,3 +286,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..6b8136c52d 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();
@@ -4140,8 +4136,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 +4146,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();
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 +4174,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,7 +4190,7 @@ 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();
int stopCount = stops.count();
@@ -4203,14 +4199,16 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
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 +4220,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 +4241,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 +4258,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 +4277,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 +4290,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 +4314,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 +4334,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 +4355,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 +4373,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 +4406,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 +4417,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 +4434,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 +4455,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..e80c0130c3 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);
}
@@ -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..513fdfa2b6 100644
--- a/src/gui/painting/qpathclipper.cpp
+++ b/src/gui/painting/qpathclipper.cpp
@@ -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/qpdf.cpp b/src/gui/painting/qpdf.cpp
index 54e656e339..0814e0494d 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -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)
{
@@ -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;
@@ -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 62492980de..e765a9e402 100644
--- a/src/gui/painting/qplatformbackingstore.cpp
+++ b/src/gui/painting/qplatformbackingstore.cpp
@@ -100,7 +100,7 @@ public:
{
}
- QList<QBackingstoreTextureInfo> textures;
+ QVector<QBackingstoreTextureInfo> textures;
bool locked;
};
@@ -220,7 +220,9 @@ static QRegion deviceRegion(const QRegion &region, QWindow *window)
return region;
QVector<QRect> rects;
- foreach (QRect rect, region.rects())
+ const QVector<QRect> regionRects = region.rects();
+ rects.reserve(regionRects.count());
+ foreach (const QRect &rect, regionRects)
rects.append(deviceRect(rect, window));
QRegion deviceRegion;
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/qrgba64.h b/src/gui/painting/qrgba64.h
new file mode 100644
index 0000000000..cca9019959
--- /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) { *this = fromRgba64(_red, green(), blue(), alpha()); }
+ void setGreen(quint16 _green) { *this = fromRgba64(red(), _green, blue(), alpha()); }
+ void setBlue(quint16 _blue) { *this = fromRgba64(red(), green(), _blue, alpha()); }
+ void setAlpha(quint16 _alpha) { *this = fromRgba64(red(), green(), blue(), _alpha); }
+
+ 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 quint64 alphaMask() { return quint64(0xffff) << AlphaShift; }
+
+ static Q_DECL_CONSTEXPR uint div_257_floor(uint x) { return (x - (x >> 8)) >> 8; }
+ static Q_DECL_CONSTEXPR uint div_257(uint x) { return div_257_floor(x + 128); }
+ static Q_DECL_CONSTEXPR uint div_65535(uint x) { return (x + (x>>16) + 0x8000U) >> 16; }
+ Q_DECL_RELAXED_CONSTEXPR QRgba64 unpremultiplied_32bit() const
+ {
+ const quint16 a = alpha();
+ if (a == 0xffff || a == 0)
+ return *this;
+ 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 QRgba64 unpremultiplied_64bit() const
+ {
+ const quint16 a = alpha();
+ if (a == 0xffff || a == 0)
+ return *this;
+ 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..29da0aa390
--- /dev/null
+++ b/src/gui/painting/qrgba64.qdoc
@@ -0,0 +1,241 @@
+/****************************************************************************
+**
+** 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 unpremultipled QRgb without loss of precision except
+ for alpha 0.
+
+ \sa QRgb, QColor
+*/
+
+/*!
+ \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 quint16 QRgba64::red() const
+
+ Returns the 16-bit red color component.
+*/
+
+/*!
+ \fn quint16 QRgba64::green() const
+
+ Returns the 16-bit green color component.
+*/
+
+/*!
+ \fn quint16 QRgba64::blue() const
+
+ Returns the 16-bit blue color component.
+*/
+
+/*!
+ \fn quint16 QRgba64::alpha() const
+
+ Returns the 16-bit alpha channel.
+*/
+
+/*!
+ \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..c6cbe666ac
--- /dev/null
+++ b/src/gui/painting/qrgba64_p.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** 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
+
+#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..44e14f656d 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);
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 3c6709e685..796f223797 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;
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 85a804acfe..80908122a8 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -1413,22 +1413,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;
}
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index 37be0afccf..246df127ad 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
@@ -629,11 +636,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)
@@ -760,6 +763,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;
diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h
index 7b28a4064f..b81e51bf2e 100644
--- a/src/gui/text/qfontengine_ft_p.h
+++ b/src/gui/text/qfontengine_ft_p.h
@@ -281,7 +281,7 @@ private:
virtual int getPointInOutline(glyph_t glyph, int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints) Q_DECL_OVERRIDE;
-
+ void setQtDefaultHintStyle(QFont::HintingPreference hintingPreference);
virtual void setDefaultHintStyle(HintStyle style) Q_DECL_OVERRIDE;
virtual QFontEngine *cloneWithSize(qreal pixelSize) const Q_DECL_OVERRIDE;
@@ -307,6 +307,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;
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index bb34155d31..780104bc37 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"
@@ -328,12 +329,18 @@ 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/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..350f38cd02 100644
--- a/src/gui/text/qtextcursor.h
+++ b/src/gui/text/qtextcursor.h
@@ -66,10 +66,13 @@ public:
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;
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index 29e00d481e..0affd3239d 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -532,7 +532,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)
{
@@ -1401,7 +1401,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 +1456,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 +1467,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
@@ -1525,7 +1529,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 +1584,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 +1956,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..6b98c14205 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -1120,6 +1120,15 @@ QT_BEGIN_INCLUDE_NAMESPACE
QT_END_INCLUDE_NAMESPACE
+#if defined(Q_OS_OSX) && !defined(QT_NO_FREETYPE)
+static const char *s_shapersForOsxFreeType[] =
+{
+ "ot",
+ "fallback",
+ Q_NULLPTR
+};
+#endif
+
int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *string, int itemLength, QFontEngine *fontEngine, const QVector<uint> &itemBoundaries, bool kerningEnabled) const
{
uint glyphs_shaped = 0;
@@ -1172,7 +1181,15 @@ 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_OSX) && !defined(QT_NO_FREETYPE)
+ // What's behind QFontEngine::FaceData::user_data isn't compatible between CoreText and
+ // FreeType font engines - specifically functions in hb-coretext.cc would run into undefined
+ // behavior with data from the FreeType engine. The OpenType shaper works with that engine.
+ if (actualFontEngine->type() == QFontEngine::Freetype)
+ shaper_list = s_shapersForOsxFreeType;
+#endif
+ bool shapedOk = hb_shape_full(hb_font, buffer, features, num_features, shaper_list);
if (Q_UNLIKELY(!shapedOk)) {
hb_buffer_destroy(buffer);
return 0;
@@ -2571,7 +2588,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 +2880,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 +2964,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;
}
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index 39b9e0cb5a..d2b39f274c 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -400,6 +400,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 +410,7 @@ public:
QPen pen;
};
- typedef QList<ItemDecoration> ItemDecorationList;
+ typedef QVector<ItemDecoration> ItemDecorationList;
QTextEngine();
QTextEngine(const QString &str, const QFont &f);
@@ -570,9 +571,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 +581,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 +644,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..1ba2cb31ca 100644
--- a/src/gui/text/qtextimagehandler.cpp
+++ b/src/gui/text/qtextimagehandler.cpp
@@ -256,10 +256,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..0c729c74d1 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>());
}
/*!
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.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..429e910f18 100644
--- a/src/gui/text/qtextodfwriter.cpp
+++ b/src/gui/text/qtextodfwriter.cpp
@@ -396,7 +396,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.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..6053466148 100644
--- a/src/gui/text/qzip.cpp
+++ b/src/gui/text/qzip.cpp
@@ -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
@@ -913,15 +892,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 +923,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 +1021,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/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;