summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-08-02 07:54:03 +0000
committerThe Qt Project <gerrit-noreply@qt-project.org>2016-08-02 07:54:03 +0000
commitd875d5e2fc66b9a4ab1afea8441b33d4afc6e9b5 (patch)
treeda084fd38c0a2689f57fc98385f346beb9ac9906 /src/gui
parenta9603ef7d42c15090d86d04d1bc6aaf684257862 (diff)
parentf6fc34294f5691da8aa7ab8dc0452c6fa9036b67 (diff)
Merge "Merge remote-tracking branch 'origin/5.7' into dev" into refs/staging/dev
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/image/qimage.cpp44
-rw-r--r--src/gui/image/qpixmap.cpp6
-rw-r--r--src/gui/kernel/qevent.h4
-rw-r--r--src/gui/kernel/qplatformwindow.cpp31
-rw-r--r--src/gui/kernel/qwindow.cpp9
-rw-r--r--src/gui/opengl/qopengldebug.cpp40
-rw-r--r--src/gui/opengl/qopengltexturehelper_p.h16
-rw-r--r--src/gui/opengl/qopenglvertexarrayobject.cpp4
-rw-r--r--src/gui/painting/qbackingstore.cpp15
-rw-r--r--src/gui/text/qfont.cpp8
-rw-r--r--src/gui/text/qfontengine_ft.cpp5
11 files changed, 129 insertions, 53 deletions
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 3abfac1575..bd32ca7bee 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -840,17 +840,6 @@ QImageData *QImageData::create(uchar *data, int width, int height, int bpl, QIm
d->cleanupFunction = cleanupFunction;
d->cleanupInfo = cleanupInfo;
- switch (format) {
- case QImage::Format_Mono:
- case QImage::Format_MonoLSB:
- d->colortable.resize(2);
- d->colortable[0] = QColor(Qt::black).rgba();
- d->colortable[1] = QColor(Qt::white).rgba();
- break;
- default:
- break;
- }
-
return d;
}
@@ -2249,21 +2238,30 @@ QRgb QImage::pixel(int x, int y) const
}
const uchar *s = d->data + y * d->bytes_per_line;
- switch(d->format) {
+
+ int index = -1;
+ switch (d->format) {
case Format_Mono:
- return d->colortable.at((*(s + (x >> 3)) >> (~x & 7)) & 1);
+ index = (*(s + (x >> 3)) >> (~x & 7)) & 1;
+ break;
case Format_MonoLSB:
- return d->colortable.at((*(s + (x >> 3)) >> (x & 7)) & 1);
+ index = (*(s + (x >> 3)) >> (x & 7)) & 1;
+ break;
case Format_Indexed8:
- {
- int index = (int)s[x];
- if (index < d->colortable.size()) {
- return d->colortable.at(index);
- } else {
- qWarning("QImage::pixel: color table index %d out of range.", index);
- return 0;
- }
+ index = s[x];
+ break;
+ default:
+ break;
+ }
+ if (index >= 0) { // Indexed format
+ if (index >= d->colortable.size()) {
+ qWarning("QImage::pixel: color table index %d out of range.", index);
+ return 0;
}
+ return d->colortable.at(index);
+ }
+
+ switch (d->format) {
case Format_RGB32:
return 0xff000000 | reinterpret_cast<const QRgb *>(s)[x];
case Format_ARGB32: // Keep old behaviour.
@@ -4250,6 +4248,8 @@ void QImage::setAlphaChannel(const QImage &alphaChannel)
} else {
const QImage sourceImage = alphaChannel.convertToFormat(QImage::Format_RGB32);
+ if (sourceImage.isNull())
+ return;
const uchar *src_data = sourceImage.d->data;
uchar *dest_data = d->data;
for (int y=0; y<h; ++y) {
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index 4ab8160f21..a360debf5b 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -1410,10 +1410,8 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode)
QPixmap using the fromImage(). If this is too expensive an
operation, you can use QBitmap::fromImage() instead.
- The QPixmap class also supports conversion to and from HICON:
- the toWinHICON() function creates a HICON equivalent to the
- QPixmap, and returns the HICON handle. The fromWinHICON()
- function returns a QPixmap that is equivalent to the given icon.
+ To convert a QPixmap to and from HICON you can use the QtWinExtras
+ functions QtWin::toHICON() and QtWin::fromHICON() respectively.
\section1 Pixmap Transformations
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index fb72c561ab..93374b2299 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -537,8 +537,8 @@ public:
};
class Attribute {
public:
- Attribute(AttributeType t, int s, int l, QVariant val) : type(t), start(s), length(l), value(qMove(val)) {}
- Attribute(AttributeType t, int s, int l) : type(t), start(s), length(l), value() {}
+ Attribute(AttributeType typ, int s, int l, QVariant val) : type(typ), start(s), length(l), value(qMove(val)) {}
+ Attribute(AttributeType typ, int s, int l) : type(typ), start(s), length(l), value() {}
AttributeType type;
int start;
diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp
index e45a1d61ba..bcd3e830dd 100644
--- a/src/gui/kernel/qplatformwindow.cpp
+++ b/src/gui/kernel/qplatformwindow.cpp
@@ -581,6 +581,20 @@ void QPlatformWindow::invalidateSurface()
{
}
+static QSize fixInitialSize(QSize size, const QWindow *w,
+ int defaultWidth, int defaultHeight)
+{
+ if (size.width() == 0) {
+ const int minWidth = w->minimumWidth();
+ size.setWidth(minWidth > 0 ? minWidth : defaultWidth);
+ }
+ if (size.height() == 0) {
+ const int minHeight = w->minimumHeight();
+ size.setHeight(minHeight > 0 ? minHeight : defaultHeight);
+ }
+ return size;
+}
+
/*!
Helper function to get initial geometry on windowing systems which do not
do smart positioning and also do not provide a means of centering a
@@ -593,19 +607,18 @@ void QPlatformWindow::invalidateSurface()
QRect QPlatformWindow::initialGeometry(const QWindow *w,
const QRect &initialGeometry, int defaultWidth, int defaultHeight)
{
+ if (!w->isTopLevel()) {
+ const qreal factor = QHighDpiScaling::factor(w);
+ const QSize size = fixInitialSize(QHighDpi::fromNative(initialGeometry.size(), factor),
+ w, defaultWidth, defaultHeight);
+ return QRect(initialGeometry.topLeft(), QHighDpi::toNative(size, factor));
+ }
const QScreen *screen = effectiveScreen(w);
if (!screen)
return initialGeometry;
QRect rect(QHighDpi::fromNativePixels(initialGeometry, w));
- if (rect.width() == 0) {
- const int minWidth = w->minimumWidth();
- rect.setWidth(minWidth > 0 ? minWidth : defaultWidth);
- }
- if (rect.height() == 0) {
- const int minHeight = w->minimumHeight();
- rect.setHeight(minHeight > 0 ? minHeight : defaultHeight);
- }
- if (w->isTopLevel() && qt_window_private(const_cast<QWindow*>(w))->positionAutomatic
+ rect.setSize(fixInitialSize(rect.size(), w, defaultWidth, defaultHeight));
+ if (qt_window_private(const_cast<QWindow*>(w))->positionAutomatic
&& w->type() != Qt::Popup) {
const QRect availableGeometry = screen->availableGeometry();
// Center unless the geometry ( + unknown window frame) is too large for the screen).
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index fa26fd77a3..f061a2bf50 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -402,7 +402,7 @@ void QWindowPrivate::create(bool recursive)
q->parent()->create();
platformWindow = QGuiApplicationPrivate::platformIntegration()->createPlatformWindow(q);
- Q_ASSERT(platformWindow);
+ Q_ASSERT(platformWindow || q->type() == Qt::ForeignWindow);
if (!platformWindow) {
qWarning() << "Failed to create platform window for" << q << "with flags" << q->flags();
@@ -2432,7 +2432,8 @@ QWindow *QWindowPrivate::topLevelWindow() const
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.
+ If foreign windows are not supported or embedding the native window
+ failed in the platform plugin, 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
@@ -2453,6 +2454,10 @@ QWindow *QWindow::fromWinId(WId id)
window->setFlags(Qt::ForeignWindow);
window->setProperty("_q_foreignWinId", QVariant::fromValue(id));
window->create();
+ if (!window->handle()) {
+ delete window;
+ return nullptr;
+ }
return window;
}
diff --git a/src/gui/opengl/qopengldebug.cpp b/src/gui/opengl/qopengldebug.cpp
index 24aa6094dd..f6c3af37dd 100644
--- a/src/gui/opengl/qopengldebug.cpp
+++ b/src/gui/opengl/qopengldebug.cpp
@@ -42,6 +42,7 @@
#include <QtCore/qvarlengtharray.h>
#include <QtGui/qopengl.h>
#include <QtGui/qopenglfunctions.h>
+#include <QtGui/qoffscreensurface.h>
#include "qopengldebug.h"
@@ -1287,8 +1288,41 @@ void QOpenGLDebugLoggerPrivate::controlDebugMessages(QOpenGLDebugMessage::Source
*/
void QOpenGLDebugLoggerPrivate::_q_contextAboutToBeDestroyed()
{
+ Q_ASSERT(context);
+
+ // Re-make our context current somehow, otherwise stopLogging will fail.
+
+ // Save the current context and its surface in case we need to set them back
+ QOpenGLContext *currentContext = QOpenGLContext::currentContext();
+ QSurface *currentSurface = 0;
+
+ QScopedPointer<QOffscreenSurface> offscreenSurface;
+
+ if (context != currentContext) {
+ // Make our old context current on a temporary surface
+ if (currentContext)
+ currentSurface = currentContext->surface();
+
+ offscreenSurface.reset(new QOffscreenSurface);
+ offscreenSurface->setFormat(context->format());
+ offscreenSurface->create();
+ if (!context->makeCurrent(offscreenSurface.data()))
+ qWarning("QOpenGLDebugLoggerPrivate::_q_contextAboutToBeDestroyed(): could not make the owning GL context current for cleanup");
+ }
+
Q_Q(QOpenGLDebugLogger);
q->stopLogging();
+
+ if (offscreenSurface) {
+ // We did change the current context: set it back
+ if (currentContext)
+ currentContext->makeCurrent(currentSurface);
+ else
+ context->doneCurrent();
+ }
+
+ QObject::disconnect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed()));
+ context = 0;
initialized = false;
}
@@ -1494,6 +1528,12 @@ void QOpenGLDebugLogger::stopLogging()
if (!d->isLogging)
return;
+ QOpenGLContext *currentContext = QOpenGLContext::currentContext();
+ if (!currentContext || currentContext != d->context) {
+ qWarning("QOpenGLDebugLogger::stopLogging(): attempting to stop logging with the wrong OpenGL context current");
+ return;
+ }
+
d->isLogging = false;
d->glDebugMessageCallback(d->oldDebugCallbackFunction, d->oldDebugCallbackParameter);
diff --git a/src/gui/opengl/qopengltexturehelper_p.h b/src/gui/opengl/qopengltexturehelper_p.h
index 77049dced3..00f6f9e5aa 100644
--- a/src/gui/opengl/qopengltexturehelper_p.h
+++ b/src/gui/opengl/qopengltexturehelper_p.h
@@ -76,6 +76,14 @@ QT_BEGIN_NAMESPACE
#define GL_TEXTURE_COMPARE_FUNC 0x884D
#endif
+// use GL_APICALL only on Android + __clang__
+#if !defined(Q_OS_ANDROID) || !defined(__clang__)
+# undef GL_APICALL
+# define GL_APICALL
+#elif !defined(GL_APICALL)
+# define GL_APICALL
+#endif
+
class QOpenGLContext;
class QOpenGLTextureHelper
@@ -754,15 +762,15 @@ private:
// OpenGL 1.3
void (QOPENGLF_APIENTRYP GetCompressedTexImage)(GLenum target, GLint level, GLvoid *img);
void (QOPENGLF_APIENTRYP CompressedTexSubImage1D)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
- void (QOPENGLF_APIENTRYP CompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+ GL_APICALL void (QOPENGLF_APIENTRYP CompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, 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 CompressedTexImage1D)(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
- void (QOPENGLF_APIENTRYP CompressedTexImage2D)(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+ GL_APICALL void (QOPENGLF_APIENTRYP CompressedTexImage2D)(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
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 ActiveTexture)(GLenum texture);
+ GL_APICALL void (QOPENGLF_APIENTRYP ActiveTexture)(GLenum texture);
// OpenGL 3.0
- void (QOPENGLF_APIENTRYP GenerateMipmap)(GLenum target);
+ GL_APICALL void (QOPENGLF_APIENTRYP GenerateMipmap)(GLenum target);
// OpenGL 3.2
void (QOPENGLF_APIENTRYP TexImage3DMultisample)(GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
diff --git a/src/gui/opengl/qopenglvertexarrayobject.cpp b/src/gui/opengl/qopenglvertexarrayobject.cpp
index 6753064a60..babe52aa83 100644
--- a/src/gui/opengl/qopenglvertexarrayobject.cpp
+++ b/src/gui/opengl/qopenglvertexarrayobject.cpp
@@ -358,9 +358,11 @@ QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject()
Q_D(QOpenGLVertexArrayObject);
QOpenGLContext *oldContext = 0;
+ QSurface *oldContextSurface = 0;
QScopedPointer<QOffscreenSurface> offscreenSurface;
if (d->context && ctx && d->context != ctx) {
oldContext = ctx;
+ oldContextSurface = ctx->surface();
// Cannot just make the current surface current again with another context.
// The format may be incompatible and some platforms (iOS) may impose
// restrictions on using a window with different contexts. Create an
@@ -380,7 +382,7 @@ QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject()
destroy();
if (oldContext) {
- if (!oldContext->makeCurrent(oldContext->surface()))
+ if (!oldContext->makeCurrent(oldContextSurface))
qWarning("QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject() failed to restore current context");
}
}
diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp
index 801397751b..e3d18512dd 100644
--- a/src/gui/painting/qbackingstore.cpp
+++ b/src/gui/painting/qbackingstore.cpp
@@ -236,11 +236,16 @@ QSize QBackingStore::size() const
*/
bool QBackingStore::scroll(const QRegion &area, int dx, int dy)
{
- Q_UNUSED(area);
- Q_UNUSED(dx);
- Q_UNUSED(dy);
-
- return d_ptr->platformBackingStore->scroll(QHighDpi::toNativeLocalRegion(area, d_ptr->window), QHighDpi::toNativePixels(dx, d_ptr->window), QHighDpi::toNativePixels(dy, d_ptr->window));
+ // Disable scrolling for non-integer scroll deltas. For this case
+ // the the existing rendered pixels can't be re-used, and we return
+ // false to signal that a repaint is needed.
+ const qreal nativeDx = QHighDpi::toNativePixels(qreal(dx), d_ptr->window);
+ const qreal nativeDy = QHighDpi::toNativePixels(qreal(dy), d_ptr->window);
+ if (qFloor(nativeDx) != nativeDx || qFloor(nativeDy) != nativeDy)
+ return false;
+
+ return d_ptr->platformBackingStore->scroll(QHighDpi::toNativeLocalRegion(area, d_ptr->window),
+ nativeDx, nativeDy);
}
/*!
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index 828dbc318c..12631b3a73 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -76,7 +76,9 @@
QT_BEGIN_NAMESPACE
-
+#ifndef QFONTCACHE_DECREASE_TRIGGER_LIMIT
+# define QFONTCACHE_DECREASE_TRIGGER_LIMIT 256
+#endif
bool QFontDef::exactMatch(const QFontDef &other) const
{
@@ -2800,7 +2802,7 @@ void QFontCache::insertEngineData(const QFontDef &def, QFontEngineData *engineDa
engineData->ref.ref();
// Decrease now rather than waiting
- if (total_cost > min_cost * 2)
+ if (total_cost > min_cost * 2 && engineDataCache.size() >= QFONTCACHE_DECREASE_TRIGGER_LIMIT)
decreaseCache();
engineDataCache.insert(def, engineData);
@@ -2849,7 +2851,7 @@ void QFontCache::insertEngine(const Key &key, QFontEngine *engine, bool insertMu
#endif
engine->ref.ref();
// Decrease now rather than waiting
- if (total_cost > min_cost * 2)
+ if (total_cost > min_cost * 2 && engineCache.size() >= QFONTCACHE_DECREASE_TRIGGER_LIMIT)
decreaseCache();
Engine data(engine);
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index 26ed81a091..51b1418bc3 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -1849,7 +1849,10 @@ static inline QImage alphaMapFromGlyphData(QFontEngineFT::Glyph *glyph, QFontEng
Q_UNREACHABLE();
};
- return QImage(static_cast<const uchar *>(glyph->data), glyph->width, glyph->height, bytesPerLine, format);
+ QImage img(static_cast<const uchar *>(glyph->data), glyph->width, glyph->height, bytesPerLine, format);
+ if (format == QImage::Format_Mono)
+ img.setColor(1, QColor(Qt::white).rgba()); // Expands color table to 2 items; item 0 set to transparent.
+ return img;
}
QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixelPosition,