From 833341e301bf5ffc786e42a3c4be2ec25dbd8115 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 9 Nov 2015 14:00:22 +0100 Subject: Detect alpha8 as having alpha-pixels Change-Id: I09025da7e3df84b6092295ec1a02698bd7b24bed Reviewed-by: Gunnar Sletta --- src/gui/image/qimage.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'src/gui') diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index b3d8563614..01cacad630 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -192,7 +192,9 @@ bool QImageData::checkForAlphaPixels() const case QImage::Format_Indexed8: has_alpha_pixels = has_alpha_clut; break; - + case QImage::Format_Alpha8: + has_alpha_pixels = true; + break; case QImage::Format_ARGB32: case QImage::Format_ARGB32_Premultiplied: { uchar *bits = data; @@ -266,7 +268,20 @@ bool QImageData::checkForAlphaPixels() const } } break; - default: + case QImage::Format_RGB32: + case QImage::Format_RGB16: + case QImage::Format_RGB444: + case QImage::Format_RGB555: + case QImage::Format_RGB666: + case QImage::Format_RGB888: + case QImage::Format_RGBX8888: + case QImage::Format_BGR30: + case QImage::Format_RGB30: + case QImage::Format_Grayscale8: + break; + case QImage::Format_Invalid: + case QImage::NImageFormats: + Q_UNREACHABLE(); break; } -- cgit v1.2.3 From 672f7dfdcd00d124cd0f973e04e3e2d6445d5483 Mon Sep 17 00:00:00 2001 From: Juha Turunen Date: Tue, 8 Dec 2015 00:51:54 -0800 Subject: Fix a crash when calling QOpenGLTexture::setData with a null QImage. Change-Id: Idf8ae00cff6929114b38dcb003c259c83a11dbaa Reviewed-by: Laszlo Agocs --- src/gui/opengl/qopengltexture.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/gui') diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp index 5271826015..c58ddbd71e 100644 --- a/src/gui/opengl/qopengltexture.cpp +++ b/src/gui/opengl/qopengltexture.cpp @@ -3050,6 +3050,12 @@ void QOpenGLTexture::setData(const QImage& image, MipMapGeneration genMipMaps) qWarning("QOpenGLTexture::setData() requires a valid current context"); return; } + + if (image.isNull()) { + qWarning("QOpenGLTexture::setData() tried to set a null image"); + return; + } + if (context->isOpenGLES() && context->format().majorVersion() < 3) setFormat(QOpenGLTexture::RGBAFormat); else -- cgit v1.2.3 From 7ac5228144b692e40d40dfcfe2e3799f2ad4c620 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pasi=20Pet=C3=A4j=C3=A4j=C3=A4rvi?= Date: Thu, 12 Nov 2015 16:23:42 +0200 Subject: Delete QInputDeviceManager when deleting QGuiApplication Without deleting m_inputDeviceManager instance it will remain in process and causes crash when creating+destroying QGuiApplication multiple times in process. Crash happens because m_inputDeviceManager already exists when creating new instance of QGuiApplication and metadata for QInputDeviceManager is not anymore valid and crash when accessing it e.g. using connect() function. Change-Id: I5acb1c5f6ce2ba9665fa893047210a913debe4e4 Reviewed-by: Laszlo Agocs --- src/gui/kernel/qguiapplication.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gui') diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 64be8ee3d9..c2b561aa93 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -603,6 +603,8 @@ QGuiApplication::~QGuiApplication() QGuiApplicationPrivate::platform_name = 0; delete QGuiApplicationPrivate::displayName; QGuiApplicationPrivate::displayName = 0; + delete QGuiApplicationPrivate::m_inputDeviceManager; + QGuiApplicationPrivate::m_inputDeviceManager = 0; } QGuiApplicationPrivate::QGuiApplicationPrivate(int &argc, char **argv, int flags) -- cgit v1.2.3 From e109b8a0f3c89c595f0da689e7ee847130e2ee47 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 10 Dec 2015 08:35:14 +0100 Subject: Decrease the cache if necessary when adding a new font It was possible for the cache to increase too quickly since it was relying on the timer to decrease which caused problems with FreeType. So by checking if it will be increased to be over the limit first before adding the new font, we can decrease it earlier in preparation. Task-number: QTBUG-47812 Task-number: QTBUG-49535 Change-Id: Iedc042d8903949140aa8c5257a9d54cde31a51be Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfont.cpp | 12 +++++++++++- src/gui/text/qfont_p.h | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'src/gui') diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 3c6709e685..16550c0b3c 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -2793,6 +2793,10 @@ void QFontCache::insertEngineData(const QFontDef &def, QFontEngineData *engineDa Q_ASSERT(!engineDataCache.contains(def)); engineData->ref.ref(); + // Decrease now rather than waiting + if (total_cost > min_cost * 2) + decreaseCache(); + engineDataCache.insert(def, engineData); increaseCost(sizeof(QFontEngineData)); } @@ -2830,8 +2834,10 @@ void QFontCache::insertEngine(const Key &key, QFontEngine *engine, bool insertMu key.def.pixelSize, key.def.weight, key.def.style, key.def.fixedPitch); } #endif - engine->ref.ref(); + // Decrease now rather than waiting + if (total_cost > min_cost * 2) + decreaseCache(); Engine data(engine); data.timestamp = ++current_timestamp; @@ -2892,7 +2898,11 @@ void QFontCache::timerEvent(QTimerEvent *) return; } + decreaseCache(); +} +void QFontCache::decreaseCache() +{ // go through the cache and count up everything in use uint in_use_cost = 0; diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h index 25b5ef0b0e..ff9265ca19 100644 --- a/src/gui/text/qfont_p.h +++ b/src/gui/text/qfont_p.h @@ -276,6 +276,7 @@ private: void increaseCost(uint cost); void decreaseCost(uint cost); void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE; + void decreaseCache(); static const uint min_cost; uint total_cost, max_cost; -- cgit v1.2.3 From a88da6377da2e10998574ccc709bec014e2b75a5 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 16 Dec 2015 13:59:54 +0100 Subject: The cache_cost is measured in bytes and not kilobytes. When increaseCost() is called then it will convert from bytes to kilobytes so we need to specify the cache_cost to be in bytes. Task-number: QTBUG-47812 Change-Id: I842514c9ab4d86b60b2beb6c80979156ea0de59c Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfontengine_ft.cpp | 2 +- src/gui/text/qfontengine_p.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gui') diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 37be0afccf..1177305f6e 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -621,7 +621,7 @@ QFontEngineFT::QFontEngineFT(const QFontDef &fd) matrix.yy = 0x10000; matrix.xy = 0; matrix.yx = 0; - cache_cost = 100; + cache_cost = 100 * 1024; kerning_pairs_loaded = false; transform = false; embolden = false; diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index bb34155d31..6f4fabe1f6 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -277,7 +277,7 @@ public: qt_get_font_table_func_t get_font_table; } faceData; - uint cache_cost; // amount of mem used in kb by the font + uint cache_cost; // amount of mem used in bytes by the font uint fsType : 16; bool symbol; struct KernPair { -- cgit v1.2.3 From af45b352d7c29c42035196bb2d7c5c76a2f303da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 11 Jan 2016 19:25:05 +0100 Subject: Fix reentrancy regression in QShortcutMap after c7e5e1d9e When closing a popup dialog using a shortcut, when the popup was originally opened using a shortcut, the closing-shortcut would interfere with the state of the first shortcut, and we ended up sending a key event for the original shortcut. Task-number: QTBUG-50360 Change-Id: I62e5ddb9ca43b28519ede629775bc0d7598dccc4 Reviewed-by: Simon Hausmann --- src/gui/kernel/qshortcutmap.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/gui') diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp index 9c8218b7b5..3941f7233f 100644 --- a/src/gui/kernel/qshortcutmap.cpp +++ b/src/gui/kernel/qshortcutmap.cpp @@ -336,12 +336,16 @@ bool QShortcutMap::tryShortcut(QKeyEvent *e) // For a partial match we don't know yet if we will handle the shortcut // but we need to say we did, so that we get the follow-up key-presses. return true; - case QKeySequence::ExactMatch: + case QKeySequence::ExactMatch: { + // Save number of identical matches before dispatching + // to keep QShortcutMap and tryShortcut reentrant. + const int identicalMatches = d->identicals.count(); resetState(); dispatchEvent(e); // If there are no identicals we've only found disabled shortcuts, and // shouldn't say that we handled the event. - return d->identicals.count() > 0; + return identicalMatches > 0; + } default: Q_UNREACHABLE(); } -- cgit v1.2.3 From 1e15b428b59c3134a0f584bfb303e95d0682e45d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 12 Jan 2016 16:52:03 +0100 Subject: Fix shortcut modifiers not being propagated after c7e5e1d9e MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The code-path used by non-OSX platforms were not passing on the native scan-code, virtual key, and modifiers, breaking QKeyMapper::possibleKeys in the process. Task-number: QTBUG-50360 Change-Id: Idc36380a234f0a37d016dbeaca594aeb82c496d2 Reviewed-by: Simon Hausmann Reviewed-by: Błażej Szczygieł --- src/gui/kernel/qwindowsysteminterface.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gui') diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 8a46e7009b..d17a1f1d5b 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -275,8 +275,10 @@ bool QWindowSystemInterface::handleExtendedKeyEvent(QWindow *tlw, ulong timestam const QString& text, bool autorep, ushort count, bool tryShortcutOverride) { - if (tryShortcutOverride && type == QEvent::KeyPress && QWindowSystemInterface::handleShortcutEvent(tlw, timestamp, key, modifiers, 0, 0, 0, text, autorep, count)) + if (tryShortcutOverride && type == QEvent::KeyPress && QWindowSystemInterface::handleShortcutEvent(tlw, + timestamp, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count)) { return true; + } QWindowSystemInterfacePrivate::KeyEvent * e = new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, type, key, modifiers, -- cgit v1.2.3 From 0bc4288689882e731fc1811c4de11fbc6d0c28ff Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 11 Jan 2016 11:32:44 +0100 Subject: Optimize OpenGL binding of ARGB32PM backing store Detect premultiplied backing store and upload it without conversion and adjust blend to not multiply alpha again. Task-number: QTBUG-50381 Change-Id: I51939c4f82fbb0c48eaca6e2475bf4cf3722bc2d Reviewed-by: Laszlo Agocs Reviewed-by: Gunnar Sletta --- src/gui/kernel/qplatformgraphicsbufferhelper.cpp | 34 ++++++++++++++++----- src/gui/kernel/qplatformgraphicsbufferhelper.h | 4 +-- src/gui/painting/qplatformbackingstore.cpp | 38 ++++++++++++++++++------ src/gui/painting/qplatformbackingstore.h | 3 +- 4 files changed, 60 insertions(+), 19 deletions(-) (limited to 'src/gui') diff --git a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp index 1d59c38598..7f2672bc5e 100644 --- a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp +++ b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp @@ -64,7 +64,7 @@ QT_BEGIN_NAMESPACE bound texture, otherwise returns false. */ bool QPlatformGraphicsBufferHelper::lockAndBindToTexture(QPlatformGraphicsBuffer *graphicsBuffer, - bool *swizzle, + bool *swizzle, bool *premultiplied, const QRect &rect) { if (graphicsBuffer->lock(QPlatformGraphicsBuffer::TextureAccess)) { @@ -74,8 +74,10 @@ bool QPlatformGraphicsBufferHelper::lockAndBindToTexture(QPlatformGraphicsBuffer } if (swizzle) *swizzle = false; + if (premultiplied) + *premultiplied = false; } else if (graphicsBuffer->lock(QPlatformGraphicsBuffer::SWReadAccess)) { - if (!bindSWToTexture(graphicsBuffer, swizzle, rect)) { + if (!bindSWToTexture(graphicsBuffer, swizzle, premultiplied, rect)) { qWarning("Failed to bind %sgraphicsbuffer to texture", "SW "); return false; } @@ -109,7 +111,7 @@ bool QPlatformGraphicsBufferHelper::lockAndBindToTexture(QPlatformGraphicsBuffer Returns true on success, otherwise false. */ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffer *graphicsBuffer, - bool *swizzleRandB, + bool *swizzleRandB, bool *premultipliedB, const QRect &subRect) { #ifndef QT_NO_OPENGL @@ -124,14 +126,30 @@ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffe Q_ASSERT(subRect.isEmpty() || QRect(QPoint(0,0), size).contains(subRect)); bool swizzle = false; + bool premultiplied = false; QImage::Format imageformat = QImage::toImageFormat(graphicsBuffer->format()); QImage image(graphicsBuffer->data(), size.width(), size.height(), graphicsBuffer->bytesPerLine(), imageformat); if (graphicsBuffer->bytesPerLine() != (size.width() * 4)) { image = image.convertToFormat(QImage::Format_RGBA8888); - } else if (imageformat == QImage::Format_RGB32) { - swizzle = true; - } else if (imageformat != QImage::Format_RGBA8888) { - image = image.convertToFormat(QImage::Format_RGBA8888); + } else { + switch (imageformat) { + case QImage::Format_ARGB32_Premultiplied: + premultiplied = true; + // no break + case QImage::Format_RGB32: + case QImage::Format_ARGB32: + swizzle = true; + break; + case QImage::Format_RGBA8888_Premultiplied: + premultiplied = true; + // no break + case QImage::Format_RGBX8888: + case QImage::Format_RGBA8888: + break; + default: + image = image.convertToFormat(QImage::Format_RGBA8888); + break; + } } QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); @@ -170,6 +188,8 @@ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffe } if (swizzleRandB) *swizzleRandB = swizzle; + if (premultipliedB) + *premultipliedB = premultiplied; return true; diff --git a/src/gui/kernel/qplatformgraphicsbufferhelper.h b/src/gui/kernel/qplatformgraphicsbufferhelper.h index ded7810608..cc1a4918cd 100644 --- a/src/gui/kernel/qplatformgraphicsbufferhelper.h +++ b/src/gui/kernel/qplatformgraphicsbufferhelper.h @@ -39,8 +39,8 @@ QT_BEGIN_NAMESPACE namespace QPlatformGraphicsBufferHelper { - bool lockAndBindToTexture(QPlatformGraphicsBuffer *graphicsBuffer, bool *swizzleRandB, const QRect &rect = QRect()); - bool bindSWToTexture(const QPlatformGraphicsBuffer *graphicsBuffer, bool *swizzleRandB = Q_NULLPTR, const QRect &rect = QRect()); + bool lockAndBindToTexture(QPlatformGraphicsBuffer *graphicsBuffer, bool *swizzleRandB, bool *premultipliedB, const QRect &rect = QRect()); + bool bindSWToTexture(const QPlatformGraphicsBuffer *graphicsBuffer, bool *swizzleRandB = Q_NULLPTR, bool *premultipliedB = Q_NULLPTR, const QRect &rect = QRect()); } QT_END_NAMESPACE diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index 4b725fc79f..ef1652b48b 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -92,6 +92,7 @@ public: mutable GLuint textureId; mutable QSize textureSize; mutable bool needsSwizzle; + mutable bool premultiplied; QOpenGLTextureBlitter *blitter; #endif }; @@ -323,9 +324,6 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i blitTextureForWidget(textures, i, window, deviceWindowRect, d_ptr->blitter, offset); } - funcs->glEnable(GL_BLEND); - funcs->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - // Backingstore texture with the normal widgets. GLuint textureId = 0; QOpenGLTextureBlitter::Origin origin = QOpenGLTextureBlitter::OriginTopLeft; @@ -345,7 +343,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - if (QPlatformGraphicsBufferHelper::lockAndBindToTexture(graphicsBuffer, &d_ptr->needsSwizzle)) { + if (QPlatformGraphicsBufferHelper::lockAndBindToTexture(graphicsBuffer, &d_ptr->needsSwizzle, &d_ptr->premultiplied)) { d_ptr->textureSize = graphicsBuffer->size(); } else { d_ptr->textureSize = QSize(0,0); @@ -354,7 +352,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i graphicsBuffer->unlock(); } else if (!region.isEmpty()){ funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId); - QPlatformGraphicsBufferHelper::lockAndBindToTexture(graphicsBuffer, &d_ptr->needsSwizzle); + QPlatformGraphicsBufferHelper::lockAndBindToTexture(graphicsBuffer, &d_ptr->needsSwizzle, &d_ptr->premultiplied); } if (graphicsBuffer->origin() == QPlatformGraphicsBuffer::OriginBottomLeft) @@ -364,10 +362,17 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i TextureFlags flags = 0; textureId = toTexture(deviceRegion(region, window, offset), &d_ptr->textureSize, &flags); d_ptr->needsSwizzle = (flags & TextureSwizzle) != 0; + d_ptr->premultiplied = (flags & TexturePremultiplied) != 0; if (flags & TextureFlip) origin = QOpenGLTextureBlitter::OriginBottomLeft; } + funcs->glEnable(GL_BLEND); + if (d_ptr->premultiplied) + funcs->glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); + else + funcs->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); + if (textureId) { if (d_ptr->needsSwizzle) d_ptr->blitter->setSwizzleRB(true); @@ -443,10 +448,26 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu QImage image = toImage(); QSize imageSize = image.size(); + bool needConvert = false; *flags = 0; - if (image.format() == QImage::Format_RGB32) + switch (image.format()) { + case QImage::Format_ARGB32_Premultiplied: + *flags |= TexturePremultiplied; + // no break + case QImage::Format_RGB32: + case QImage::Format_ARGB32: *flags |= TextureSwizzle; - + break; + case QImage::Format_RGBA8888_Premultiplied: + *flags |= TexturePremultiplied; + // no break + case QImage::Format_RGBX8888: + case QImage::Format_RGBA8888: + break; + default: + needConvert = true; + break; + } if (imageSize.isEmpty()) { *textureSize = imageSize; return 0; @@ -460,8 +481,7 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu *textureSize = imageSize; - // Fast path for RGB32 and RGBA8888, convert everything else to RGBA8888. - if (image.format() != QImage::Format_RGB32 && image.format() != QImage::Format_RGBA8888) + if (needConvert) image = image.convertToFormat(QImage::Format_RGBA8888); QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h index eac97e9cf6..9c8da0d1db 100644 --- a/src/gui/painting/qplatformbackingstore.h +++ b/src/gui/painting/qplatformbackingstore.h @@ -118,7 +118,8 @@ public: virtual QImage toImage() const; enum TextureFlag { TextureSwizzle = 0x01, - TextureFlip = 0x02 + TextureFlip = 0x02, + TexturePremultiplied = 0x04, }; Q_DECLARE_FLAGS(TextureFlags, TextureFlag) virtual GLuint toTexture(const QRegion &dirtyRegion, QSize *textureSize, TextureFlags *flags) const; -- cgit v1.2.3 From d53f614740abcda84a1fae7f09fa68b94583e79f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 13 Jan 2016 14:18:35 -0800 Subject: Doc: add missing semi-colon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I408dcb81ba654c929f25ffff14291c57198e7367 Reviewed-by: Giuseppe D'Angelo Reviewed-by: Topi Reiniö --- src/gui/opengl/qopenglfunctions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gui') diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp index d614ad8401..be1a979c37 100644 --- a/src/gui/opengl/qopenglfunctions.cpp +++ b/src/gui/opengl/qopenglfunctions.cpp @@ -96,7 +96,7 @@ Q_LOGGING_CATEGORY(lcGLES3, "qt.opengl.es3") // Setup scene and render it initializeGL(); - paintGL() + paintGL(); } void MyGLWindow::initializeGL() -- cgit v1.2.3 From 4f71654385438a015931a0c7be52f2c7188c9f7d Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 11 Jan 2016 16:33:45 +0100 Subject: Handle RGB30 formats in OpenGL backing-store integration Optimizes composition on platforms that may use 10-bit per color channel formats. Change-Id: Ib303c391d47795c79a4ba55d78dbb1c3c702d90a Reviewed-by: Laszlo Agocs --- src/gui/kernel/qplatformgraphicsbufferhelper.cpp | 54 ++++++++++++++++++++---- src/gui/painting/qplatformbackingstore.cpp | 48 ++++++++++++++++----- 2 files changed, 83 insertions(+), 19 deletions(-) (limited to 'src/gui') diff --git a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp index 7f2672bc5e..c0c51b8d5e 100644 --- a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp +++ b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp @@ -40,6 +40,14 @@ #include #include +#ifndef GL_RGB10_A2 +#define GL_RGB10_A2 0x8059 +#endif + +#ifndef GL_UNSIGNED_INT_2_10_10_10_REV +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#endif + QT_BEGIN_NAMESPACE /*! @@ -115,7 +123,8 @@ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffe const QRect &subRect) { #ifndef QT_NO_OPENGL - if (!QOpenGLContext::currentContext()) + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + if (!ctx) return false; if (!(graphicsBuffer->isLocked() & QPlatformGraphicsBuffer::SWReadAccess)) @@ -125,12 +134,16 @@ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffe Q_ASSERT(subRect.isEmpty() || QRect(QPoint(0,0), size).contains(subRect)); + GLenum internalFormat = GL_RGBA; + GLuint pixelType = GL_UNSIGNED_BYTE; + + bool needsConversion = false; bool swizzle = false; bool premultiplied = false; QImage::Format imageformat = QImage::toImageFormat(graphicsBuffer->format()); QImage image(graphicsBuffer->data(), size.width(), size.height(), graphicsBuffer->bytesPerLine(), imageformat); if (graphicsBuffer->bytesPerLine() != (size.width() * 4)) { - image = image.convertToFormat(QImage::Format_RGBA8888); + needsConversion = true; } else { switch (imageformat) { case QImage::Format_ARGB32_Premultiplied: @@ -146,22 +159,45 @@ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffe case QImage::Format_RGBX8888: case QImage::Format_RGBA8888: break; + case QImage::Format_BGR30: + case QImage::Format_A2BGR30_Premultiplied: + if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) { + pixelType = GL_UNSIGNED_INT_2_10_10_10_REV; + internalFormat = GL_RGB10_A2; + premultiplied = true; + } else { + needsConversion = true; + } + break; + case QImage::Format_RGB30: + case QImage::Format_A2RGB30_Premultiplied: + if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) { + pixelType = GL_UNSIGNED_INT_2_10_10_10_REV; + internalFormat = GL_RGB10_A2; + premultiplied = true; + swizzle = true; + } else { + needsConversion = true; + } + break; default: - image = image.convertToFormat(QImage::Format_RGBA8888); + needsConversion = true; break; } } + if (needsConversion) + image = image.convertToFormat(QImage::Format_RGBA8888); - QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); + QOpenGLFunctions *funcs = ctx->functions(); QRect rect = subRect; if (rect.isNull() || rect == QRect(QPoint(0,0),size)) { - funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, image.constBits()); + funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, size.width(), size.height(), 0, GL_RGBA, pixelType, image.constBits()); } else { #ifndef QT_OPENGL_ES_2 - if (!QOpenGLContext::currentContext()->isOpenGLES()) { + if (!ctx->isOpenGLES()) { funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, image.width()); - funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, + funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType, image.constScanLine(rect.y()) + rect.x() * 4); funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); } else @@ -178,10 +214,10 @@ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffe // OpenGL instead of copying, since there's no gap between scanlines if (rect.width() == size.width()) { - funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, + funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType, image.constScanLine(rect.y())); } else { - funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, + funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType, image.copy(rect).constBits()); } } diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index ef1652b48b..83b75ae605 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -57,6 +57,12 @@ #ifndef GL_UNPACK_ROW_LENGTH #define GL_UNPACK_ROW_LENGTH 0x0CF2 #endif +#ifndef GL_RGB10_A2 +#define GL_RGB10_A2 0x8059 +#endif +#ifndef GL_UNSIGNED_INT_2_10_10_10_REV +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#endif QT_BEGIN_NAMESPACE @@ -448,7 +454,11 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu QImage image = toImage(); QSize imageSize = image.size(); - bool needConvert = false; + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + GLenum internalFormat = GL_RGBA; + GLuint pixelType = GL_UNSIGNED_BYTE; + + bool needsConversion = false; *flags = 0; switch (image.format()) { case QImage::Format_ARGB32_Premultiplied: @@ -464,8 +474,28 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu case QImage::Format_RGBX8888: case QImage::Format_RGBA8888: break; + case QImage::Format_BGR30: + case QImage::Format_A2BGR30_Premultiplied: + if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) { + pixelType = GL_UNSIGNED_INT_2_10_10_10_REV; + internalFormat = GL_RGB10_A2; + *flags |= TexturePremultiplied; + } else { + needsConversion = true; + } + break; + case QImage::Format_RGB30: + case QImage::Format_A2RGB30_Premultiplied: + if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) { + pixelType = GL_UNSIGNED_INT_2_10_10_10_REV; + internalFormat = GL_RGB10_A2; + *flags |= TextureSwizzle | TexturePremultiplied; + } else { + needsConversion = true; + } + break; default: - needConvert = true; + needsConversion = true; break; } if (imageSize.isEmpty()) { @@ -481,16 +511,15 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu *textureSize = imageSize; - if (needConvert) + if (needsConversion) image = image.convertToFormat(QImage::Format_RGBA8888); - QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); + QOpenGLFunctions *funcs = ctx->functions(); if (resized) { if (d_ptr->textureId) funcs->glDeleteTextures(1, &d_ptr->textureId); funcs->glGenTextures(1, &d_ptr->textureId); funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId); - 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); @@ -500,17 +529,16 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageSize.width(), imageSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, + funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, imageSize.width(), imageSize.height(), 0, GL_RGBA, pixelType, const_cast(image.constBits())); } else { funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId); QRect imageRect = image.rect(); QRect rect = dirtyRegion.boundingRect() & imageRect; - 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, + funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType, image.constScanLine(rect.y()) + rect.x() * 4); funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); } else { @@ -525,10 +553,10 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu // OpenGL instead of copying, since there's no gap between scanlines if (rect.width() == imageRect.width()) { - funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, + funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType, image.constScanLine(rect.y())); } else { - funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, + funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType, image.copy(rect).constBits()); } } -- cgit v1.2.3 From 8fd75739efd49a424e90938a51802f38c8c504e6 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 13 Jan 2016 14:54:48 +0100 Subject: Lock qfontdatabase mutex in qt_fallbacksForFamily When called from outside of qfontdatabase, the qfontdatabase mutex will not be locked upon entry to qt_fallbacksForFamily, so we need to add it to the exported version. Change-Id: I16a21708d7cca15730c12de3dbeeaab13ffbd315 Reviewed-by: Konstantin Ritt Reviewed-by: Oswald Buddenhagen Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfontdatabase.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'src/gui') diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 1b9852c20c..aae84dc988 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -838,7 +838,7 @@ QStringList QPlatformFontDatabase::fallbacksForFamily(const QString &family, QFo return retList; } -QStringList qt_fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) +static QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) { QFontDatabasePrivate *db = privateDb(); @@ -870,6 +870,12 @@ QStringList qt_fallbacksForFamily(const QString &family, QFont::Style style, QFo return retList; } +QStringList qt_fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) +{ + QMutexLocker locker(fontDatabaseMutex()); + return fallbacksForFamily(family, style, styleHint, script); +} + static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt); static void initializeDb() @@ -984,7 +990,7 @@ QFontEngine *loadEngine(int script, const QFontDef &request, if (styleHint == QFont::AnyStyle && request.fixedPitch) styleHint = QFont::TypeWriter; - fallbacks += qt_fallbacksForFamily(family->name, QFont::Style(style->key.style), styleHint, QChar::Script(script)); + fallbacks += fallbacksForFamily(family->name, QFont::Style(style->key.style), styleHint, QChar::Script(script)); pfMultiEngine->setFallbackFamiliesList(fallbacks); } @@ -2664,10 +2670,10 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script) styleHint = QFont::TypeWriter; QStringList fallbacks = request.fallBackFamilies - + qt_fallbacksForFamily(request.family, - QFont::Style(request.style), - styleHint, - QChar::Script(script)); + + fallbacksForFamily(request.family, + QFont::Style(request.style), + styleHint, + QChar::Script(script)); if (script > QChar::Script_Common) fallbacks += QString(); // Find the first font matching the specified script. -- cgit v1.2.3 From fd6cf5c875d794d23e513c8e7d6ebabc91dae790 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Sat, 16 Jan 2016 19:59:23 +0100 Subject: Avoid checking the fb status in every bind On some drivers (e.g. NVIDIA, tested on Windows) the status check is apparently expensive. A simple FBO test app rendering into the FBO on every frame (and thus calling bind()) shows a 19-21% CPU usage. With the patch this gets reduced to 0.8-1%. The check is fairly useless too - whenever creating attachments, the status is checked, so d->valid is up-to-date. Task-number: QTBUG-50496 Change-Id: Ie9f0db34e5c2bc1a1141c734ca0b318419013c0d Reviewed-by: Allan Sandfeld Jensen --- src/gui/opengl/qopenglframebufferobject.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gui') diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp index e0ef7c52a5..5184283a31 100644 --- a/src/gui/opengl/qopenglframebufferobject.cpp +++ b/src/gui/opengl/qopenglframebufferobject.cpp @@ -1077,8 +1077,6 @@ bool QOpenGLFramebufferObject::bind() } } - d->valid = d->checkFramebufferStatus(current); - return d->valid; } -- cgit v1.2.3