diff options
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/Qt5GuiConfigExtras.cmake.in | 2 | ||||
-rw-r--r-- | src/gui/image/qpixmap_win.cpp | 160 | ||||
-rw-r--r-- | src/gui/kernel/qsurface.cpp | 6 | ||||
-rw-r--r-- | src/gui/opengl/qopenglframebufferobject.cpp | 11 | ||||
-rw-r--r-- | src/gui/opengl/qopenglfunctions.cpp | 8 | ||||
-rw-r--r-- | src/gui/opengl/qopengltexture.cpp | 36 | ||||
-rw-r--r-- | src/gui/opengl/qopengltextureglyphcache.cpp | 4 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine_raster.cpp | 7 |
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; } } |