summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/image/qimage_p.h6
-rw-r--r--src/gui/kernel/qopenglwindow.cpp6
-rw-r--r--src/gui/opengl/qopenglframebufferobject.cpp4
-rw-r--r--src/gui/opengl/qopenglpaintengine.cpp53
-rw-r--r--src/gui/opengl/qopenglpaintengine_p.h2
-rw-r--r--src/gui/painting/qdrawhelper.cpp7
-rw-r--r--src/gui/text/qfontengine_ft.cpp22
-rw-r--r--src/gui/text/qfontengine_ft_p.h2
8 files changed, 61 insertions, 41 deletions
diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h
index 26c42b988e..47e68b14a5 100644
--- a/src/gui/image/qimage_p.h
+++ b/src/gui/image/qimage_p.h
@@ -116,6 +116,9 @@ void qInitImageConversions();
const uchar *qt_get_bitflip_array();
Q_GUI_EXPORT void qGamma_correct_back_to_linear_cs(QImage *image);
+#if defined(Q_OS_WINRT) && defined(_M_ARM) // QTBUG-42038
+#pragma optimize("", off)
+#endif
inline int qt_depthForFormat(QImage::Format format)
{
int depth = 0;
@@ -160,6 +163,9 @@ inline int qt_depthForFormat(QImage::Format format)
}
return depth;
}
+#if defined(Q_OS_WINRT) && defined(_M_ARM)
+#pragma optimize("", on)
+#endif
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qopenglwindow.cpp b/src/gui/kernel/qopenglwindow.cpp
index 158fb248dc..c37974c429 100644
--- a/src/gui/kernel/qopenglwindow.cpp
+++ b/src/gui/kernel/qopenglwindow.cpp
@@ -38,6 +38,7 @@
#include <QtGui/QOpenGLFunctions>
#include <QtGui/private/qopengltextureblitter_p.h>
#include <QtGui/private/qopenglextensions_p.h>
+#include <QtGui/private/qopenglcontext_p.h>
#include <QtGui/QMatrix4x4>
#include <QtGui/QOffscreenSurface>
@@ -101,6 +102,10 @@ QT_BEGIN_NAMESPACE
this way they do not have to redraw the entire window content on each
paintGL() call.
+ Similarly to QOpenGLWidget, QOpenGLWindow supports the Qt::AA_ShareOpenGLContexts
+ attribute. When enabled, the OpenGL contexts of all QOpenGLWindow instances will share
+ with each other. This allows accessing each other's shareable OpenGL resources.
+
For more information on graphics in Qt, see \l {Graphics}.
*/
@@ -196,6 +201,7 @@ public:
if (!context) {
context.reset(new QOpenGLContext);
+ context->setShareContext(qt_gl_global_share_context());
context->setFormat(q->requestedFormat());
if (!context->create())
qWarning("QOpenGLWindow::beginPaint: Failed to create context");
diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp
index 124d9d53f6..6351b8a1e3 100644
--- a/src/gui/opengl/qopenglframebufferobject.cpp
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -481,11 +481,9 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
GLenum storageFormat = internal_format;
// ES requires a sized format. The older desktop extension does not. Correct the format on ES.
if (ctx->isOpenGLES() && internal_format == GL_RGBA) {
-#ifdef GL_RGBA8_OES
if (funcs.hasOpenGLExtension(QOpenGLExtensions::Sized8Formats))
- storageFormat = GL_RGBA8_OES;
+ storageFormat = GL_RGBA8;
else
-#endif
storageFormat = GL_RGBA4;
}
diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp
index 299d3da73d..bfc08a5332 100644
--- a/src/gui/opengl/qopenglpaintengine.cpp
+++ b/src/gui/opengl/qopenglpaintengine.cpp
@@ -107,7 +107,7 @@ QOpenGL2PaintEngineExPrivate::~QOpenGL2PaintEngineExPrivate()
}
}
-void QOpenGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id)
+void QOpenGL2PaintEngineExPrivate::updateTextureFilter(GLenum wrapMode, bool smoothPixmapTransform, GLuint id)
{
// funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); //### Is it always this texture unit?
if (id != GLuint(-1) && id == lastTextureUsed)
@@ -115,6 +115,8 @@ void QOpenGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wra
lastTextureUsed = id;
+ static const GLenum target = GL_TEXTURE_2D;
+
if (smoothPixmapTransform) {
funcs.glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
funcs.glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -122,6 +124,7 @@ void QOpenGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wra
funcs.glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
funcs.glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
+
funcs.glTexParameteri(target, GL_TEXTURE_WRAP_S, wrapMode);
funcs.glTexParameteri(target, GL_TEXTURE_WRAP_T, wrapMode);
}
@@ -185,7 +188,7 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture()
funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, texImage);
- updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
+ updateTextureFilter(GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
}
else if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) {
// Gradiant brush: All the gradiants use the same texture
@@ -196,15 +199,15 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture()
// for opacity to the cache.
GLuint texId = QOpenGL2GradientCache::cacheForContext(ctx)->getBuffer(*g, 1.0);
- funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
- funcs.glBindTexture(GL_TEXTURE_2D, texId);
-
+ GLenum wrapMode = GL_CLAMP_TO_EDGE;
if (g->spread() == QGradient::RepeatSpread || g->type() == QGradient::ConicalGradient)
- updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
+ wrapMode = GL_REPEAT;
else if (g->spread() == QGradient::ReflectSpread)
- updateTextureFilter(GL_TEXTURE_2D, GL_MIRRORED_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
- else
- updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, q->state()->renderHints & QPainter::SmoothPixmapTransform);
+ wrapMode = GL_MIRRORED_REPEAT;
+
+ funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
+ funcs.glBindTexture(GL_TEXTURE_2D, texId);
+ updateTextureFilter(wrapMode, q->state()->renderHints & QPainter::SmoothPixmapTransform);
}
else if (style == Qt::TexturePattern) {
currentBrushImage = currentBrush.textureImage();
@@ -223,7 +226,8 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture()
funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, currentBrushImage);
- updateTextureFilter(GL_TEXTURE_2D, wrapMode, q->state()->renderHints & QPainter::SmoothPixmapTransform);
+ updateTextureFilter(wrapMode, q->state()->renderHints & QPainter::SmoothPixmapTransform);
+
textureInvertedY = false;
}
brushTextureDirty = false;
@@ -1380,16 +1384,14 @@ void QOpenGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixma
d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
GLuint id = QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, pixmap);
-
- QOpenGLRect srcRect(src.left(), src.top(), src.right(), src.bottom());
+ d->updateTextureFilter(GL_CLAMP_TO_EDGE, state()->renderHints & QPainter::SmoothPixmapTransform, id);
bool isBitmap = pixmap.isQBitmap();
bool isOpaque = !isBitmap && !pixmap.hasAlpha();
- d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
- state()->renderHints & QPainter::SmoothPixmapTransform, id);
-
d->shaderManager->setSrcPixelType(isBitmap ? QOpenGLEngineShaderManager::PatternSrc : QOpenGLEngineShaderManager::ImageSrc);
+
+ QOpenGLRect srcRect(src.left(), src.top(), src.right(), src.bottom());
d->drawTexture(dest, srcRect, pixmap.size(), isOpaque, isBitmap);
}
@@ -1442,9 +1444,7 @@ void QOpenGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, c
d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
GLuint id = QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, image, bindOption);
-
- d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
- state()->renderHints & QPainter::SmoothPixmapTransform, id);
+ d->updateTextureFilter(GL_CLAMP_TO_EDGE, state()->renderHints & QPainter::SmoothPixmapTransform, id);
d->drawTexture(dest, src, image.size(), !image.hasAlphaChannel());
}
@@ -1487,13 +1487,13 @@ bool QOpenGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, co
d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
d->funcs.glBindTexture(GL_TEXTURE_2D, textureId);
+ d->updateTextureFilter(GL_CLAMP_TO_EDGE, state()->renderHints & QPainter::SmoothPixmapTransform, textureId);
- QOpenGLRect srcRect(src.left(), src.bottom(), src.right(), src.top());
-
- d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
- state()->renderHints & QPainter::SmoothPixmapTransform, textureId);
d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::ImageSrc);
+
+ QOpenGLRect srcRect(src.left(), src.bottom(), src.right(), src.top());
d->drawTexture(dest, srcRect, size, false);
+
return true;
}
@@ -1821,7 +1821,7 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat gly
funcs.glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT);
funcs.glBindTexture(GL_TEXTURE_2D, cache->texture());
- updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false);
+ updateTextureFilter(GL_REPEAT, false);
#if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO)
funcs.glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, 0);
@@ -1964,16 +1964,15 @@ void QOpenGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::PixmapFra
allOpaque &= (opacity >= 0.99f);
}
+ transferMode(ImageOpacityArrayDrawingMode);
+
funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
GLuint id = QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, pixmap);
- transferMode(ImageOpacityArrayDrawingMode);
+ updateTextureFilter(GL_CLAMP_TO_EDGE, q->state()->renderHints & QPainter::SmoothPixmapTransform, id);
bool isBitmap = pixmap.isQBitmap();
bool isOpaque = !isBitmap && (!pixmap.hasAlpha() || (hints & QPainter::OpaqueHint)) && allOpaque;
- updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
- q->state()->renderHints & QPainter::SmoothPixmapTransform, id);
-
// Setup for texture drawing
currentBrush = noBrush;
shaderManager->setSrcPixelType(isBitmap ? QOpenGLEngineShaderManager::PatternSrc
diff --git a/src/gui/opengl/qopenglpaintengine_p.h b/src/gui/opengl/qopenglpaintengine_p.h
index 47e915eae5..85ecd82b6f 100644
--- a/src/gui/opengl/qopenglpaintengine_p.h
+++ b/src/gui/opengl/qopenglpaintengine_p.h
@@ -193,7 +193,7 @@ public:
void updateBrushUniforms();
void updateMatrix();
void updateCompositionMode();
- void updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id = GLuint(-1));
+ void updateTextureFilter(GLenum wrapMode, bool smoothPixmapTransform, GLuint id = GLuint(-1));
void resetGLState();
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index a991b89f48..bd53952d1b 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -6288,6 +6288,8 @@ static inline void rgbBlendPixel(quint32 *dst, int coverage, int sr, int sg, int
}
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+Q_GUI_EXPORT bool qt_needs_a8_gamma_correction = false;
+
static inline void grayBlendPixel(quint32 *dst, int coverage, int sr, int sg, int sb, const uint *gamma, const uchar *invgamma)
{
// Do a gammacorrected gray alphablend...
@@ -6335,6 +6337,7 @@ static void qt_alphamapblit_argb32(QRasterBuffer *rasterBuffer,
int sb = gamma[qBlue(color)];
bool opaque_src = (qAlpha(color) == 255);
+ bool doGrayBlendPixel = opaque_src && qt_needs_a8_gamma_correction;
#endif
if (!clip) {
@@ -6349,7 +6352,7 @@ static void qt_alphamapblit_argb32(QRasterBuffer *rasterBuffer,
dest[i] = c;
} else {
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
- if (QSysInfo::WindowsVersion >= QSysInfo::WV_XP && opaque_src
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_XP && doGrayBlendPixel
&& qAlpha(dest[i]) == 255) {
grayBlendPixel(dest+i, coverage, sr, sg, sb, gamma, invgamma);
} else
@@ -6390,7 +6393,7 @@ static void qt_alphamapblit_argb32(QRasterBuffer *rasterBuffer,
dest[xp] = c;
} else {
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
- if (QSysInfo::WindowsVersion >= QSysInfo::WV_XP && opaque_src
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_XP && doGrayBlendPixel
&& qAlpha(dest[xp]) == 255) {
grayBlendPixel(dest+xp, coverage, sr, sg, sb, gamma, invgamma);
} else
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index ef397e532c..4d6c04a262 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -762,8 +762,10 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
face->face_flags &= ~FT_FACE_FLAG_SCALABLE;
FT_Select_Size(face, i);
- metrics.ascender = face->size->metrics.ascender;
- metrics.descender = face->size->metrics.descender;
+ if (face->size->metrics.ascender + face->size->metrics.descender > 0) {
+ metrics.ascender = face->size->metrics.ascender;
+ metrics.descender = face->size->metrics.descender;
+ }
FT_Set_Char_Size(face, xsize, ysize, 0, 0);
face->face_flags |= FT_FACE_FLAG_SCALABLE;
@@ -889,6 +891,13 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
// this is an error in the bytecode interpreter, just try to run without it
load_flags |= FT_LOAD_FORCE_AUTOHINT;
err = FT_Load_Glyph(face, glyph, load_flags);
+ } else if (err == FT_Err_Execution_Too_Long) {
+ // This is an error in the bytecode, probably a web font made by someone who
+ // didn't test bytecode hinting at all so disable for it for all glyphs.
+ qWarning("load glyph failed due to broken hinting bytecode in font, switching to auto hinting");
+ default_load_flags |= FT_LOAD_FORCE_AUTOHINT;
+ load_flags |= FT_LOAD_FORCE_AUTOHINT;
+ err = FT_Load_Glyph(face, glyph, load_flags);
}
if (err != FT_Err_Ok) {
qWarning("load glyph failed err=%x face=%p, glyph=%d", err, face, glyph);
@@ -1123,7 +1132,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
while (h--) {
uint *dd = (uint *)dst;
*dd++ = 0;
- for (int x = 0; x < slot->bitmap.width; x++) {
+ for (int x = 0; x < static_cast<int>(slot->bitmap.width); x++) {
uint a = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xffffff : 0x000000);
*dd++ = a;
}
@@ -1134,7 +1143,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
} else if (vfactor != 1) {
while (h--) {
uint *dd = (uint *)dst;
- for (int x = 0; x < slot->bitmap.width; x++) {
+ for (int x = 0; x < static_cast<int>(slot->bitmap.width); x++) {
uint a = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xffffff : 0x000000);
*dd++ = a;
}
@@ -1143,7 +1152,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
}
} else {
while (h--) {
- for (int x = 0; x < slot->bitmap.width; x++) {
+ for (int x = 0; x < static_cast<int>(slot->bitmap.width); x++) {
unsigned char a = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xff : 0x00);
dst[x] = a;
}
@@ -1771,8 +1780,7 @@ glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixe
overall.x = TRUNC(left);
overall.y = -TRUNC(top);
overall.xoff = TRUNC(ROUND(face->glyph->advance.x));
- if (face)
- unlockFace();
+ unlockFace();
}
return overall;
}
diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h
index 4c29b5a504..02c692cccc 100644
--- a/src/gui/text/qfontengine_ft_p.h
+++ b/src/gui/text/qfontengine_ft_p.h
@@ -293,7 +293,7 @@ private:
protected:
QFreetypeFace *freetype;
- int default_load_flags;
+ mutable int default_load_flags;
HintStyle default_hint_style;
bool antialias;
bool transform;