From 715a8e6f4ed3f8fd5c6d98c88b6260e5c1dba428 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 15 Sep 2015 15:51:43 +0200 Subject: Avoid image copy in toTexture() on GLES 3.0 as well The default backingstore implementation is now cleaned for ES_2 ifdefs. All the checks are now done at runtime and ES 3.0+ is included as well for the efficient, QImage::copy()-less path. For embedded a customized backingstore is used so the change has to be done separately there. This should result in a slight improvement for QOpenGLWidget/QQuickWidget when running on GLES 3.x. Task-number: QTBUG-37624 Change-Id: I107330c25a993c5cdcd92e4ebdc17ae172a03da8 Reviewed-by: Paul Olav Tvete --- src/gui/painting/qplatformbackingstore.cpp | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'src/gui') diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index c86fdebea5..dd02e24676 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -48,6 +48,16 @@ #include #include +#ifndef GL_TEXTURE_BASE_LEVEL +#define GL_TEXTURE_BASE_LEVEL 0x813C +#endif +#ifndef GL_TEXTURE_MAX_LEVEL +#define GL_TEXTURE_MAX_LEVEL 0x813D +#endif +#ifndef GL_UNPACK_ROW_LENGTH +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#endif + QT_BEGIN_NAMESPACE class QPlatformBackingStorePrivate @@ -311,12 +321,11 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i funcs->glDeleteTextures(1, &d_ptr->textureId); funcs->glGenTextures(1, &d_ptr->textureId); funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId); -#ifndef QT_OPENGL_ES_2 - if (!QOpenGLContext::currentContext()->isOpenGLES()) { + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) { funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); } -#endif funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); @@ -435,18 +444,16 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu image = image.convertToFormat(QImage::Format_RGBA8888); QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); - if (resized) { if (d_ptr->textureId) funcs->glDeleteTextures(1, &d_ptr->textureId); funcs->glGenTextures(1, &d_ptr->textureId); funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId); -#ifndef QT_OPENGL_ES_2 - if (!QOpenGLContext::currentContext()->isOpenGLES()) { + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) { funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); } -#endif funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); @@ -459,15 +466,13 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu QRect imageRect = image.rect(); QRect rect = dirtyRegion.boundingRect() & imageRect; -#ifndef QT_OPENGL_ES_2 - if (!QOpenGLContext::currentContext()->isOpenGLES()) { + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) { funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, image.width()); funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, image.constScanLine(rect.y()) + rect.x() * 4); funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - } else -#endif - { + } else { // if the rect is wide enough it's cheaper to just // extend it instead of doing an image copy if (rect.width() >= imageRect.width() / 2) { -- cgit v1.2.3 From 26a89e7bf7c39a4e8052f32f4b751476f101d15c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 9 Oct 2015 14:06:19 +0200 Subject: Don't use d_func in QWindow::mapToGlobal We initialize the variable d at the top using Q_D(const QWindow); Change-Id: I2de3b33c043024c5599b7cd1ebecae2db0b39d87 Reviewed-by: Christian Stromme --- src/gui/kernel/qwindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gui') diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index d4edc0fca1..628523e90f 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -2295,7 +2295,7 @@ QPoint QWindow::mapToGlobal(const QPoint &pos) const && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded(0))) { return d->platformWindow->mapToGlobal(pos); } - return pos + d_func()->globalPosition(); + return pos + d->globalPosition(); } @@ -2315,7 +2315,7 @@ QPoint QWindow::mapFromGlobal(const QPoint &pos) const && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded(0))) { return d->platformWindow->mapFromGlobal(pos); } - return pos - d_func()->globalPosition(); + return pos - d->globalPosition(); } -- cgit v1.2.3 From 233d0a6b8d497fa7ef43c02b9bb551ac48454773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 8 Oct 2015 14:29:13 +0200 Subject: Add default argument to QPlatformWindow::isEmbedded() Removes magic 0-pointers at the call sites. Change-Id: I6740f6b8cc75004ab5f2ebcb3b3c95cbbdc43153 Reviewed-by: Lars Knoll --- src/gui/kernel/qguiapplication.cpp | 2 +- src/gui/kernel/qplatformwindow.h | 2 +- src/gui/kernel/qwindow.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gui') diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 3f50ab8688..2e0595152b 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -870,7 +870,7 @@ QWindowList QGuiApplication::topLevelWindows() if (!list.at(i)->parent() && list.at(i)->type() != Qt::Desktop) { // Top windows of embedded QAxServers do not have QWindow parents, // but they are not true top level windows, so do not include them. - const bool embedded = list.at(i)->handle() && list.at(i)->handle()->isEmbedded(0); + const bool embedded = list.at(i)->handle() && list.at(i)->handle()->isEmbedded(); if (!embedded) topLevelWindows.prepend(list.at(i)); } diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h index 9c2817906f..850e2b4bfe 100644 --- a/src/gui/kernel/qplatformwindow.h +++ b/src/gui/kernel/qplatformwindow.h @@ -95,7 +95,7 @@ public: virtual bool isExposed() const; virtual bool isActive() const; - virtual bool isEmbedded(const QPlatformWindow *parentWindow) const; + virtual bool isEmbedded(const QPlatformWindow *parentWindow = 0) const; virtual QPoint mapToGlobal(const QPoint &pos) const; virtual QPoint mapFromGlobal(const QPoint &pos) const; diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 628523e90f..f1c754c422 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -2292,7 +2292,7 @@ QPoint QWindow::mapToGlobal(const QPoint &pos) const Q_D(const QWindow); // QTBUG-43252, prefer platform implementation for foreign windows. if (d->platformWindow - && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded(0))) { + && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded())) { return d->platformWindow->mapToGlobal(pos); } return pos + d->globalPosition(); @@ -2312,7 +2312,7 @@ QPoint QWindow::mapFromGlobal(const QPoint &pos) const Q_D(const QWindow); // QTBUG-43252, prefer platform implementation for foreign windows. if (d->platformWindow - && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded(0))) { + && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded())) { return d->platformWindow->mapFromGlobal(pos); } return pos - d->globalPosition(); -- cgit v1.2.3 From 957fb9fb82f6852e4d94bdce27892598e00bc677 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 13 Oct 2015 13:55:08 +0200 Subject: qt_pixmapFromWinHICON(): Fix crash and leak in case of Win32 API fails. Release the DC and move alpha-checking into separate function to prevent it from using invalid width/height. Task-number: QTBUG-48732 Change-Id: Iaf7cfa89b0f702f5012b0451d24a9e887d832c59 Reviewed-by: Oliver Wolff --- src/gui/image/qpixmap_win.cpp | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'src/gui') diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp index 12e19440dc..a7a9b375ff 100644 --- a/src/gui/image/qpixmap_win.cpp +++ b/src/gui/image/qpixmap_win.cpp @@ -345,9 +345,22 @@ static QImage qt_imageFromWinIconHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h) return image; } +static inline bool hasAlpha(const QImage &image) +{ + const int w = image.width(); + const int h = image.height(); + for (int y = 0; y < h; ++y) { + const QRgb *scanLine = reinterpret_cast(image.scanLine(y)); + for (int x = 0; x < w; ++x) { + if (qAlpha(scanLine[x]) != 0) + return true; + } + } + return false; +} + Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon) { - bool foundAlpha = false; HDC screenDevice = GetDC(0); HDC hdc = CreateCompatibleDC(screenDevice); ReleaseDC(0, screenDevice); @@ -356,6 +369,7 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon) const bool result = GetIconInfo(icon, &iconinfo); //x and y Hotspot describes the icon center if (!result) { qErrnoWarning("QPixmap::fromWinHICON(), failed to GetIconInfo()"); + DeleteDC(hdc); return QPixmap(); } @@ -371,17 +385,7 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon) DrawIconEx( hdc, 0, 0, icon, iconinfo.xHotspot * 2, iconinfo.yHotspot * 2, 0, 0, DI_NORMAL); QImage image = qt_imageFromWinIconHBITMAP(hdc, winBitmap, w, h); - for (int y = 0 ; y < h && !foundAlpha ; y++) { - const QRgb *scanLine= reinterpret_cast(image.scanLine(y)); - for (int x = 0; x < w ; x++) { - if (qAlpha(scanLine[x]) != 0) { - foundAlpha = true; - break; - } - } - } - if (!foundAlpha) { - //If no alpha was found, we use the mask to set alpha values + if (!image.isNull() && !hasAlpha(image)) { //If no alpha was found, we use the mask to set alpha values DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_MASK); const QImage mask = qt_imageFromWinIconHBITMAP(hdc, winBitmap, w, h); -- cgit v1.2.3 From e9121328866efa6ba3eb78a991fef785338fd55e Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Mon, 13 Apr 2015 14:13:34 +0300 Subject: xcb: Use XShape for DnD when a compositing manager is not running Otherwise transparent areas of the drag'n'drop pixmap are painted with the black color. Task-number: QTBUG-45193 Change-Id: I55b7c7caababe13584fa1c7a52835f112e20f920 Reviewed-by: Lars Knoll --- src/gui/kernel/qshapedpixmapdndwindow.cpp | 13 +++++++++++-- src/gui/kernel/qshapedpixmapdndwindow_p.h | 2 ++ src/gui/kernel/qsimpledrag.cpp | 3 ++- src/gui/kernel/qsimpledrag_p.h | 4 ++++ 4 files changed, 19 insertions(+), 3 deletions(-) (limited to 'src/gui') diff --git a/src/gui/kernel/qshapedpixmapdndwindow.cpp b/src/gui/kernel/qshapedpixmapdndwindow.cpp index 5736c41e25..d77b6dc262 100644 --- a/src/gui/kernel/qshapedpixmapdndwindow.cpp +++ b/src/gui/kernel/qshapedpixmapdndwindow.cpp @@ -35,12 +35,16 @@ #include #include +#include +#include +#include QT_BEGIN_NAMESPACE QShapedPixmapWindow::QShapedPixmapWindow(QScreen *screen) : QWindow(screen), - m_backingStore(0) + m_backingStore(0), + m_useCompositing(true) { QSurfaceFormat format; format.setAlphaBufferSize(8); @@ -68,7 +72,10 @@ void QShapedPixmapWindow::render() { QPainter p(device); - p.setCompositionMode(QPainter::CompositionMode_Source); + if (m_useCompositing) + p.setCompositionMode(QPainter::CompositionMode_Source); + else + p.fillRect(rect, QGuiApplication::palette().base()); p.drawPixmap(0, 0, m_pixmap); } @@ -79,6 +86,8 @@ void QShapedPixmapWindow::render() void QShapedPixmapWindow::setPixmap(const QPixmap &pixmap) { m_pixmap = pixmap; + if (!m_useCompositing) + setMask(m_pixmap.mask()); } void QShapedPixmapWindow::setHotspot(const QPoint &hotspot) diff --git a/src/gui/kernel/qshapedpixmapdndwindow_p.h b/src/gui/kernel/qshapedpixmapdndwindow_p.h index 7536c09165..3d7974fa82 100644 --- a/src/gui/kernel/qshapedpixmapdndwindow_p.h +++ b/src/gui/kernel/qshapedpixmapdndwindow_p.h @@ -60,6 +60,7 @@ public: void render(); + void setUseCompositing(bool on) { m_useCompositing = on; } void setPixmap(const QPixmap &pixmap); void setHotspot(const QPoint &hotspot); @@ -72,6 +73,7 @@ private: QBackingStore *m_backingStore; QPixmap m_pixmap; QPoint m_hotSpot; + bool m_useCompositing; }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp index 6acac4cade..9f38c9b78a 100644 --- a/src/gui/kernel/qsimpledrag.cpp +++ b/src/gui/kernel/qsimpledrag.cpp @@ -88,7 +88,7 @@ static QWindow* topLevelAt(const QPoint &pos) QBasicDrag::QBasicDrag() : m_restoreCursor(false), m_eventLoop(0), m_executed_drop_action(Qt::IgnoreAction), m_can_drop(false), - m_drag(0), m_drag_icon_window(0) + m_drag(0), m_drag_icon_window(0), m_useCompositing(true) { } @@ -226,6 +226,7 @@ void QBasicDrag::recreateShapedPixmapWindow(QScreen *screen, const QPoint &pos) // when QDrag is used without a pixmap - QDrag::setPixmap() m_drag_icon_window = new QShapedPixmapWindow(screen); + m_drag_icon_window->setUseCompositing(m_useCompositing); m_drag_icon_window->setPixmap(m_drag->pixmap()); m_drag_icon_window->setHotspot(m_drag->hotSpot()); m_drag_icon_window->updateGeometry(pos); diff --git a/src/gui/kernel/qsimpledrag_p.h b/src/gui/kernel/qsimpledrag_p.h index 4c9edbae05..055136c436 100644 --- a/src/gui/kernel/qsimpledrag_p.h +++ b/src/gui/kernel/qsimpledrag_p.h @@ -87,6 +87,9 @@ protected: bool canDrop() const { return m_can_drop; } void setCanDrop(bool c) { m_can_drop = c; } + bool useCompositing() const { return m_useCompositing; } + void setUseCompositing(bool on) { m_useCompositing = on; } + Qt::DropAction executedDropAction() const { return m_executed_drop_action; } void setExecutedDropAction(Qt::DropAction da) { m_executed_drop_action = da; } @@ -104,6 +107,7 @@ private: bool m_can_drop; QDrag *m_drag; QShapedPixmapWindow *m_drag_icon_window; + bool m_useCompositing; }; class Q_GUI_EXPORT QSimpleDrag : public QBasicDrag -- cgit v1.2.3 From 0a00782608c7dcc15f58f514bb75bbf0d646abed Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 3 Sep 2015 14:28:18 +0200 Subject: QShortcutMap: enable extra debugging when Dump_QShortcutMap is defined Dump_QShortcutMap is already made available in qshortcutmap_p.h, and if set, "void dumpMap() const;" will be available to help debugging. But unless QDebug &operator<< in qshortcutmap.cpp is also defined, the dumpMap output will be pretty useless. Change-Id: If8d535998ec01686eca25da73c2220062820a927 Reviewed-by: Frederik Gladhorn --- src/gui/kernel/qshortcutmap.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gui') diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp index 3b2e6ffd29..9c8218b7b5 100644 --- a/src/gui/kernel/qshortcutmap.cpp +++ b/src/gui/kernel/qshortcutmap.cpp @@ -84,7 +84,7 @@ struct QShortcutEntry QShortcutMap::ContextMatcher contextMatcher; }; -#if 0 //ndef QT_NO_DEBUG_STREAM +#ifdef Dump_QShortcutMap /*! \internal QDebug operator<< for easy debug output of the shortcut entries. */ @@ -99,7 +99,7 @@ static QDebug &operator<<(QDebug &dbg, const QShortcutEntry *se) << "), owner(" << se->owner << ')'; return dbg; } -#endif // QT_NO_DEBUGSTREAM +#endif // Dump_QShortcutMap /* \internal Private data for QShortcutMap -- cgit v1.2.3 From b37a548d083cf686cc6212fe9345c06406091f45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 13 Oct 2015 16:06:54 +0200 Subject: Clarify foreign window documentation a bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I50193cb0c106bc17a008e6778d2d722545c7cb1c Reviewed-by: Venugopal Shivashankar Reviewed-by: Lars Knoll Reviewed-by: Topi Reiniö --- src/gui/kernel/qplatformintegration.cpp | 3 +-- src/gui/kernel/qwindow.cpp | 11 ++++++----- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/gui') diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp index 457a420148..14633d8b30 100644 --- a/src/gui/kernel/qplatformintegration.cpp +++ b/src/gui/kernel/qplatformintegration.cpp @@ -208,8 +208,7 @@ QPlatformServices *QPlatformIntegration::services() const behavior for desktop platforms. \value ForeignWindows The platform allows creating QWindows which represent - native windows created by other processes or anyway created by using native - libraries. + native windows created by other processes or by using native libraries. \value NonFullScreenWindows The platform supports top-level windows which do not fill the screen. The default implementation returns \c true. Returning false for diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index f1c754c422..9ca5d3e9f8 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -588,8 +588,7 @@ QWindow *QWindow::parent() const Setting \a parent to be 0 will make the window become a top level window. If \a parent is a window created by fromWinId(), then the current window - will be embedded inside \a parent, if the platform supports it. Window - embedding is currently supported only by the X11 platform plugin. + will be embedded inside \a parent, if the platform supports it. */ void QWindow::setParent(QWindow *parent) { @@ -2377,9 +2376,11 @@ QWindow *QWindowPrivate::topLevelWindow() const Given the handle \a id to a native window, this method creates a QWindow object which can be used to represent the window when invoking methods like setParent() and setTransientParent(). - This can be used, on platforms which support it, to embed a window inside a - container or to make a window stick on top of a window created by another - process. + + This can be used, on platforms which support it, to embed a QWindow inside a + native window, or to embed a native window inside a QWindow. + + If foreign windows are not supported, this function returns 0. \sa setParent() \sa setTransientParent() -- cgit v1.2.3 From e9835a3812f91fc4a948a606fd751382d4ecf248 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 13 Oct 2015 16:13:30 +0200 Subject: Document that QWindow::fromWinId() should be used with caution Change-Id: I28c58fb720c323048615efe677a920f179ef9d20 Reviewed-by: Lars Knoll Reviewed-by: Friedemann Kleint --- src/gui/kernel/qwindow.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/gui') diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 9ca5d3e9f8..dbacfba4a8 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -2382,6 +2382,11 @@ QWindow *QWindowPrivate::topLevelWindow() const If foreign windows are not supported, this function returns 0. + \note The resulting QWindow should not be used to manipulate the underlying + native window (besides re-parenting), or to observe state changes of the + native window. Any support for these kind of operations is incidental, highly + platform dependent and untested. + \sa setParent() \sa setTransientParent() */ -- cgit v1.2.3 From 40b4c305d82e75d23842348a537972a0d2f15887 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 16 Oct 2015 14:40:53 +0200 Subject: Check that QPlatformIntegration::createPlatformWindow() doesn't fail We expect createPlatformWindow() to return a valid platform window. If it fails we now assert in debug, and emit a warning in release. The only platform where this is currently possible is on Windows, where the platform plugin will return 0 if CreateWindowEx for some reason fails. Change-Id: Ia2461efcfc48d180e073fa372d9c385650129e1c Reviewed-by: Friedemann Kleint --- src/gui/kernel/qwindow.cpp | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) (limited to 'src/gui') diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index dbacfba4a8..e262f3f8a4 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -389,25 +389,31 @@ void QWindowPrivate::setTopLevelScreen(QScreen *newScreen, bool recreate) void QWindowPrivate::create(bool recursive) { Q_Q(QWindow); + if (platformWindow) + return; + + platformWindow = QGuiApplicationPrivate::platformIntegration()->createPlatformWindow(q); + Q_ASSERT(platformWindow); + if (!platformWindow) { - platformWindow = QGuiApplicationPrivate::platformIntegration()->createPlatformWindow(q); - QObjectList childObjects = q->children(); - for (int i = 0; i < childObjects.size(); i ++) { - QObject *object = childObjects.at(i); - if (object->isWindowType()) { - QWindow *window = static_cast(object); - if (recursive) - window->d_func()->create(true); - if (window->d_func()->platformWindow) - window->d_func()->platformWindow->setParent(platformWindow); - } - } + qWarning() << "Failed to create platform window for" << q << "with flags" << q->flags(); + return; + } - if (platformWindow) { - QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceCreated); - QGuiApplication::sendEvent(q, &e); + QObjectList childObjects = q->children(); + for (int i = 0; i < childObjects.size(); i ++) { + QObject *object = childObjects.at(i); + if (object->isWindowType()) { + QWindow *window = static_cast(object); + if (recursive) + window->d_func()->create(true); + if (window->d_func()->platformWindow) + window->d_func()->platformWindow->setParent(platformWindow); } } + + QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceCreated); + QGuiApplication::sendEvent(q, &e); } void QWindowPrivate::clearFocusObject() -- cgit v1.2.3 From 068a545339a3ec14187e6b9b5ea05c6ffbda05a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 2 Oct 2015 23:48:17 +0200 Subject: Add support for "@3x" image loading. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement as generic "@Nx" support in an exported qt_findAtNxFile function. 3x devices now get one extra file existence test in cases where @3x versions are not present. 1x devices are still on the fast path where there are no extra file system accesses. Add an @3x image to the highdpi manual test. Change-Id: I4ce3fc245ada01ea410abe1443ceb1e3abf7c17f Reviewed-by: Timur Pocheptsov Reviewed-by: Tor Arne Vestbø --- src/gui/image/qicon.cpp | 51 ++++++++++++++++++++++++++++++-------- src/gui/image/qicon.h | 2 ++ src/gui/text/qtextimagehandler.cpp | 16 +++--------- 3 files changed, 45 insertions(+), 24 deletions(-) (limited to 'src/gui') diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index 7a59adffb8..af3af516db 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -45,6 +45,7 @@ #include "qcache.h" #include "qdebug.h" #include "qpalette.h" +#include "qmath.h" #include "private/qhexstring_p.h" #include "private/qguiapplication_p.h" @@ -1026,19 +1027,13 @@ void QIcon::addFile(const QString &fileName, const QSize &size, Mode mode, State } else { detach(); } + d->engine->addFile(fileName, size, mode, state); - // Check if a "@2x" file exists and add it. - static bool disable2xImageLoading = !qEnvironmentVariableIsEmpty("QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING"); - if (!disable2xImageLoading && qApp->devicePixelRatio() > 1.0) { - QString at2xfileName = fileName; - int dotIndex = fileName.lastIndexOf(QLatin1Char('.')); - if (dotIndex == -1) /* no dot */ - dotIndex = fileName.size(); /* append */ - at2xfileName.insert(dotIndex, QStringLiteral("@2x")); - if (QFile::exists(at2xfileName)) - d->engine->addFile(at2xfileName, size, mode, state); - } + // Check if a "@Nx" file exists and add it. + QString atNxFileName = qt_findAtNxFile(fileName, qApp->devicePixelRatio()); + if (atNxFileName != fileName) + d->engine->addFile(atNxFileName, size, mode, state); } /*! @@ -1375,5 +1370,39 @@ QDebug operator<<(QDebug dbg, const QIcon &i) \internal */ +/*! + \internal + \since 5.6 + Attempts to find a suitable @Nx file for the given \a targetDevicePixelRatio + Returns the the \a baseFileName if no such file was found. + + Given base foo.png and a target dpr of 2.5, this function will look for + foo@3x.png, then foo@2x, then fall back to foo.png if not found. +*/ +QString qt_findAtNxFile(const QString &baseFileName, qreal targetDevicePixelRatio) +{ + if (targetDevicePixelRatio <= 1.0) + return baseFileName; + + static bool disableNxImageLoading = !qEnvironmentVariableIsEmpty("QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING"); + if (disableNxImageLoading) + return baseFileName; + + QString atNx = QLatin1String("@%1x"); + int dotIndex = baseFileName.lastIndexOf(QLatin1Char('.')); + if (dotIndex == -1) /* no dot */ + dotIndex = baseFileName.size(); /* append */ + + // Check for @Nx, ..., @3x, @2x file versions, + for (int n = qCeil(targetDevicePixelRatio); n > 1; --n) { + QString atNxfileName = baseFileName; + atNxfileName.insert(dotIndex, atNx.arg(n)); + if (QFile::exists(atNxfileName)) + return atNxfileName; + } + + return baseFileName; +} + QT_END_NAMESPACE #endif //QT_NO_ICON diff --git a/src/gui/image/qicon.h b/src/gui/image/qicon.h index ccddf69101..8c72f54629 100644 --- a/src/gui/image/qicon.h +++ b/src/gui/image/qicon.h @@ -139,6 +139,8 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QIcon &); Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QIcon &); #endif +Q_GUI_EXPORT QString qt_findAtNxFile(const QString &baseFileName, qreal targetDevicePixelRatio); + QT_END_NAMESPACE #endif // QICON_H diff --git a/src/gui/text/qtextimagehandler.cpp b/src/gui/text/qtextimagehandler.cpp index 1ba2cb31ca..747ed90281 100644 --- a/src/gui/text/qtextimagehandler.cpp +++ b/src/gui/text/qtextimagehandler.cpp @@ -44,6 +44,7 @@ QT_BEGIN_NAMESPACE +extern QString qt_findAtNxFile(const QString &baseFileName, qreal targetDevicePixelRatio); static QString resolveFileName(QString fileName, QUrl *url, qreal targetDevicePixelRatio) { // We might use the fileName for loading if url loading fails @@ -62,19 +63,8 @@ static QString resolveFileName(QString fileName, QUrl *url, qreal targetDevicePi if (targetDevicePixelRatio <= 1.0) return fileName; - // try to find a 2x version - - const int dotIndex = fileName.lastIndexOf(QLatin1Char('.')); - if (dotIndex != -1) { - QString at2xfileName = fileName; - at2xfileName.insert(dotIndex, QStringLiteral("@2x")); - if (QFile::exists(at2xfileName)) { - fileName = at2xfileName; - *url = QUrl(fileName); - } - } - - return fileName; + // try to find a Nx version + return qt_findAtNxFile(fileName, targetDevicePixelRatio); } -- cgit v1.2.3 From 2eb0f8488cbfc6f7d9aedf7fe29a62ff579456ef Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 18 Mar 2015 15:18:01 +0100 Subject: Make sure registered schemes are lower case QUrl::scheme() already returns the scheme in lowercase, so this should guarantee that the matching works correctly. Task-number: QTBUG-5552 Change-Id: Ie68e01943c8cb105e11e54b348a090d9ffd5e65b Reviewed-by: Thiago Macieira --- src/gui/util/qdesktopservices.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gui') diff --git a/src/gui/util/qdesktopservices.cpp b/src/gui/util/qdesktopservices.cpp index 4c92e5d000..354dfeb78c 100644 --- a/src/gui/util/qdesktopservices.cpp +++ b/src/gui/util/qdesktopservices.cpp @@ -231,13 +231,13 @@ void QDesktopServices::setUrlHandler(const QString &scheme, QObject *receiver, c QOpenUrlHandlerRegistry *registry = handlerRegistry(); QMutexLocker locker(®istry->mutex); if (!receiver) { - registry->handlers.remove(scheme); + registry->handlers.remove(scheme.toLower()); return; } QOpenUrlHandlerRegistry::Handler h; h.receiver = receiver; h.name = method; - registry->handlers.insert(scheme, h); + registry->handlers.insert(scheme.toLower(), h); QObject::connect(receiver, SIGNAL(destroyed(QObject*)), registry, SLOT(handlerDestroyed(QObject*))); } -- cgit v1.2.3 From 2e3ebcd1d4d04dece0ac0427afae4cce7c417926 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Fri, 16 Oct 2015 07:36:59 +0200 Subject: Don't crash when QOpenGLPaintDevice is created without context. Change-Id: Ic826158a1570ec49e9847cf040ce897a682048db Reviewed-by: Laszlo Agocs --- src/gui/opengl/qopenglpaintengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gui') diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp index a9a4adaddc..4836dde343 100644 --- a/src/gui/opengl/qopenglpaintengine.cpp +++ b/src/gui/opengl/qopenglpaintengine.cpp @@ -2076,7 +2076,7 @@ bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev) d->device->ensureActiveTarget(); - if (d->device->context() != QOpenGLContext::currentContext()) { + if (d->device->context() != QOpenGLContext::currentContext() || !d->device->context()) { qWarning("QPainter::begin(): QOpenGLPaintDevice's context needs to be current"); return false; } -- cgit v1.2.3 From d159fe199fd50845fd20b00da0962c060479fe4c Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Tue, 13 Oct 2015 12:20:37 +0200 Subject: Doc: Update examplesinstallpath to include the repository name The examplesinstallpath variable in .qdocconf files defines the path under QT_INSTALL_EXAMPLES where examples are found. To match the way examples are packaged in Qt 5.6, prefix each install path with the repository name. Task-number: QTBUG-48736 Change-Id: I6a35c94fdacaad21cd044411aba02027b9019300 Reviewed-by: Venugopal Shivashankar --- src/gui/doc/qtgui.qdocconf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gui') diff --git a/src/gui/doc/qtgui.qdocconf b/src/gui/doc/qtgui.qdocconf index 436e2e0b34..e34347b801 100644 --- a/src/gui/doc/qtgui.qdocconf +++ b/src/gui/doc/qtgui.qdocconf @@ -4,7 +4,7 @@ project = QtGui description = Qt GUI Reference Documentation version = $QT_VERSION -examplesinstallpath = gui +examplesinstallpath = qtbase/gui qhp.projects = QtGui -- cgit v1.2.3 From 2a1d3f330d5f8cfc5358055b27e8e8301b3e050a Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 20 Oct 2015 12:19:11 +0200 Subject: Add support for TEXTURE_EXTERNAL_OES in the internal texture blitter Assuming that the target is always GL_TEXTURE_2D is not going to be sufficient when working with EGLStreams for example where GL_TEXTURE_EXTERNAL_OES is a must. The blitter is now changed to support multiple programs so other targets can easily be added as well in the future, if necessary. Change-Id: I247d30600222fb5af6305ed5d9740baa5e43e83e Reviewed-by: Louai Al-Khanji --- src/gui/opengl/qopengltextureblitter.cpp | 257 ++++++++++++++++++++----------- src/gui/opengl/qopengltextureblitter_p.h | 4 +- 2 files changed, 168 insertions(+), 93 deletions(-) (limited to 'src/gui') diff --git a/src/gui/opengl/qopengltextureblitter.cpp b/src/gui/opengl/qopengltextureblitter.cpp index 0f9fa6400d..1c6a7937e5 100644 --- a/src/gui/opengl/qopengltextureblitter.cpp +++ b/src/gui/opengl/qopengltextureblitter.cpp @@ -39,6 +39,10 @@ #include #include +#ifndef GL_TEXTURE_EXTERNAL_OES +#define GL_TEXTURE_EXTERNAL_OES 0x8D65 +#endif + QT_BEGIN_NAMESPACE static const char vertex_shader150[] = @@ -88,6 +92,18 @@ static const char fragment_shader[] = " gl_FragColor = swizzle ? tmpFragColor.bgra : tmpFragColor;" "}"; +static const char fragment_shader_external_oes[] = + "#extension GL_OES_EGL_image_external : require\n" + "varying highp vec2 uv;" + "uniform samplerExternalOES textureSampler;\n" + "uniform bool swizzle;" + "uniform highp float opacity;" + "void main() {" + " highp vec4 tmpFragColor = texture2D(textureSampler, uv);" + " tmpFragColor.a *= opacity;" + " gl_FragColor = swizzle ? tmpFragColor.bgra : tmpFragColor;" + "}"; + static const GLfloat vertex_buffer_data[] = { -1,-1, 0, -1, 1, 0, @@ -109,14 +125,17 @@ static const GLfloat texture_buffer_data[] = { class TextureBinder { public: - TextureBinder(GLuint textureId) + TextureBinder(GLenum target, GLuint textureId) : m_target(target) { - QOpenGLContext::currentContext()->functions()->glBindTexture(GL_TEXTURE_2D, textureId); + QOpenGLContext::currentContext()->functions()->glBindTexture(m_target, textureId); } ~TextureBinder() { - QOpenGLContext::currentContext()->functions()->glBindTexture(GL_TEXTURE_2D, 0); + QOpenGLContext::currentContext()->functions()->glBindTexture(m_target, 0); } + +private: + GLenum m_target; }; class QOpenGLTextureBlitterPrivate @@ -128,74 +147,106 @@ public: IdentityFlipped }; - QOpenGLTextureBlitterPrivate() - : program(0) - , vertexCoordAttribPos(0) - , vertexTransformUniformPos(0) - , textureCoordAttribPos(0) - , textureTransformUniformPos(0) - , swizzle(false) - , swizzleOld(false) - , opacity(1.0f) - , opacityOld(0.0f) - , textureMatrixUniformState(User) - , vao(new QOpenGLVertexArrayObject()) + enum ProgramIndex { + TEXTURE_2D, + TEXTURE_EXTERNAL_OES + }; + + QOpenGLTextureBlitterPrivate() : + swizzle(false), + opacity(1.0f), + vao(new QOpenGLVertexArrayObject), + currentTarget(TEXTURE_2D) { } + bool buildProgram(ProgramIndex idx, const char *vs, const char *fs); + void blit(GLuint texture, const QMatrix4x4 &vertexTransform, const QMatrix3x3 &textureTransform); void blit(GLuint texture, const QMatrix4x4 &vertexTransform, QOpenGLTextureBlitter::Origin origin); - void prepareProgram(const QMatrix4x4 &vertexTransform) - { - vertexBuffer.bind(); - program->setAttributeBuffer(vertexCoordAttribPos, GL_FLOAT, 0, 3, 0); - program->enableAttributeArray(vertexCoordAttribPos); - vertexBuffer.release(); - - program->setUniformValue(vertexTransformUniformPos, vertexTransform); - - textureBuffer.bind(); - program->setAttributeBuffer(textureCoordAttribPos, GL_FLOAT, 0, 2, 0); - program->enableAttributeArray(textureCoordAttribPos); - textureBuffer.release(); - - if (swizzle != swizzleOld) { - program->setUniformValue(swizzleUniformPos, swizzle); - swizzleOld = swizzle; - } - - if (opacity != opacityOld) { - program->setUniformValue(opacityUniformPos, opacity); - opacityOld = opacity; - } - } + void prepareProgram(const QMatrix4x4 &vertexTransform); QOpenGLBuffer vertexBuffer; QOpenGLBuffer textureBuffer; - QScopedPointer program; - GLuint vertexCoordAttribPos; - GLuint vertexTransformUniformPos; - GLuint textureCoordAttribPos; - GLuint textureTransformUniformPos; - GLuint swizzleUniformPos; - GLuint opacityUniformPos; + struct Program { + Program() : + vertexCoordAttribPos(0), + vertexTransformUniformPos(0), + textureCoordAttribPos(0), + textureTransformUniformPos(0), + swizzleUniformPos(0), + opacityUniformPos(0), + swizzle(false), + opacity(0.0f), + textureMatrixUniformState(User) + { } + QScopedPointer glProgram; + GLuint vertexCoordAttribPos; + GLuint vertexTransformUniformPos; + GLuint textureCoordAttribPos; + GLuint textureTransformUniformPos; + GLuint swizzleUniformPos; + GLuint opacityUniformPos; + bool swizzle; + float opacity; + TextureMatrixUniform textureMatrixUniformState; + } programs[2]; bool swizzle; - bool swizzleOld; float opacity; - float opacityOld; - TextureMatrixUniform textureMatrixUniformState; QScopedPointer vao; + GLenum currentTarget; }; +static inline QOpenGLTextureBlitterPrivate::ProgramIndex targetToProgramIndex(GLenum target) +{ + switch (target) { + case GL_TEXTURE_2D: + return QOpenGLTextureBlitterPrivate::TEXTURE_2D; + case GL_TEXTURE_EXTERNAL_OES: + return QOpenGLTextureBlitterPrivate::TEXTURE_EXTERNAL_OES; + default: + qWarning("Unsupported texture target 0x%x", target); + return QOpenGLTextureBlitterPrivate::TEXTURE_2D; + } +} + +void QOpenGLTextureBlitterPrivate::prepareProgram(const QMatrix4x4 &vertexTransform) +{ + Program *program = &programs[targetToProgramIndex(currentTarget)]; + + vertexBuffer.bind(); + program->glProgram->setAttributeBuffer(program->vertexCoordAttribPos, GL_FLOAT, 0, 3, 0); + program->glProgram->enableAttributeArray(program->vertexCoordAttribPos); + vertexBuffer.release(); + + program->glProgram->setUniformValue(program->vertexTransformUniformPos, vertexTransform); + + textureBuffer.bind(); + program->glProgram->setAttributeBuffer(program->textureCoordAttribPos, GL_FLOAT, 0, 2, 0); + program->glProgram->enableAttributeArray(program->textureCoordAttribPos); + textureBuffer.release(); + + if (swizzle != program->swizzle) { + program->glProgram->setUniformValue(program->swizzleUniformPos, swizzle); + program->swizzle = swizzle; + } + + if (opacity != program->opacity) { + program->glProgram->setUniformValue(program->opacityUniformPos, opacity); + program->opacity = opacity; + } +} + void QOpenGLTextureBlitterPrivate::blit(GLuint texture, const QMatrix4x4 &vertexTransform, const QMatrix3x3 &textureTransform) { - TextureBinder binder(texture); + TextureBinder binder(currentTarget, texture); prepareProgram(vertexTransform); - program->setUniformValue(textureTransformUniformPos, textureTransform); - textureMatrixUniformState = User; + Program *program = &programs[targetToProgramIndex(currentTarget)]; + program->glProgram->setUniformValue(program->textureTransformUniformPos, textureTransform); + program->textureMatrixUniformState = User; QOpenGLContext::currentContext()->functions()->glDrawArrays(GL_TRIANGLES, 0, 6); } @@ -204,25 +255,54 @@ void QOpenGLTextureBlitterPrivate::blit(GLuint texture, const QMatrix4x4 &vertexTransform, QOpenGLTextureBlitter::Origin origin) { - TextureBinder binder(texture); + TextureBinder binder(currentTarget, texture); prepareProgram(vertexTransform); + Program *program = &programs[targetToProgramIndex(currentTarget)]; if (origin == QOpenGLTextureBlitter::OriginTopLeft) { - if (textureMatrixUniformState != IdentityFlipped) { + if (program->textureMatrixUniformState != IdentityFlipped) { QMatrix3x3 flipped; flipped(1,1) = -1; flipped(1,2) = 1; - program->setUniformValue(textureTransformUniformPos, flipped); - textureMatrixUniformState = IdentityFlipped; + program->glProgram->setUniformValue(program->textureTransformUniformPos, flipped); + program->textureMatrixUniformState = IdentityFlipped; } - } else if (textureMatrixUniformState != Identity) { - program->setUniformValue(textureTransformUniformPos, QMatrix3x3()); - textureMatrixUniformState = Identity; + } else if (program->textureMatrixUniformState != Identity) { + program->glProgram->setUniformValue(program->textureTransformUniformPos, QMatrix3x3()); + program->textureMatrixUniformState = Identity; } QOpenGLContext::currentContext()->functions()->glDrawArrays(GL_TRIANGLES, 0, 6); } +bool QOpenGLTextureBlitterPrivate::buildProgram(ProgramIndex idx, const char *vs, const char *fs) +{ + Program *p = &programs[idx]; + + p->glProgram.reset(new QOpenGLShaderProgram); + + p->glProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, vs); + p->glProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, fs); + p->glProgram->link(); + if (!p->glProgram->isLinked()) { + qWarning() << Q_FUNC_INFO << "Could not link shader program:\n" << p->glProgram->log(); + return false; + } + + p->glProgram->bind(); + + p->vertexCoordAttribPos = p->glProgram->attributeLocation("vertexCoord"); + p->vertexTransformUniformPos = p->glProgram->uniformLocation("vertexTransform"); + p->textureCoordAttribPos = p->glProgram->attributeLocation("textureCoord"); + p->textureTransformUniformPos = p->glProgram->uniformLocation("textureTransform"); + p->swizzleUniformPos = p->glProgram->uniformLocation("swizzle"); + p->opacityUniformPos = p->glProgram->uniformLocation("opacity"); + + p->glProgram->setUniformValue(p->swizzleUniformPos, false); + + return true; +} + QOpenGLTextureBlitter::QOpenGLTextureBlitter() : d_ptr(new QOpenGLTextureBlitterPrivate) { @@ -241,28 +321,21 @@ bool QOpenGLTextureBlitter::create() Q_D(QOpenGLTextureBlitter); - if (d->program) + if (d->programs[QOpenGLTextureBlitterPrivate::TEXTURE_2D].glProgram) return true; - d->program.reset(new QOpenGLShaderProgram()); - QSurfaceFormat format = currentContext->format(); - if (format.profile() == QSurfaceFormat::CoreProfile && format.version() >= qMakePair(3,2)) { - d->program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertex_shader150); - d->program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragment_shader150); + if (!d->buildProgram(QOpenGLTextureBlitterPrivate::TEXTURE_2D, vertex_shader150, fragment_shader150)) + return false; } else { - d->program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertex_shader); - d->program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragment_shader); - } - d->program->link(); - if (!d->program->isLinked()) { - qWarning() << Q_FUNC_INFO << "Could not link shader program:\n" << d->program->log(); - return false; + if (!d->buildProgram(QOpenGLTextureBlitterPrivate::TEXTURE_2D, vertex_shader, fragment_shader)) + return false; + if (supportsExternalOESTarget()) + if (!d->buildProgram(QOpenGLTextureBlitterPrivate::TEXTURE_EXTERNAL_OES, vertex_shader, fragment_shader_external_oes)) + return false; } - d->program->bind(); - // Create and bind the VAO, if supported. QOpenGLVertexArrayObject::Binder vaoBinder(d->vao.data()); @@ -276,22 +349,13 @@ bool QOpenGLTextureBlitter::create() d->textureBuffer.allocate(texture_buffer_data, sizeof(texture_buffer_data)); d->textureBuffer.release(); - d->vertexCoordAttribPos = d->program->attributeLocation("vertexCoord"); - d->vertexTransformUniformPos = d->program->uniformLocation("vertexTransform"); - d->textureCoordAttribPos = d->program->attributeLocation("textureCoord"); - d->textureTransformUniformPos = d->program->uniformLocation("textureTransform"); - d->swizzleUniformPos = d->program->uniformLocation("swizzle"); - d->opacityUniformPos = d->program->uniformLocation("opacity"); - - d->program->setUniformValue(d->swizzleUniformPos,false); - return true; } bool QOpenGLTextureBlitter::isCreated() const { Q_D(const QOpenGLTextureBlitter); - return d->program; + return d->programs[QOpenGLTextureBlitterPrivate::TEXTURE_2D].glProgram; } void QOpenGLTextureBlitter::destroy() @@ -299,36 +363,45 @@ void QOpenGLTextureBlitter::destroy() if (!isCreated()) return; Q_D(QOpenGLTextureBlitter); - d->program.reset(); + d->programs[QOpenGLTextureBlitterPrivate::TEXTURE_2D].glProgram.reset(); + d->programs[QOpenGLTextureBlitterPrivate::TEXTURE_EXTERNAL_OES].glProgram.reset(); d->vertexBuffer.destroy(); d->textureBuffer.destroy(); d->vao.reset(); } -void QOpenGLTextureBlitter::bind() +bool QOpenGLTextureBlitter::supportsExternalOESTarget() const +{ + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + return ctx && ctx->isOpenGLES() && ctx->hasExtension("GL_OES_EGL_image_external"); +} + +void QOpenGLTextureBlitter::bind(GLenum target) { Q_D(QOpenGLTextureBlitter); if (d->vao->isCreated()) d->vao->bind(); - d->program->bind(); + d->currentTarget = target; + QOpenGLTextureBlitterPrivate::Program *p = &d->programs[targetToProgramIndex(target)]; + p->glProgram->bind(); d->vertexBuffer.bind(); - d->program->setAttributeBuffer(d->vertexCoordAttribPos, GL_FLOAT, 0, 3, 0); - d->program->enableAttributeArray(d->vertexCoordAttribPos); + p->glProgram->setAttributeBuffer(p->vertexCoordAttribPos, GL_FLOAT, 0, 3, 0); + p->glProgram->enableAttributeArray(p->vertexCoordAttribPos); d->vertexBuffer.release(); d->textureBuffer.bind(); - d->program->setAttributeBuffer(d->textureCoordAttribPos, GL_FLOAT, 0, 2, 0); - d->program->enableAttributeArray(d->textureCoordAttribPos); + p->glProgram->setAttributeBuffer(p->textureCoordAttribPos, GL_FLOAT, 0, 2, 0); + p->glProgram->enableAttributeArray(p->textureCoordAttribPos); d->textureBuffer.release(); } void QOpenGLTextureBlitter::release() { Q_D(QOpenGLTextureBlitter); - d->program->release(); + d->programs[targetToProgramIndex(d->currentTarget)].glProgram->release(); if (d->vao->isCreated()) d->vao->release(); } diff --git a/src/gui/opengl/qopengltextureblitter_p.h b/src/gui/opengl/qopengltextureblitter_p.h index 8f7eae1c32..ebf3a4bfbb 100644 --- a/src/gui/opengl/qopengltextureblitter_p.h +++ b/src/gui/opengl/qopengltextureblitter_p.h @@ -68,7 +68,9 @@ public: bool isCreated() const; void destroy(); - void bind(); + bool supportsExternalOESTarget() const; + + void bind(GLenum target = GL_TEXTURE_2D); void release(); void setSwizzleRB(bool swizzle); -- cgit v1.2.3 From 8ea61d6d2a63e49a7734fe70a2f2ddd2e14f7ca4 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Thu, 22 Oct 2015 14:38:44 +0200 Subject: Fix alignment issues on 32 bit in qConvertA2RGB30PMToARGB64PM_sse2 and qConvertARGB32PMToARGB64PM_sse2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On 32 bit platforms the pointers may end up being 4 byte aligned. Happens with MSVC on 32 bit Windows. _mm_store_si128 is documented to require 16 byte alignment. Change-Id: I80737fedf9e7f436a51a83924117cc0bc63017cc Reviewed-by: Jędrzej Nowacki --- src/gui/painting/qdrawhelper.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'src/gui') diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 64a363868a..6cfc4b9307 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -503,14 +503,16 @@ static const uint *QT_FASTCALL convertRGBA8888PMFromARGB32PM(uint *buffer, const template static inline void qConvertARGB32PMToARGB64PM_sse2(QRgba64 *buffer, const uint *src, int count) { + if (count <= 0) + return; + const __m128i amask = _mm_set1_epi32(0xff000000); int i = 0; - if (((uintptr_t)buffer & 0xf) && count > 0) { + for (; ((uintptr_t)buffer & 0xf) && i < count; ++i) { 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); @@ -641,15 +643,18 @@ static const uint *QT_FASTCALL convertA2RGB30PMToARGB32PM(uint *buffer, const ui template static inline void qConvertA2RGB30PMToARGB64PM_sse2(QRgba64 *buffer, const uint *src, int count) { + if (count <= 0) + return; + const __m128i rmask = _mm_set1_epi32(0x3ff00000); const __m128i gmask = _mm_set1_epi32(0x000ffc00); const __m128i bmask = _mm_set1_epi32(0x000003ff); const __m128i afactor = _mm_set1_epi16(0x5555); int i = 0; - if (((uintptr_t)buffer & 0xf) && count > 0) { + + for (; ((uintptr_t)buffer & 0xf) && i < count; ++i) *buffer++ = qConvertA2rgb30ToRgb64(*src++); - i++; - } + for (; i < count-3; i += 4) { __m128i vs = _mm_loadu_si128((const __m128i*)src); src += 4; -- cgit v1.2.3 From 661bcb79c8dee37da8bd9f8e231829879d25847d Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 16 Oct 2015 10:56:57 +0200 Subject: Fix warning message to match the function signature Change-Id: Ie21d63e29351dae9a52998e3d1068500e502ec5a Task-number: QTBUG-46693 Reviewed-by: Laszlo Agocs --- src/gui/painting/qcolor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gui') diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index 1012ed7c6d..3f30c061dc 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -2075,7 +2075,7 @@ QColor QColor::fromHsl(int h, int s, int l, int a) || s < 0 || s > 255 || l < 0 || l > 255 || a < 0 || a > 255) { - qWarning("QColor::fromHsv: HSV parameters out of range"); + qWarning("QColor::fromHsl: HSL parameters out of range"); return QColor(); } @@ -2107,7 +2107,7 @@ QColor QColor::fromHslF(qreal h, qreal s, qreal l, qreal a) || (s < qreal(0.0) || s > qreal(1.0)) || (l < qreal(0.0) || l > qreal(1.0)) || (a < qreal(0.0) || a > qreal(1.0))) { - qWarning("QColor::fromHsvF: HSV parameters out of range"); + qWarning("QColor::fromHslF: HSL parameters out of range"); return QColor(); } -- cgit v1.2.3 From cefc3930597707293edb408dc251528f9277e78b Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 16 Oct 2015 13:34:20 +0200 Subject: Respect QPen::dashOffset when generating PDF Change-Id: I26de1cd4a14d1b8978be6d0377cb2cba573fc82a Task-number: QTBUG-47164 Reviewed-by: Laszlo Agocs --- src/gui/painting/qpdf.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gui') diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index 0f81f09f60..47483b2869 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -377,8 +377,8 @@ QByteArray QPdf::generateDashes(const QPen &pen) s << dw; } s << ']'; - //qDebug() << "dasharray: pen has" << dasharray; - //qDebug() << " => " << result; + s << pen.dashOffset() * w; + s << " d\n"; return result; } @@ -1209,7 +1209,7 @@ void QPdfEngine::setPen() } *d->currentPage << pdfJoinStyle << "j "; - *d->currentPage << QPdf::generateDashes(d->pen) << " 0 d\n"; + *d->currentPage << QPdf::generateDashes(d->pen); } -- cgit v1.2.3 From be926e412c9c4ec9ee77b49dbe370fbb5451f0e1 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 21 Oct 2015 08:44:10 -0700 Subject: Prevent the pixmap cache from crashing if it's been destroyed In case the static destructor has already been run, make sure we don't crash. This shouldn't happen, but could happen if the QApplication destructor is run in a weird order (after the static destructors have begun running). That's not usually a case we'd fix (unsupported), but since this change improves the code and also avoids creating the pixmap cache if it hadn't been used up until this point, the change is a net benefit. Task-number: QTBUG-48709 Change-Id: Ia505aece07bf4e13a1faffff140f3e119cfc773e Reviewed-by: Gunnar Sletta --- src/gui/image/qpixmapcache.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gui') diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp index de37e0ab44..d29ddcf978 100644 --- a/src/gui/image/qpixmapcache.cpp +++ b/src/gui/image/qpixmapcache.cpp @@ -642,7 +642,8 @@ void QPixmapCache::remove(const Key &key) void QPixmapCache::clear() { QT_TRY { - pm_cache()->clear(); + if (pm_cache.exists()) + pm_cache->clear(); } QT_CATCH(const std::bad_alloc &) { // if we ran out of memory during pm_cache(), it's no leak, // so just ignore it. -- cgit v1.2.3