summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/Qt5GuiConfigExtras.cmake.in2
-rw-r--r--src/gui/image/qpixmap_win.cpp160
-rw-r--r--src/gui/kernel/qsurface.cpp6
-rw-r--r--src/gui/opengl/qopenglframebufferobject.cpp11
-rw-r--r--src/gui/opengl/qopenglfunctions.cpp8
-rw-r--r--src/gui/opengl/qopengltexture.cpp36
-rw-r--r--src/gui/opengl/qopengltextureglyphcache.cpp4
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp7
8 files changed, 142 insertions, 92 deletions
diff --git a/src/gui/Qt5GuiConfigExtras.cmake.in b/src/gui/Qt5GuiConfigExtras.cmake.in
index f9c327f938..d734e56d23 100644
--- a/src/gui/Qt5GuiConfigExtras.cmake.in
+++ b/src/gui/Qt5GuiConfigExtras.cmake.in
@@ -107,7 +107,7 @@ macro(_qt5gui_find_extra_libs Name Libs LibDir IncDirs)
set(Qt5Gui_${_cmake_lib_name}_LIBRARY "${Qt5Gui_${_cmake_lib_name}_LIBRARY}/${_lib}")
!!ENDIF
if (WIN32 AND NOT Qt5Gui_${_cmake_lib_name}_LIBRARY)
- # The above find_library call doesn't work for finding
+ # The above find_library call doesn\'t work for finding
# libraries in Windows SDK paths outside of the proper
# environment. Just add the library name to the result
# variable instead.
diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp
index 93efe2e696..6cbb6fdb69 100644
--- a/src/gui/image/qpixmap_win.cpp
+++ b/src/gui/image/qpixmap_win.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -133,6 +133,68 @@ int qt_wince_GetDIBits(HDC /*hdc*/ , HBITMAP hSourceBitmap, uint, uint, LPVOID l
}
#endif
+static inline void initBitMapInfoHeader(int width, int height, bool topToBottom, BITMAPINFOHEADER *bih)
+{
+ memset(bih, 0, sizeof(BITMAPINFOHEADER));
+ bih->biSize = sizeof(BITMAPINFOHEADER);
+ bih->biWidth = width;
+ bih->biHeight = topToBottom ? -height : height;
+ bih->biPlanes = 1;
+ bih->biBitCount = 32;
+ bih->biCompression = BI_RGB;
+ bih->biSizeImage = width * height * 4;
+}
+
+static inline void initBitMapInfo(int width, int height, bool topToBottom, BITMAPINFO *bmi)
+{
+ initBitMapInfoHeader(width, height, topToBottom, &bmi->bmiHeader);
+ memset(bmi->bmiColors, 0, sizeof(RGBQUAD));
+}
+
+static inline uchar *getDiBits(HDC hdc, HBITMAP bitmap, int width, int height, bool topToBottom = true)
+{
+ BITMAPINFO bmi;
+ initBitMapInfo(width, height, topToBottom, &bmi);
+ uchar *result = new uchar[bmi.bmiHeader.biSizeImage];
+ if (!GetDIBits(hdc, bitmap, 0, height, result, &bmi, DIB_RGB_COLORS)) {
+ delete [] result;
+ qErrnoWarning("%s: GetDIBits() failed to get bitmap bits.", __FUNCTION__);
+ return 0;
+ }
+ return result;
+}
+
+static inline void copyImageDataCreateAlpha(const uchar *data, QImage *target)
+{
+ const uint mask = target->format() == QImage::Format_RGB32 ? 0xff000000 : 0;
+ const int height = target->height();
+ const int width = target->width();
+ const int bytesPerLine = width * int(sizeof(QRgb));
+ for (int y = 0; y < height; ++y) {
+ QRgb *dest = reinterpret_cast<QRgb *>(target->scanLine(y));
+ const QRgb *src = reinterpret_cast<const QRgb *>(data + y * bytesPerLine);
+ for (int x = 0; x < width; ++x) {
+ const uint pixel = src[x];
+ if ((pixel & 0xff000000) == 0 && (pixel & 0x00ffffff) != 0)
+ dest[x] = pixel | 0xff000000;
+ else
+ dest[x] = pixel | mask;
+ }
+ }
+}
+
+static inline void copyImageData(const uchar *data, QImage *target)
+{
+ const int height = target->height();
+ const int bytesPerLine = target->bytesPerLine();
+ for (int y = 0; y < height; ++y) {
+ void *dest = static_cast<void *>(target->scanLine(y));
+ const void *src = data + y * bytesPerLine;
+ memcpy(dest, src, bytesPerLine);
+ }
+
+}
+
enum HBitmapFormat
{
HBitmapNoAlpha,
@@ -176,14 +238,7 @@ Q_GUI_EXPORT HBITMAP qt_pixmapToWinHBITMAP(const QPixmap &p, int hbitmapFormat =
// Define the header
BITMAPINFO bmi;
- memset(&bmi, 0, sizeof(bmi));
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biWidth = w;
- bmi.bmiHeader.biHeight = -h;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = 32;
- bmi.bmiHeader.biCompression = BI_RGB;
- bmi.bmiHeader.biSizeImage = w * h * 4;
+ initBitMapInfo(w, h, true, &bmi);
// Create the pixmap
uchar *pixels = 0;
@@ -227,31 +282,16 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat =
const int w = bitmap_info.bmWidth;
const int h = bitmap_info.bmHeight;
- BITMAPINFO bmi;
- memset(&bmi, 0, sizeof(bmi));
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biWidth = w;
- bmi.bmiHeader.biHeight = -h;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = 32;
- bmi.bmiHeader.biCompression = BI_RGB;
- bmi.bmiHeader.biSizeImage = w * h * 4;
-
// Get bitmap bits
- QScopedArrayPointer<uchar> data(new uchar[bmi.bmiHeader.biSizeImage]);
HDC display_dc = GetDC(0);
- if (!GetDIBits(display_dc, bitmap, 0, h, data.data(), &bmi, DIB_RGB_COLORS)) {
+ QScopedArrayPointer<uchar> data(getDiBits(display_dc, bitmap, w, h, true));
+ if (data.isNull()) {
ReleaseDC(0, display_dc);
- qWarning("%s, failed to get bitmap bits", __FUNCTION__);
return QPixmap();
}
- QImage::Format imageFormat = QImage::Format_ARGB32_Premultiplied;
- uint mask = 0;
- if (hbitmapFormat == HBitmapNoAlpha) {
- imageFormat = QImage::Format_RGB32;
- mask = 0xff000000;
- }
+ const QImage::Format imageFormat = hbitmapFormat == HBitmapNoAlpha ?
+ QImage::Format_RGB32 : QImage::Format_ARGB32_Premultiplied;
// Create image and copy data into image.
QImage image(w, h, imageFormat);
@@ -260,18 +300,7 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat =
qWarning("%s, failed create image of %dx%d", __FUNCTION__, w, h);
return QPixmap();
}
- const int bytes_per_line = w * sizeof(QRgb);
- for (int y = 0; y < h; ++y) {
- QRgb *dest = (QRgb *) image.scanLine(y);
- const QRgb *src = (const QRgb *) (data.data() + y * bytes_per_line);
- for (int x = 0; x < w; ++x) {
- const uint pixel = src[x];
- if ((pixel & 0xff000000) == 0 && (pixel & 0x00ffffff) != 0)
- dest[x] = pixel | 0xff000000;
- else
- dest[x] = pixel | mask;
- }
- }
+ copyImageDataCreateAlpha(data.data(), &image);
ReleaseDC(0, display_dc);
return QPixmap::fromImage(image);
}
@@ -307,32 +336,25 @@ Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &p)
Q_GUI_EXPORT QImage qt_imageFromWinHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h)
{
- BITMAPINFO bmi;
- memset(&bmi, 0, sizeof(bmi));
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biWidth = w;
- bmi.bmiHeader.biHeight = -h;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = 32;
- bmi.bmiHeader.biCompression = BI_RGB;
- bmi.bmiHeader.biSizeImage = w * h * 4;
-
QImage image(w, h, QImage::Format_ARGB32_Premultiplied);
if (image.isNull())
return image;
+ QScopedArrayPointer<uchar> data(getDiBits(hdc, bitmap, w, h, true));
+ if (data.isNull())
+ return QImage();
+ copyImageDataCreateAlpha(data.data(), &image);
+ return image;
+}
- // Get bitmap bits
- QScopedArrayPointer<uchar> data(new uchar [bmi.bmiHeader.biSizeImage]);
- if (!GetDIBits(hdc, bitmap, 0, h, data.data(), &bmi, DIB_RGB_COLORS)) {
- qErrnoWarning("%s: failed to get bitmap bits", __FUNCTION__);
+static QImage qt_imageFromWinIconHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h)
+{
+ QImage image(w, h, QImage::Format_ARGB32_Premultiplied);
+ if (image.isNull())
+ return image;
+ QScopedArrayPointer<uchar> data(getDiBits(hdc, bitmap, w, h, true));
+ if (data.isNull())
return QImage();
- }
- // Create image and copy data into image.
- for (int y = 0; y < h; ++y) {
- void *dest = (void *) image.scanLine(y);
- void *src = data.data() + y * image.bytesPerLine();
- memcpy(dest, src, image.bytesPerLine());
- }
+ copyImageData(data.data(), &image);
return image;
}
@@ -354,23 +376,13 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon)
const int h = iconinfo.yHotspot * 2;
BITMAPINFOHEADER bitmapInfo;
- bitmapInfo.biSize = sizeof(BITMAPINFOHEADER);
- bitmapInfo.biWidth = w;
- bitmapInfo.biHeight = h;
- bitmapInfo.biPlanes = 1;
- bitmapInfo.biBitCount = 32;
- bitmapInfo.biCompression = BI_RGB;
- bitmapInfo.biSizeImage = 0;
- bitmapInfo.biXPelsPerMeter = 0;
- bitmapInfo.biYPelsPerMeter = 0;
- bitmapInfo.biClrUsed = 0;
- bitmapInfo.biClrImportant = 0;
+ initBitMapInfoHeader(w, h, false, &bitmapInfo);
DWORD* bits;
HBITMAP winBitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bitmapInfo, DIB_RGB_COLORS, (VOID**)&bits, NULL, 0);
HGDIOBJ oldhdc = (HBITMAP)SelectObject(hdc, winBitmap);
DrawIconEx( hdc, 0, 0, icon, iconinfo.xHotspot * 2, iconinfo.yHotspot * 2, 0, 0, DI_NORMAL);
- QImage image = qt_imageFromWinHBITMAP(hdc, winBitmap, w, h);
+ QImage image = qt_imageFromWinIconHBITMAP(hdc, winBitmap, w, h);
for (int y = 0 ; y < h && !foundAlpha ; y++) {
const QRgb *scanLine= reinterpret_cast<const QRgb *>(image.scanLine(y));
@@ -384,7 +396,7 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon)
if (!foundAlpha) {
//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_imageFromWinHBITMAP(hdc, winBitmap, w, h);
+ const QImage mask = qt_imageFromWinIconHBITMAP(hdc, winBitmap, w, h);
for (int y = 0 ; y < h ; y++){
QRgb *scanlineImage = reinterpret_cast<QRgb *>(image.scanLine(y));
diff --git a/src/gui/kernel/qsurface.cpp b/src/gui/kernel/qsurface.cpp
index a27bdaccde..e7fd2f79a4 100644
--- a/src/gui/kernel/qsurface.cpp
+++ b/src/gui/kernel/qsurface.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qsurface.h"
+#include "qopenglcontext.h"
QT_BEGIN_NAMESPACE
@@ -130,6 +131,11 @@ QSurface::QSurface(SurfaceClass type)
*/
QSurface::~QSurface()
{
+#ifndef QT_NO_OPENGL
+ QOpenGLContext *context = QOpenGLContext::currentContext();
+ if (context && context->surface() == this)
+ context->doneCurrent();
+#endif
}
/*!
diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp
index af0abb5ea7..231e475111 100644
--- a/src/gui/opengl/qopenglframebufferobject.cpp
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -453,10 +453,19 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
if (samples == 0) {
initTexture(texture_target, internal_format, size, mipmap);
} else {
+ GLenum storageFormat = internal_format;
+#ifdef GL_RGBA8_OES
+ // Correct the internal format used by the render buffer when using ANGLE
+ if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES && internal_format == GL_RGBA
+ && strstr((const char *)funcs.glGetString(GL_RENDERER), "ANGLE") != 0) {
+ storageFormat = GL_RGBA8_OES;
+ }
+#endif
+
mipmap = false;
funcs.glGenRenderbuffers(1, &color_buffer);
funcs.glBindRenderbuffer(GL_RENDERBUFFER, color_buffer);
- funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, internal_format, size.width(), size.height());
+ funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storageFormat, size.width(), size.height());
funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER, color_buffer);
QT_CHECK_GLERROR();
diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp
index bcb38ce7f1..a0d1775040 100644
--- a/src/gui/opengl/qopenglfunctions.cpp
+++ b/src/gui/opengl/qopenglfunctions.cpp
@@ -381,6 +381,10 @@ static int qt_gl_resolve_extensions()
// TODO: Consider matching GL_APPLE_texture_format_BGRA8888 as well, but it needs testing.
if (extensionMatcher.match("GL_IMG_texture_format_BGRA8888") || extensionMatcher.match("GL_EXT_texture_format_BGRA8888"))
extensions |= QOpenGLExtensions::BGRATextureFormat;
+ if (extensionMatcher.match("GL_ANGLE_framebuffer_blit"))
+ extensions |= QOpenGLExtensions::FramebufferBlit;
+ if (extensionMatcher.match("GL_ANGLE_framebuffer_multisample"))
+ extensions |= QOpenGLExtensions::FramebufferMultisample;
} else {
extensions |= QOpenGLExtensions::ElementIndexUint | QOpenGLExtensions::MapBuffer;
@@ -3150,7 +3154,7 @@ static void QOPENGLF_APIENTRY qopenglfResolveBlitFramebuffer(GLint srcX0, GLint
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter)
{
- RESOLVE_FUNC_VOID(ResolveEXT, BlitFramebuffer)
+ RESOLVE_FUNC_VOID_WITH_ALTERNATE(ResolveEXT, BlitFramebuffer, BlitFramebufferANGLE)
(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
}
@@ -3158,7 +3162,7 @@ static void QOPENGLF_APIENTRY qopenglfResolveRenderbufferStorageMultisample(GLen
GLenum internalFormat,
GLsizei width, GLsizei height)
{
- RESOLVE_FUNC_VOID(ResolveEXT, RenderbufferStorageMultisample)
+ RESOLVE_FUNC_VOID_WITH_ALTERNATE(ResolveEXT, RenderbufferStorageMultisample, RenderbufferStorageMultisampleANGLE)
(target, samples, internalFormat, width, height);
}
diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp
index 9a0ecee3f6..b64956c65c 100644
--- a/src/gui/opengl/qopengltexture.cpp
+++ b/src/gui/opengl/qopengltexture.cpp
@@ -2447,7 +2447,9 @@ bool QOpenGLTexture::isFixedSamplePositions() const
void QOpenGLTexture::allocateStorage()
{
Q_D(QOpenGLTexture);
- d->allocateStorage();
+ if (d->create()) {
+ d->allocateStorage();
+ }
}
/*!
@@ -2805,33 +2807,49 @@ bool QOpenGLTexture::hasFeature(Feature feature)
if (!ctx->isOpenGLES()) {
switch (feature) {
case ImmutableMultisampleStorage:
+ supported = f.version() >= qMakePair(4, 3)
+ || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_storage_multisample"));
+ break;
+
case TextureBuffer:
+ supported = f.version() >= qMakePair(4, 3)
+ || (ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_buffer_object"))
+ && ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_buffer_range")));
+ break;
+
case StencilTexturing:
- supported = f.version() >= qMakePair(4, 3);
+ supported = f.version() >= qMakePair(4, 3)
+ || ctx->hasExtension(QByteArrayLiteral("GL_ARB_stencil_texturing"));
break;
case ImmutableStorage:
- supported = f.version() >= qMakePair(4, 2);
+ supported = f.version() >= qMakePair(4, 2)
+ || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_storage"));
break;
case TextureCubeMapArrays:
- supported = f.version() >= qMakePair(4, 0);
+ supported = f.version() >= qMakePair(4, 0)
+ || ctx->hasExtension(QByteArrayLiteral("ARB_texture_cube_map_array"));
break;
case Swizzle:
- supported = f.version() >= qMakePair(3, 3);
+ supported = f.version() >= qMakePair(3, 3)
+ || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_swizzle"));
break;
case TextureMultisample:
- supported = f.version() >= qMakePair(3, 2);
+ supported = f.version() >= qMakePair(3, 2)
+ || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_multisample"));
break;
case TextureArrays:
- supported = f.version() >= qMakePair(3, 0);
+ supported = f.version() >= qMakePair(3, 0)
+ || ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_array"));
break;
case TextureRectangle:
- supported = f.version() >= qMakePair(2, 1);
+ supported = f.version() >= qMakePair(2, 1)
+ || ctx->hasExtension(QByteArrayLiteral("ARB_texture_rectangle"));
break;
case Texture3D:
@@ -3162,7 +3180,7 @@ void QOpenGLTexture::setDepthStencilMode(QOpenGLTexture::DepthStencilMode mode)
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
if (!d->features.testFlag(StencilTexturing)) {
- qWarning("QOpenGLTexture::setDepthStencilMode() requires OpenGL >= 4.3");
+ qWarning("QOpenGLTexture::setDepthStencilMode() requires OpenGL >= 4.3 or GL_ARB_stencil_texturing");
return;
}
d->depthStencilMode = mode;
diff --git a/src/gui/opengl/qopengltextureglyphcache.cpp b/src/gui/opengl/qopengltextureglyphcache.cpp
index f721d5cb8c..0610ab60ed 100644
--- a/src/gui/opengl/qopengltextureglyphcache.cpp
+++ b/src/gui/opengl/qopengltextureglyphcache.cpp
@@ -87,6 +87,7 @@ QOpenGLTextureGlyphCache::~QOpenGLTextureGlyphCache()
#ifdef QT_GL_TEXTURE_GLYPH_CACHE_DEBUG
qDebug(" -> ~QOpenGLTextureGlyphCache() %p.", this);
#endif
+ clear();
}
static inline bool isCoreProfile()
@@ -447,7 +448,8 @@ int QOpenGLTextureGlyphCache::maxTextureHeight() const
void QOpenGLTextureGlyphCache::clear()
{
- m_textureResource->free();
+ if (m_textureResource)
+ m_textureResource->free();
m_textureResource = 0;
m_w = 0;
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index ce8c1d1ca7..a004428fab 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -2603,7 +2603,7 @@ void QRasterPaintEngine::alphaPenBlt(const void* src, int bpl, int depth, int rx
return;
}
}
- } else if (d->deviceDepth == 32 && (depth == 8 || depth == 32)) {
+ } else if (d->deviceDepth == 32 && ((depth == 8 && s->penData.alphamapBlit) || (depth == 32 && s->penData.alphaRGBBlit))) {
// (A)RGB Alpha mask where the alpha component is not used.
if (!clip) {
int nx = qMax(0, rx);
@@ -2626,13 +2626,12 @@ void QRasterPaintEngine::alphaPenBlt(const void* src, int bpl, int depth, int rx
rx = nx;
ry = ny;
}
- if (depth == 8 && s->penData.alphamapBlit) {
+ if (depth == 8)
s->penData.alphamapBlit(rb, rx, ry, s->penData.solid.color,
scanline, w, h, bpl, clip);
- } else if (depth == 32 && s->penData.alphaRGBBlit) {
+ else if (depth == 32)
s->penData.alphaRGBBlit(rb, rx, ry, s->penData.solid.color,
(const uint *) scanline, w, h, bpl / 4, clip);
- }
return;
}
}