summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-09-21 08:50:26 +0200
committerLiang Qi <liang.qi@qt.io>2016-09-21 09:11:02 +0200
commiteaec2b664aa2c3cbca13b425901888468a4652a1 (patch)
tree93dbd19f3b538baa81dec6c04e5258161f7d8cfb /src/gui
parent278e557ceacbe7de728987a4a5365f78e56d76b1 (diff)
parent31c251765db45a068f1268027e5dd600151af1e5 (diff)
Merge remote-tracking branch 'origin/5.8' into dev
Conflicts: src/gui/painting/qcoregraphics.mm src/network/access/qnetworkrequest.h src/plugins/platforms/cocoa/qcocoahelpers.mm Change-Id: I81266414c06ea2edf63cbc7e93a86bd5d66a31a5
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/image/qimage_conversions.cpp12
-rw-r--r--src/gui/image/qimagereader.cpp2
-rw-r--r--src/gui/kernel/qevent.h2
-rw-r--r--src/gui/kernel/qkeysequence.cpp10
-rw-r--r--src/gui/kernel/qscreen.cpp4
-rw-r--r--src/gui/painting/painting.pri5
-rw-r--r--src/gui/painting/qcoregraphics.mm566
-rw-r--r--src/gui/painting/qcoregraphics_p.h121
-rw-r--r--src/gui/painting/qdrawhelper.cpp683
-rw-r--r--src/gui/painting/qdrawhelper_avx2.cpp305
-rw-r--r--src/gui/painting/qpaintengine_p.h5
-rw-r--r--src/gui/text/qfontdatabase.cpp2
-rw-r--r--src/gui/text/qtextodfwriter.cpp2
13 files changed, 1183 insertions, 536 deletions
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp
index 442492d198..9bd098b7b1 100644
--- a/src/gui/image/qimage_conversions.cpp
+++ b/src/gui/image/qimage_conversions.cpp
@@ -134,7 +134,8 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio
Q_ASSERT(dest->format > QImage::Format_Indexed8);
Q_ASSERT(src->format > QImage::Format_Indexed8);
const int buffer_size = 2048;
- uint buffer[buffer_size];
+ uint buf[buffer_size];
+ uint *buffer = buf;
const QPixelLayout *srcLayout = &qPixelLayouts[src->format];
const QPixelLayout *destLayout = &qPixelLayouts[dest->format];
const uchar *srcData = src->data;
@@ -169,11 +170,16 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio
int x = 0;
while (x < src->width) {
dither.x = x;
- int l = qMin(src->width - x, buffer_size);
+ int l = src->width - x;
+ if (destLayout->bpp == QPixelLayout::BPP32)
+ buffer = reinterpret_cast<uint *>(destData) + x;
+ else
+ l = qMin(l, buffer_size);
const uint *ptr = fetch(buffer, srcData, x, l);
ptr = convertToARGB32PM(buffer, ptr, l, 0, ditherPtr);
ptr = convertFromARGB32PM(buffer, ptr, l, 0, ditherPtr);
- store(destData, ptr, x, l);
+ if (ptr != reinterpret_cast<uint *>(destData))
+ store(destData, ptr, x, l);
x += l;
}
srcData += src->bytes_per_line;
diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index 0320d032b0..4390e46fde 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -569,7 +569,7 @@ bool QImageReaderPrivate::initHandler()
do {
file->setFileName(fileName + QLatin1Char('.')
- + QString::fromLatin1(extensions.at(currentExtension++).constData()));
+ + QLatin1String(extensions.at(currentExtension++).constData()));
file->open(QIODevice::ReadOnly);
} while (!file->isOpen() && currentExtension < extensions.size());
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index 93374b2299..a062331bd8 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -52,7 +52,7 @@
#include <QtCore/qvector.h>
#include <QtCore/qset.h> // ### Qt 6: Remove
#include <QtCore/qurl.h>
-#include <QtCore/qfile.h> // ### Qt 6: Replace by <qiodevice.h> and forward declare QFile
+#include <QtCore/qfile.h> // ### Qt 6: Replace by <QtCore/qiodevice.h> and forward declare QFile
#include <QtGui/qvector2d.h>
#include <QtGui/qtouchdevice.h> // ### Qt 6: Replace by forward declaration
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index 9a75f4bc83..d59bd63caf 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -1211,9 +1211,13 @@ QString QKeySequence::encodeString(int key)
static inline void addKey(QString &str, const QString &theKey, QKeySequence::SequenceFormat format)
{
- if (!str.isEmpty())
- str += (format == QKeySequence::NativeText) ? QCoreApplication::translate("QShortcut", "+")
- : QString::fromLatin1("+");
+ if (!str.isEmpty()) {
+ if (format == QKeySequence::NativeText)
+ str += QCoreApplication::translate("QShortcut", "+");
+ else
+ str += QLatin1Char('+');
+ }
+
str += theKey;
}
diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp
index bc4a25a65f..1dd8fb5e67 100644
--- a/src/gui/kernel/qscreen.cpp
+++ b/src/gui/kernel/qscreen.cpp
@@ -667,6 +667,10 @@ void QScreenPrivate::updatePrimaryOrientation()
that are not part of the application, window system frames, and so
on.
+ \warning Grabbing windows that are not part of the application is
+ not supported on systems such as iOS, where sandboxing/security
+ prevents reading pixels of windows not owned by the application.
+
The grabWindow() function grabs pixels from the screen, not from
the window, i.e. if there is another window partially or entirely
over the one you grab, you get pixels from the overlying window,
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index c47060a2ad..a61865a0b6 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -99,6 +99,11 @@ SOURCES += \
painting/qplatformbackingstore.cpp \
painting/qpathsimplifier.cpp
+darwin {
+ HEADERS += painting/qcoregraphics_p.h
+ SOURCES += painting/qcoregraphics.mm
+}
+
SSE2_SOURCES += painting/qdrawhelper_sse2.cpp
SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp
SSE4_1_SOURCES += painting/qdrawhelper_sse4.cpp \
diff --git a/src/gui/painting/qcoregraphics.mm b/src/gui/painting/qcoregraphics.mm
new file mode 100644
index 0000000000..a29d60ca6e
--- /dev/null
+++ b/src/gui/painting/qcoregraphics.mm
@@ -0,0 +1,566 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcoregraphics_p.h"
+
+#include <private/qcore_mac_p.h>
+#include <qpa/qplatformpixmap.h>
+#include <QtGui/qicon.h>
+#include <QtGui/private/qpaintengine_p.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qoperatingsystemversion.h>
+
+QT_BEGIN_NAMESPACE
+
+// ---------------------- Images ----------------------
+
+CGImageRef qt_mac_toCGImage(const QImage &inImage)
+{
+ CGImageRef cgImage = inImage.toCGImage();
+ if (cgImage)
+ return cgImage;
+
+ // Convert image data to a known-good format if the fast conversion fails.
+ return inImage.convertToFormat(QImage::Format_ARGB32_Premultiplied).toCGImage();
+}
+
+CGImageRef qt_mac_toCGImageMask(const QImage &image)
+{
+ static const auto deleter = [](void *image, const void *, size_t) { delete static_cast<QImage *>(image); };
+ QCFType<CGDataProviderRef> dataProvider =
+ CGDataProviderCreateWithData(new QImage(image), image.bits(),
+ image.byteCount(), deleter);
+
+ return CGImageMaskCreate(image.width(), image.height(), 8, image.depth(),
+ image.bytesPerLine(), dataProvider, NULL, false);
+}
+
+OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage)
+{
+ // Verbatim copy if HIViewDrawCGImage (as shown on Carbon-Dev)
+ OSStatus err = noErr;
+
+#ifdef Q_OS_MACOS
+ require_action(inContext != NULL, InvalidContext, err = paramErr);
+ require_action(inBounds != NULL, InvalidBounds, err = paramErr);
+ require_action(inImage != NULL, InvalidImage, err = paramErr);
+#endif
+
+ CGContextSaveGState( inContext );
+ CGContextTranslateCTM (inContext, 0, inBounds->origin.y + CGRectGetMaxY(*inBounds));
+ CGContextScaleCTM(inContext, 1, -1);
+
+ CGContextDrawImage(inContext, *inBounds, inImage);
+
+ CGContextRestoreGState(inContext);
+
+#ifdef Q_OS_MACOS
+InvalidImage:
+InvalidBounds:
+InvalidContext:
+#endif
+ return err;
+}
+
+QImage qt_mac_toQImage(CGImageRef image)
+{
+ const size_t w = CGImageGetWidth(image),
+ h = CGImageGetHeight(image);
+ QImage ret(w, h, QImage::Format_ARGB32_Premultiplied);
+ ret.fill(Qt::transparent);
+ CGRect rect = CGRectMake(0, 0, w, h);
+ QMacCGContext ctx(&ret);
+ qt_mac_drawCGImage(ctx, &rect, image);
+ return ret;
+}
+
+#ifdef Q_OS_MACOS
+
+QT_END_NAMESPACE
+
+@interface NSGraphicsContext (QtAdditions)
+
++ (NSGraphicsContext *)qt_graphicsContextWithCGContext:(CGContextRef)graphicsPort flipped:(BOOL)initialFlippedState;
+
+@end
+
+@implementation NSGraphicsContext (QtAdditions)
+
++ (NSGraphicsContext *)qt_graphicsContextWithCGContext:(CGContextRef)graphicsPort flipped:(BOOL)initialFlippedState
+{
+#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_10, __IPHONE_NA)
+ if (QT_PREPEND_NAMESPACE(QOperatingSystemVersion::current()) >= QT_PREPEND_NAMESPACE(QOperatingSystemVersion::OSXYosemite))
+ return [self graphicsContextWithCGContext:graphicsPort flipped:initialFlippedState];
+#endif
+ return [self graphicsContextWithGraphicsPort:graphicsPort flipped:initialFlippedState];
+}
+
+@end
+
+QT_BEGIN_NAMESPACE
+
+static NSImage *qt_mac_cgimage_to_nsimage(CGImageRef image)
+{
+ NSImage *newImage = [[NSImage alloc] initWithCGImage:image size:NSZeroSize];
+ return newImage;
+}
+
+NSImage *qt_mac_create_nsimage(const QPixmap &pm)
+{
+ if (pm.isNull())
+ return 0;
+ QImage image = pm.toImage();
+ CGImageRef cgImage = qt_mac_toCGImage(image);
+ NSImage *nsImage = qt_mac_cgimage_to_nsimage(cgImage);
+ CGImageRelease(cgImage);
+ return nsImage;
+}
+
+NSImage *qt_mac_create_nsimage(const QIcon &icon)
+{
+ if (icon.isNull())
+ return nil;
+
+ NSImage *nsImage = [[NSImage alloc] init];
+ foreach (QSize size, icon.availableSizes()) {
+ QPixmap pm = icon.pixmap(size);
+ QImage image = pm.toImage();
+ CGImageRef cgImage = qt_mac_toCGImage(image);
+ NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage];
+ [nsImage addRepresentation:imageRep];
+ [imageRep release];
+ CGImageRelease(cgImage);
+ }
+ return nsImage;
+}
+
+QPixmap qt_mac_toQPixmap(const NSImage *image, const QSizeF &size)
+{
+ const NSSize pixmapSize = NSMakeSize(size.width(), size.height());
+ QPixmap pixmap(pixmapSize.width, pixmapSize.height);
+ pixmap.fill(Qt::transparent);
+ [image setSize:pixmapSize];
+ const NSRect iconRect = NSMakeRect(0, 0, pixmapSize.width, pixmapSize.height);
+ QMacCGContext ctx(&pixmap);
+ if (!ctx)
+ return QPixmap();
+ NSGraphicsContext *gc = [NSGraphicsContext qt_graphicsContextWithCGContext:ctx flipped:YES];
+ if (!gc)
+ return QPixmap();
+ [NSGraphicsContext saveGraphicsState];
+ [NSGraphicsContext setCurrentContext:gc];
+ [image drawInRect:iconRect fromRect:iconRect operation:NSCompositeSourceOver fraction:1.0 respectFlipped:YES hints:nil];
+ [NSGraphicsContext restoreGraphicsState];
+ return pixmap;
+}
+
+#endif // Q_OS_MACOS
+
+// ---------------------- Colors and Brushes ----------------------
+
+QColor qt_mac_toQColor(CGColorRef color)
+{
+ QColor qtColor;
+ CGColorSpaceModel model = CGColorSpaceGetModel(CGColorGetColorSpace(color));
+ const CGFloat *components = CGColorGetComponents(color);
+ if (model == kCGColorSpaceModelRGB) {
+ qtColor.setRgbF(components[0], components[1], components[2], components[3]);
+ } else if (model == kCGColorSpaceModelCMYK) {
+ qtColor.setCmykF(components[0], components[1], components[2], components[3]);
+ } else if (model == kCGColorSpaceModelMonochrome) {
+ qtColor.setRgbF(components[0], components[0], components[0], components[1]);
+ } else {
+ // Colorspace we can't deal with.
+ qWarning("Qt: qt_mac_toQColor: cannot convert from colorspace model: %d", model);
+ Q_ASSERT(false);
+ }
+ return qtColor;
+}
+
+#ifdef Q_OS_MACOS
+QColor qt_mac_toQColor(const NSColor *color)
+{
+ QColor qtColor;
+ NSString *colorSpace = [color colorSpaceName];
+ if (colorSpace == NSDeviceCMYKColorSpace) {
+ CGFloat cyan, magenta, yellow, black, alpha;
+ [color getCyan:&cyan magenta:&magenta yellow:&yellow black:&black alpha:&alpha];
+ qtColor.setCmykF(cyan, magenta, yellow, black, alpha);
+ } else {
+ NSColor *tmpColor;
+ tmpColor = [color colorUsingColorSpaceName:NSDeviceRGBColorSpace];
+ CGFloat red, green, blue, alpha;
+ [tmpColor getRed:&red green:&green blue:&blue alpha:&alpha];
+ qtColor.setRgbF(red, green, blue, alpha);
+ }
+ return qtColor;
+}
+#endif
+
+QBrush qt_mac_toQBrush(CGColorRef color)
+{
+ QBrush qtBrush;
+ CGColorSpaceModel model = CGColorSpaceGetModel(CGColorGetColorSpace(color));
+ if (model == kCGColorSpaceModelPattern) {
+ // Colorspace we can't deal with; the color is drawn directly using a callback.
+ qWarning("Qt: qt_mac_toQBrush: cannot convert from colorspace model: %d", model);
+ Q_ASSERT(false);
+ } else {
+ qtBrush.setStyle(Qt::SolidPattern);
+ qtBrush.setColor(qt_mac_toQColor(color));
+ }
+ return qtBrush;
+}
+
+#ifdef Q_OS_MACOS
+static bool qt_mac_isSystemColorOrInstance(const NSColor *color, NSString *colorNameComponent, NSString *className)
+{
+ // We specifically do not want isKindOfClass: here
+ if ([color.className isEqualToString:className]) // NSPatternColorSpace
+ return true;
+ if ([color.catalogNameComponent isEqualToString:@"System"] &&
+ [color.colorNameComponent isEqualToString:colorNameComponent] &&
+ [color.colorSpaceName isEqualToString:NSNamedColorSpace])
+ return true;
+ return false;
+}
+
+QBrush qt_mac_toQBrush(const NSColor *color, QPalette::ColorGroup colorGroup)
+{
+ QBrush qtBrush;
+
+ // QTBUG-49773: This calls NSDrawMenuItemBackground to render a 1 by n gradient; could use HITheme
+ if ([color.className isEqualToString:@"NSMenuItemHighlightColor"]) {
+ qWarning("Qt: qt_mac_toQBrush: cannot convert from NSMenuItemHighlightColor");
+ return qtBrush;
+ }
+
+ // Not a catalog color or a manifestation of System.windowBackgroundColor;
+ // only retrieved from NSWindow.backgroundColor directly
+ if ([color.className isEqualToString:@"NSMetalPatternColor"]) {
+ // NSTexturedBackgroundWindowMask, could theoretically handle this without private API by
+ // creating a window with the appropriate properties and then calling NSWindow.backgroundColor.patternImage,
+ // which returns a texture sized 1 by (window height, including frame), backed by a CGPattern
+ // which follows the window key state... probably need to allow QBrush to store a function pointer
+ // like CGPattern does
+ qWarning("Qt: qt_mac_toQBrush: cannot convert from NSMetalPatternColor");
+ return qtBrush;
+ }
+
+ // No public API to get these colors/stops;
+ // both accurately obtained through runtime object inspection on OS X 10.11
+ // (the NSColor object has NSGradient i-vars for both color groups)
+ if (qt_mac_isSystemColorOrInstance(color, @"_sourceListBackgroundColor", @"NSSourceListBackgroundColor")) {
+ QLinearGradient gradient;
+ if (colorGroup == QPalette::Active) {
+ gradient.setColorAt(0, QColor(233, 237, 242));
+ gradient.setColorAt(0.5, QColor(225, 229, 235));
+ gradient.setColorAt(1, QColor(209, 216, 224));
+ } else {
+ gradient.setColorAt(0, QColor(248, 248, 248));
+ gradient.setColorAt(0.5, QColor(240, 240, 240));
+ gradient.setColorAt(1, QColor(235, 235, 235));
+ }
+ return QBrush(gradient);
+ }
+
+ // A couple colors are special... they are actually instances of NSGradientPatternColor, which
+ // override set/setFill/setStroke to instead initialize an internal color
+ // ([NSColor colorWithCalibratedWhite:0.909804 alpha:1.000000]) while still returning the
+ // ruled lines pattern image (from OS X 10.4) to the user from -[NSColor patternImage]
+ // (and providing no public API to get the underlying color without this insanity)
+ if (qt_mac_isSystemColorOrInstance(color, @"controlColor", @"NSGradientPatternColor") ||
+ qt_mac_isSystemColorOrInstance(color, @"windowBackgroundColor", @"NSGradientPatternColor")) {
+ qtBrush.setStyle(Qt::SolidPattern);
+ qtBrush.setColor(qt_mac_toQColor(color.CGColor));
+ return qtBrush;
+ }
+
+ if (NSColor *patternColor = [color colorUsingColorSpaceName:NSPatternColorSpace]) {
+ NSImage *patternImage = patternColor.patternImage;
+ const QSizeF sz(patternImage.size.width, patternImage.size.height);
+ // FIXME: QBrush is not resolution independent (QTBUG-49774)
+ qtBrush.setTexture(qt_mac_toQPixmap(patternImage, sz));
+ } else {
+ qtBrush.setStyle(Qt::SolidPattern);
+ qtBrush.setColor(qt_mac_toQColor(color));
+ }
+ return qtBrush;
+}
+#endif
+
+// ---------------------- Color Management ----------------------
+
+static CGColorSpaceRef m_genericColorSpace = 0;
+static QHash<uint32_t, CGColorSpaceRef> m_displayColorSpaceHash;
+static bool m_postRoutineRegistered = false;
+
+static void qt_mac_cleanUpMacColorSpaces()
+{
+ if (m_genericColorSpace) {
+ CFRelease(m_genericColorSpace);
+ m_genericColorSpace = 0;
+ }
+ QHash<uint32_t, CGColorSpaceRef>::const_iterator it = m_displayColorSpaceHash.constBegin();
+ while (it != m_displayColorSpaceHash.constEnd()) {
+ if (it.value())
+ CFRelease(it.value());
+ ++it;
+ }
+ m_displayColorSpaceHash.clear();
+}
+
+static CGColorSpaceRef qt_mac_displayColorSpace(const QWindow *window)
+{
+ CGColorSpaceRef colorSpace = 0;
+ uint32_t displayID = 0;
+
+#ifdef Q_OS_MACOS
+ if (window == 0) {
+ displayID = CGMainDisplayID();
+ } else {
+ displayID = CGMainDisplayID();
+ /*
+ ### get correct display
+ const QRect &qrect = window->geometry();
+ CGRect rect = CGRectMake(qrect.x(), qrect.y(), qrect.width(), qrect.height());
+ CGDisplayCount throwAway;
+ CGDisplayErr dErr = CGGetDisplaysWithRect(rect, 1, &displayID, &throwAway);
+ if (dErr != kCGErrorSuccess)
+ return macDisplayColorSpace(0); // fall back on main display
+ */
+ }
+ if ((colorSpace = m_displayColorSpaceHash.value(displayID)))
+ return colorSpace;
+
+ colorSpace = CGDisplayCopyColorSpace(displayID);
+#else
+ Q_UNUSED(window);
+#endif
+
+ if (colorSpace == 0)
+ colorSpace = CGColorSpaceCreateDeviceRGB();
+
+ m_displayColorSpaceHash.insert(displayID, colorSpace);
+ if (!m_postRoutineRegistered) {
+ m_postRoutineRegistered = true;
+ qAddPostRoutine(qt_mac_cleanUpMacColorSpaces);
+ }
+ return colorSpace;
+}
+
+CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice)
+{
+ Q_UNUSED(paintDevice);
+
+ // FIXME: Move logic into each paint device once Qt has support for color spaces
+ return qt_mac_displayColorSpace(0);
+
+ // The following code seems to take care of QWidget, but in reality doesn't, as
+ // qt_mac_displayColorSpace ignores the argument and always uses the main display.
+#if 0
+ bool isWidget = (paintDevice->devType() == QInternal::Widget);
+ return qt_mac_displayColorSpace(isWidget ? static_cast<const QWidget *>(paintDevice)->window() : 0);
+#endif
+}
+
+CGColorSpaceRef qt_mac_genericColorSpace()
+{
+#if 0
+ if (!m_genericColorSpace) {
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) {
+ m_genericColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
+ } else
+ {
+ m_genericColorSpace = CGColorSpaceCreateDeviceRGB();
+ }
+ if (!m_postRoutineRegistered) {
+ m_postRoutineRegistered = true;
+ qAddPostRoutine(QCoreGraphicsPaintEngine::cleanUpMacColorSpaces);
+ }
+ }
+ return m_genericColorSpace;
+#else
+ // Just return the main display colorspace for the moment.
+ return qt_mac_displayColorSpace(0);
+#endif
+}
+
+// ---------------------- Geometry Helpers ----------------------
+
+void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform)
+{
+ CGAffineTransform old_xform = CGAffineTransformIdentity;
+ if (orig_xform) { //setup xforms
+ old_xform = CGContextGetCTM(hd);
+ CGContextConcatCTM(hd, CGAffineTransformInvert(old_xform));
+ CGContextConcatCTM(hd, *orig_xform);
+ }
+
+ //do the clipping
+ CGContextBeginPath(hd);
+ if (rgn.isEmpty()) {
+ CGContextAddRect(hd, CGRectMake(0, 0, 0, 0));
+ } else {
+ for (const QRect &r : rgn) {
+ CGRect mac_r = CGRectMake(r.x(), r.y(), r.width(), r.height());
+ CGContextAddRect(hd, mac_r);
+ }
+ }
+ CGContextClip(hd);
+
+ if (orig_xform) {//reset xforms
+ CGContextConcatCTM(hd, CGAffineTransformInvert(CGContextGetCTM(hd)));
+ CGContextConcatCTM(hd, old_xform);
+ }
+}
+
+// move to QRegion?
+void qt_mac_scale_region(QRegion *region, qreal scaleFactor)
+{
+ if (!region || !region->rectCount())
+ return;
+
+ QVector<QRect> scaledRects;
+ scaledRects.reserve(region->rectCount());
+
+ for (const QRect &rect : *region)
+ scaledRects.append(QRect(rect.topLeft() * scaleFactor, rect.size() * scaleFactor));
+
+ region->setRects(&scaledRects[0], scaledRects.count());
+}
+
+// ---------------------- QMacCGContext ----------------------
+
+QMacCGContext::QMacCGContext(QPaintDevice *paintDevice) : context(0)
+{
+ // In Qt 5, QWidget and QPixmap (and QImage) paint devices are all QImages under the hood.
+ QImage *image = 0;
+ if (paintDevice->devType() == QInternal::Image) {
+ image = static_cast<QImage *>(paintDevice);
+ } else if (paintDevice->devType() == QInternal::Pixmap) {
+
+ const QPixmap *pm = static_cast<const QPixmap*>(paintDevice);
+ QPlatformPixmap *data = const_cast<QPixmap *>(pm)->data_ptr().data();
+ if (data && data->classId() == QPlatformPixmap::RasterClass) {
+ image = data->buffer();
+ } else {
+ qDebug("QMacCGContext: Unsupported pixmap class");
+ }
+ } else if (paintDevice->devType() == QInternal::Widget) {
+ // TODO test: image = static_cast<QImage *>(static_cast<const QWidget *>(paintDevice)->backingStore()->paintDevice());
+ qDebug("QMacCGContext: not implemented: Widget class");
+ }
+
+ if (!image)
+ return; // Context type not supported.
+
+ CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(paintDevice);
+ uint flags = kCGImageAlphaPremultipliedFirst;
+ flags |= kCGBitmapByteOrder32Host;
+
+ context = CGBitmapContextCreate(image->bits(), image->width(), image->height(),
+ 8, image->bytesPerLine(), colorspace, flags);
+ CGContextTranslateCTM(context, 0, image->height());
+ CGContextScaleCTM(context, 1, -1);
+}
+
+QMacCGContext::QMacCGContext(QPainter *painter) : context(0)
+{
+ QPaintEngine *paintEngine = painter->paintEngine();
+
+ // Handle the case of QMacPrintEngine, which has an internal QCoreGraphicsPaintEngine
+ while (QPaintEngine *aggregateEngine = QPaintEnginePrivate::get(paintEngine)->aggregateEngine())
+ paintEngine = aggregateEngine;
+
+ paintEngine->syncState();
+
+ if (Qt::HANDLE handle = QPaintEnginePrivate::get(paintEngine)->nativeHandle()) {
+ context = static_cast<CGContextRef>(handle);
+ return;
+ }
+
+ int devType = painter->device()->devType();
+ if (paintEngine->type() == QPaintEngine::Raster
+ && (devType == QInternal::Widget ||
+ devType == QInternal::Pixmap ||
+ devType == QInternal::Image)) {
+
+ CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(paintEngine->paintDevice());
+ uint flags = kCGImageAlphaPremultipliedFirst;
+#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
+ flags |= kCGBitmapByteOrder32Host;
+#endif
+ const QImage *image = static_cast<const QImage *>(paintEngine->paintDevice());
+
+ context = CGBitmapContextCreate((void *)image->bits(), image->width(), image->height(),
+ 8, image->bytesPerLine(), colorspace, flags);
+
+ // Invert y axis
+ CGContextTranslateCTM(context, 0, image->height());
+ CGContextScaleCTM(context, 1, -1);
+
+ const qreal devicePixelRatio = image->devicePixelRatio();
+
+ if (devType == QInternal::Widget) {
+ // Set the clip rect which is an intersection of the system clip
+ // and the painter clip. To make matters more interesting these
+ // are in device pixels and device-independent pixels, respectively.
+ QRegion clip = painter->paintEngine()->systemClip(); // get system clip in device pixels
+ QTransform native = painter->deviceTransform(); // get device transform. dx/dy is in device pixels
+
+ if (painter->hasClipping()) {
+ QRegion r = painter->clipRegion(); // get painter clip, which is in device-independent pixels
+ qt_mac_scale_region(&r, devicePixelRatio); // scale painter clip to device pixels
+ r.translate(native.dx(), native.dy());
+ if (clip.isEmpty())
+ clip = r;
+ else
+ clip &= r;
+ }
+ qt_mac_clip_cg(context, clip, 0); // clip in device pixels
+
+ // Scale the context so that painting happens in device-independent pixels
+ CGContextScaleCTM(context, devicePixelRatio, devicePixelRatio);
+ CGContextTranslateCTM(context, native.dx() / devicePixelRatio, native.dy() / devicePixelRatio);
+ } else {
+ // Scale to paint in device-independent pixels
+ CGContextScaleCTM(context, devicePixelRatio, devicePixelRatio);
+ }
+ } else {
+ qDebug() << "QMacCGContext:: Unsupported painter devtype type" << devType;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/painting/qcoregraphics_p.h b/src/gui/painting/qcoregraphics_p.h
new file mode 100644
index 0000000000..ab2579387e
--- /dev/null
+++ b/src/gui/painting/qcoregraphics_p.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOREGRAPHICS_P_H
+#define QCOREGRAPHICS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtGui/private/qtguiglobal_p.h>
+#include <QtGui/qregion.h>
+#include <QtGui/qpalette.h>
+
+#include <CoreGraphics/CoreGraphics.h>
+#ifdef Q_OS_MACOS
+#include <AppKit/AppKit.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_OS_MACOS
+Q_GUI_EXPORT NSImage *qt_mac_create_nsimage(const QPixmap &pm);
+Q_GUI_EXPORT NSImage *qt_mac_create_nsimage(const QIcon &icon);
+Q_GUI_EXPORT QPixmap qt_mac_toQPixmap(const NSImage *image, const QSizeF &size);
+#endif
+Q_GUI_EXPORT CGImageRef qt_mac_toCGImage(const QImage &qImage);
+Q_GUI_EXPORT CGImageRef qt_mac_toCGImageMask(const QImage &qImage);
+Q_GUI_EXPORT QImage qt_mac_toQImage(CGImageRef image);
+
+Q_GUI_EXPORT OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage);
+
+Q_GUI_EXPORT CGColorSpaceRef qt_mac_genericColorSpace();
+Q_GUI_EXPORT CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice);
+
+Q_GUI_EXPORT void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform);
+
+#ifdef Q_OS_MACOS
+Q_GUI_EXPORT QColor qt_mac_toQColor(const NSColor *color);
+Q_GUI_EXPORT QBrush qt_mac_toQBrush(const NSColor *color, QPalette::ColorGroup colorGroup = QPalette::Normal);
+#endif
+Q_GUI_EXPORT QColor qt_mac_toQColor(CGColorRef color);
+Q_GUI_EXPORT QBrush qt_mac_toQBrush(CGColorRef color);
+
+class Q_GUI_EXPORT QMacCGContext
+{
+public:
+ inline QMacCGContext() { context = 0; }
+ QMacCGContext(QPaintDevice *pdev);
+ QMacCGContext(QPainter *p);
+ inline QMacCGContext(CGContextRef cg, bool takeOwnership = false) {
+ context = cg;
+ if (!takeOwnership)
+ CGContextRetain(context);
+ }
+ inline QMacCGContext(const QMacCGContext &copy) : context(0) { *this = copy; }
+ inline ~QMacCGContext() {
+ if (context)
+ CGContextRelease(context);
+ }
+ inline bool isNull() const { return context; }
+ inline operator CGContextRef() { return context; }
+ inline QMacCGContext &operator=(const QMacCGContext &copy) {
+ if (context)
+ CGContextRelease(context);
+ context = copy.context;
+ CGContextRetain(context);
+ return *this;
+ }
+ inline QMacCGContext &operator=(CGContextRef cg) {
+ if (context)
+ CGContextRelease(context);
+ context = cg;
+ CGContextRetain(context); //we do not take ownership
+ return *this;
+ }
+
+private:
+ CGContextRef context;
+};
+
+QT_END_NAMESPACE
+
+#endif // QCOREGRAPHICS_P_H
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index c697aceaf3..c1a49b7d9a 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -3263,342 +3263,72 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co
return buffer;
}
-static SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = {
- // Untransformed
- {
- 0, // Invalid
- fetchUntransformed, // Mono
- fetchUntransformed, // MonoLsb
- fetchUntransformed, // Indexed8
- fetchUntransformedARGB32PM, // RGB32
- fetchUntransformed, // ARGB32
- fetchUntransformedARGB32PM, // ARGB32_Premultiplied
- fetchUntransformedRGB16, // RGB16
- fetchUntransformed, // ARGB8565_Premultiplied
- fetchUntransformed, // RGB666
- fetchUntransformed, // ARGB6666_Premultiplied
- fetchUntransformed, // RGB555
- fetchUntransformed, // ARGB8555_Premultiplied
- fetchUntransformed, // RGB888
- fetchUntransformed, // RGB444
- fetchUntransformed, // ARGB4444_Premultiplied
- fetchUntransformed, // RGBX8888
- fetchUntransformed, // RGBA8888
- fetchUntransformed, // RGBA8888_Premultiplied
- fetchUntransformed, // Format_BGR30
- fetchUntransformed, // Format_A2BGR30_Premultiplied
- fetchUntransformed, // Format_RGB30
- fetchUntransformed, // Format_A2RGB30_Premultiplied
- fetchUntransformed, // Alpha8
- fetchUntransformed, // Grayscale8
- },
- // Tiled
- {
- 0, // Invalid
- fetchUntransformed, // Mono
- fetchUntransformed, // MonoLsb
- fetchUntransformed, // Indexed8
- fetchUntransformedARGB32PM, // RGB32
- fetchUntransformed, // ARGB32
- fetchUntransformedARGB32PM, // ARGB32_Premultiplied
- fetchUntransformedRGB16, // RGB16
- fetchUntransformed, // ARGB8565_Premultiplied
- fetchUntransformed, // RGB666
- fetchUntransformed, // ARGB6666_Premultiplied
- fetchUntransformed, // RGB555
- fetchUntransformed, // ARGB8555_Premultiplied
- fetchUntransformed, // RGB888
- fetchUntransformed, // RGB444
- fetchUntransformed, // ARGB4444_Premultiplied
- fetchUntransformed, // RGBX8888
- fetchUntransformed, // RGBA8888
- fetchUntransformed, // RGBA8888_Premultiplied
- fetchUntransformed, // BGR30
- fetchUntransformed, // A2BGR30_Premultiplied
- fetchUntransformed, // RGB30
- fetchUntransformed, // A2RGB30_Premultiplied
- fetchUntransformed, // Alpha8
- fetchUntransformed, // Grayscale8
- },
- // Transformed
- {
- 0, // Invalid
- fetchTransformed<BlendTransformed>, // Mono
- fetchTransformed<BlendTransformed>, // MonoLsb
- fetchTransformed<BlendTransformed>, // Indexed8
- fetchTransformedARGB32PM<BlendTransformed>, // RGB32
- fetchTransformed<BlendTransformed>, // ARGB32
- fetchTransformedARGB32PM<BlendTransformed>, // ARGB32_Premultiplied
- fetchTransformed<BlendTransformed>, // RGB16
- fetchTransformed<BlendTransformed>, // ARGB8565_Premultiplied
- fetchTransformed<BlendTransformed>, // RGB666
- fetchTransformed<BlendTransformed>, // ARGB6666_Premultiplied
- fetchTransformed<BlendTransformed>, // RGB555
- fetchTransformed<BlendTransformed>, // ARGB8555_Premultiplied
- fetchTransformed<BlendTransformed>, // RGB888
- fetchTransformed<BlendTransformed>, // RGB444
- fetchTransformed<BlendTransformed>, // ARGB4444_Premultiplied
- fetchTransformed<BlendTransformed>, // RGBX8888
- fetchTransformed<BlendTransformed>, // RGBA8888
- fetchTransformed<BlendTransformed>, // RGBA8888_Premultiplied
- fetchTransformed<BlendTransformed>, // BGR30
- fetchTransformed<BlendTransformed>, // A2BGR30_Premultiplied
- fetchTransformed<BlendTransformed>, // RGB30
- fetchTransformed<BlendTransformed>, // A2RGB30_Premultiplied
- fetchTransformed<BlendTransformed>, // Alpah8
- fetchTransformed<BlendTransformed>, // Grayscale8
- },
- {
- 0, // TransformedTiled
- fetchTransformed<BlendTransformedTiled>, // Mono
- fetchTransformed<BlendTransformedTiled>, // MonoLsb
- fetchTransformed<BlendTransformedTiled>, // Indexed8
- fetchTransformedARGB32PM<BlendTransformedTiled>, // RGB32
- fetchTransformed<BlendTransformedTiled>, // ARGB32
- fetchTransformedARGB32PM<BlendTransformedTiled>, // ARGB32_Premultiplied
- fetchTransformed<BlendTransformedTiled>, // RGB16
- fetchTransformed<BlendTransformedTiled>, // ARGB8565_Premultiplied
- fetchTransformed<BlendTransformedTiled>, // RGB666
- fetchTransformed<BlendTransformedTiled>, // ARGB6666_Premultiplied
- fetchTransformed<BlendTransformedTiled>, // RGB555
- fetchTransformed<BlendTransformedTiled>, // ARGB8555_Premultiplied
- fetchTransformed<BlendTransformedTiled>, // RGB888
- fetchTransformed<BlendTransformedTiled>, // RGB444
- fetchTransformed<BlendTransformedTiled>, // ARGB4444_Premultiplied
- fetchTransformed<BlendTransformedTiled>, // RGBX8888
- fetchTransformed<BlendTransformedTiled>, // RGBA8888
- fetchTransformed<BlendTransformedTiled>, // RGBA8888_Premultiplied
- fetchTransformed<BlendTransformedTiled>, // BGR30
- fetchTransformed<BlendTransformedTiled>, // A2BGR30_Premultiplied
- fetchTransformed<BlendTransformedTiled>, // RGB30
- fetchTransformed<BlendTransformedTiled>, // A2RGB30_Premultiplied
- fetchTransformed<BlendTransformedTiled>, // Alpha8
- fetchTransformed<BlendTransformedTiled>, // Grayscale8
- },
- {
- 0, // Bilinear
- fetchTransformedBilinear<BlendTransformedBilinear>, // Mono
- fetchTransformedBilinear<BlendTransformedBilinear>, // MonoLsb
- fetchTransformedBilinear<BlendTransformedBilinear>, // Indexed8
- fetchTransformedBilinearARGB32PM<BlendTransformedBilinear>, // RGB32
- fetchTransformedBilinear<BlendTransformedBilinear>, // ARGB32
- fetchTransformedBilinearARGB32PM<BlendTransformedBilinear>, // ARGB32_Premultiplied
- fetchTransformedBilinear<BlendTransformedBilinear>, // RGB16
- fetchTransformedBilinear<BlendTransformedBilinear>, // ARGB8565_Premultiplied
- fetchTransformedBilinear<BlendTransformedBilinear>, // RGB666
- fetchTransformedBilinear<BlendTransformedBilinear>, // ARGB6666_Premultiplied
- fetchTransformedBilinear<BlendTransformedBilinear>, // RGB555
- fetchTransformedBilinear<BlendTransformedBilinear>, // ARGB8555_Premultiplied
- fetchTransformedBilinear<BlendTransformedBilinear>, // RGB888
- fetchTransformedBilinear<BlendTransformedBilinear>, // RGB444
- fetchTransformedBilinear<BlendTransformedBilinear>, // ARGB4444_Premultiplied
- fetchTransformedBilinear<BlendTransformedBilinear>, // RGBX8888
- fetchTransformedBilinear<BlendTransformedBilinear>, // RGBA8888
- fetchTransformedBilinear<BlendTransformedBilinear>, // RGBA8888_Premultiplied
- fetchTransformedBilinear<BlendTransformedBilinear>, // BGR30
- fetchTransformedBilinear<BlendTransformedBilinear>, // A2BGR30_Premultiplied
- fetchTransformedBilinear<BlendTransformedBilinear>, // RGB30
- fetchTransformedBilinear<BlendTransformedBilinear>, // A2RGB30_Premultiplied
- fetchTransformedBilinear<BlendTransformedBilinear>, // Alpha8
- fetchTransformedBilinear<BlendTransformedBilinear>, // Grayscale8
- },
- {
- 0, // BilinearTiled
- fetchTransformedBilinear<BlendTransformedBilinearTiled>, // Mono
- fetchTransformedBilinear<BlendTransformedBilinearTiled>, // MonoLsb
- fetchTransformedBilinear<BlendTransformedBilinearTiled>, // Indexed8
- fetchTransformedBilinearARGB32PM<BlendTransformedBilinearTiled>, // RGB32
- fetchTransformedBilinear<BlendTransformedBilinearTiled>, // ARGB32
- fetchTransformedBilinearARGB32PM<BlendTransformedBilinearTiled>, // ARGB32_Premultiplied
- fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGB16
- fetchTransformedBilinear<BlendTransformedBilinearTiled>, // ARGB8565_Premultiplied
- fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGB666
- fetchTransformedBilinear<BlendTransformedBilinearTiled>, // ARGB6666_Premultiplied
- fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGB555
- fetchTransformedBilinear<BlendTransformedBilinearTiled>, // ARGB8555_Premultiplied
- fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGB888
- fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGB444
- fetchTransformedBilinear<BlendTransformedBilinearTiled>, // ARGB4444_Premultiplied
- fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGBX8888
- fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGBA8888
- fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGBA8888_Premultiplied
- fetchTransformedBilinear<BlendTransformedBilinearTiled>, // BGR30
- fetchTransformedBilinear<BlendTransformedBilinearTiled>, // A2BGR30_Premultiplied
- fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGB30
- fetchTransformedBilinear<BlendTransformedBilinearTiled>, // A2RGB30_Premultiplied
- fetchTransformedBilinear<BlendTransformedBilinearTiled>, // Alpha8
- fetchTransformedBilinear<BlendTransformedBilinearTiled>, // Grayscale8
- },
+// FetchUntransformed can have more specialized methods added depending on SIMD features.
+static SourceFetchProc sourceFetchUntransformed[QImage::NImageFormats] = {
+ 0, // Invalid
+ fetchUntransformed, // Mono
+ fetchUntransformed, // MonoLsb
+ fetchUntransformed, // Indexed8
+ fetchUntransformedARGB32PM, // RGB32
+ fetchUntransformed, // ARGB32
+ fetchUntransformedARGB32PM, // ARGB32_Premultiplied
+ fetchUntransformedRGB16, // RGB16
+ fetchUntransformed, // ARGB8565_Premultiplied
+ fetchUntransformed, // RGB666
+ fetchUntransformed, // ARGB6666_Premultiplied
+ fetchUntransformed, // RGB555
+ fetchUntransformed, // ARGB8555_Premultiplied
+ fetchUntransformed, // RGB888
+ fetchUntransformed, // RGB444
+ fetchUntransformed, // ARGB4444_Premultiplied
+ fetchUntransformed, // RGBX8888
+ fetchUntransformed, // RGBA8888
+ fetchUntransformed, // RGBA8888_Premultiplied
+ fetchUntransformed, // Format_BGR30
+ fetchUntransformed, // Format_A2BGR30_Premultiplied
+ fetchUntransformed, // Format_RGB30
+ fetchUntransformed, // Format_A2RGB30_Premultiplied
+ fetchUntransformed, // Alpha8
+ fetchUntransformed, // Grayscale8
};
-static SourceFetchProc64 sourceFetch64[NBlendTypes][QImage::NImageFormats] = {
- // Untransformed
- {
- 0, // Invalid
- fetchUntransformed64, // Mono
- fetchUntransformed64, // MonoLsb
- fetchUntransformed64, // Indexed8
- fetchUntransformed64, // RGB32
- fetchUntransformed64, // ARGB32
- fetchUntransformed64, // ARGB32_Premultiplied
- fetchUntransformed64, // RGB16
- fetchUntransformed64, // ARGB8565_Premultiplied
- fetchUntransformed64, // RGB666
- fetchUntransformed64, // ARGB6666_Premultiplied
- fetchUntransformed64, // RGB555
- fetchUntransformed64, // ARGB8555_Premultiplied
- fetchUntransformed64, // RGB888
- fetchUntransformed64, // RGB444
- fetchUntransformed64, // ARGB4444_Premultiplied
- fetchUntransformed64, // RGBX8888
- fetchUntransformed64, // RGBA8888
- fetchUntransformed64, // RGBA8888_Premultiplied
- fetchUntransformed64, // Format_BGR30
- fetchUntransformed64, // Format_A2BGR30_Premultiplied
- fetchUntransformed64, // Format_RGB30
- fetchUntransformed64, // Format_A2RGB30_Premultiplied
- fetchUntransformed64, // Alpha8
- fetchUntransformed64, // Grayscale8
- },
- // Tiled
- {
- 0, // Invalid
- fetchUntransformed64, // Mono
- fetchUntransformed64, // MonoLsb
- fetchUntransformed64, // Indexed8
- fetchUntransformed64, // RGB32
- fetchUntransformed64, // ARGB32
- fetchUntransformed64, // ARGB32_Premultiplied
- fetchUntransformed64, // RGB16
- fetchUntransformed64, // ARGB8565_Premultiplied
- fetchUntransformed64, // RGB666
- fetchUntransformed64, // ARGB6666_Premultiplied
- fetchUntransformed64, // RGB555
- fetchUntransformed64, // ARGB8555_Premultiplied
- fetchUntransformed64, // RGB888
- fetchUntransformed64, // RGB444
- fetchUntransformed64, // ARGB4444_Premultiplied
- fetchUntransformed64, // RGBX8888
- fetchUntransformed64, // RGBA8888
- fetchUntransformed64, // RGBA8888_Premultiplied
- fetchUntransformed64, // BGR30
- fetchUntransformed64, // A2BGR30_Premultiplied
- fetchUntransformed64, // RGB30
- fetchUntransformed64, // A2RGB30_Premultiplied
- fetchUntransformed64, // Alpha8
- fetchUntransformed64, // Grayscale8
- },
- // Transformed
- {
- 0, // Invalid
- fetchTransformed64<BlendTransformed>, // Mono
- fetchTransformed64<BlendTransformed>, // MonoLsb
- fetchTransformed64<BlendTransformed>, // Indexed8
- fetchTransformed64<BlendTransformed>, // RGB32
- fetchTransformed64<BlendTransformed>, // ARGB32
- fetchTransformed64<BlendTransformed>, // ARGB32_Premultiplied
- fetchTransformed64<BlendTransformed>, // RGB16
- fetchTransformed64<BlendTransformed>, // ARGB8565_Premultiplied
- fetchTransformed64<BlendTransformed>, // RGB666
- fetchTransformed64<BlendTransformed>, // ARGB6666_Premultiplied
- fetchTransformed64<BlendTransformed>, // RGB555
- fetchTransformed64<BlendTransformed>, // ARGB8555_Premultiplied
- fetchTransformed64<BlendTransformed>, // RGB888
- fetchTransformed64<BlendTransformed>, // RGB444
- fetchTransformed64<BlendTransformed>, // ARGB4444_Premultiplied
- fetchTransformed64<BlendTransformed>, // RGBX8888
- fetchTransformed64<BlendTransformed>, // RGBA8888
- fetchTransformed64<BlendTransformed>, // RGBA8888_Premultiplied
- fetchTransformed64<BlendTransformed>, // BGR30
- fetchTransformed64<BlendTransformed>, // A2BGR30_Premultiplied
- fetchTransformed64<BlendTransformed>, // RGB30
- fetchTransformed64<BlendTransformed>, // A2RGB30_Premultiplied
- fetchTransformed64<BlendTransformed>, // Alpah8
- fetchTransformed64<BlendTransformed>, // Grayscale8
- },
- {
- 0, // TransformedTiled
- fetchTransformed64<BlendTransformedTiled>, // Mono
- fetchTransformed64<BlendTransformedTiled>, // MonoLsb
- fetchTransformed64<BlendTransformedTiled>, // Indexed8
- fetchTransformed64<BlendTransformedTiled>, // RGB32
- fetchTransformed64<BlendTransformedTiled>, // ARGB32
- fetchTransformed64<BlendTransformedTiled>, // ARGB32_Premultiplied
- fetchTransformed64<BlendTransformedTiled>, // RGB16
- fetchTransformed64<BlendTransformedTiled>, // ARGB8565_Premultiplied
- fetchTransformed64<BlendTransformedTiled>, // RGB666
- fetchTransformed64<BlendTransformedTiled>, // ARGB6666_Premultiplied
- fetchTransformed64<BlendTransformedTiled>, // RGB555
- fetchTransformed64<BlendTransformedTiled>, // ARGB8555_Premultiplied
- fetchTransformed64<BlendTransformedTiled>, // RGB888
- fetchTransformed64<BlendTransformedTiled>, // RGB444
- fetchTransformed64<BlendTransformedTiled>, // ARGB4444_Premultiplied
- fetchTransformed64<BlendTransformedTiled>, // RGBX8888
- fetchTransformed64<BlendTransformedTiled>, // RGBA8888
- fetchTransformed64<BlendTransformedTiled>, // RGBA8888_Premultiplied
- fetchTransformed64<BlendTransformedTiled>, // BGR30
- fetchTransformed64<BlendTransformedTiled>, // A2BGR30_Premultiplied
- fetchTransformed64<BlendTransformedTiled>, // RGB30
- fetchTransformed64<BlendTransformedTiled>, // A2RGB30_Premultiplied
- fetchTransformed64<BlendTransformedTiled>, // Alpha8
- fetchTransformed64<BlendTransformedTiled>, // Grayscale8
- },
- {
- 0, // Bilinear
- fetchTransformedBilinear64<BlendTransformedBilinear>, // Mono
- fetchTransformedBilinear64<BlendTransformedBilinear>, // MonoLsb
- fetchTransformedBilinear64<BlendTransformedBilinear>, // Indexed8
- fetchTransformedBilinear64<BlendTransformedBilinear>, // RGB32
- fetchTransformedBilinear64<BlendTransformedBilinear>, // ARGB32
- fetchTransformedBilinear64<BlendTransformedBilinear>, // ARGB32_Premultiplied
- fetchTransformedBilinear64<BlendTransformedBilinear>, // RGB16
- fetchTransformedBilinear64<BlendTransformedBilinear>, // ARGB8565_Premultiplied
- fetchTransformedBilinear64<BlendTransformedBilinear>, // RGB666
- fetchTransformedBilinear64<BlendTransformedBilinear>, // ARGB6666_Premultiplied
- fetchTransformedBilinear64<BlendTransformedBilinear>, // RGB555
- fetchTransformedBilinear64<BlendTransformedBilinear>, // ARGB8555_Premultiplied
- fetchTransformedBilinear64<BlendTransformedBilinear>, // RGB888
- fetchTransformedBilinear64<BlendTransformedBilinear>, // RGB444
- fetchTransformedBilinear64<BlendTransformedBilinear>, // ARGB4444_Premultiplied
- fetchTransformedBilinear64<BlendTransformedBilinear>, // RGBX8888
- fetchTransformedBilinear64<BlendTransformedBilinear>, // RGBA8888
- fetchTransformedBilinear64<BlendTransformedBilinear>, // RGBA8888_Premultiplied
- fetchTransformedBilinear64<BlendTransformedBilinear>, // BGR30
- fetchTransformedBilinear64<BlendTransformedBilinear>, // A2BGR30_Premultiplied
- fetchTransformedBilinear64<BlendTransformedBilinear>, // RGB30
- fetchTransformedBilinear64<BlendTransformedBilinear>, // A2RGB30_Premultiplied
- fetchTransformedBilinear64<BlendTransformedBilinear>, // Alpha8
- fetchTransformedBilinear64<BlendTransformedBilinear>, // Grayscale8
- },
- {
- 0, // BilinearTiled
- fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // Mono
- fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // MonoLsb
- fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // Indexed8
- fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGB32
- fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // ARGB32
- fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // ARGB32_Premultiplied
- fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGB16
- fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // ARGB8565_Premultiplied
- fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGB666
- fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // ARGB6666_Premultiplied
- fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGB555
- fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // ARGB8555_Premultiplied
- fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGB888
- fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGB444
- fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // ARGB4444_Premultiplied
- fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGBX8888
- fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGBA8888
- fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGBA8888_Premultiplied
- fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // BGR30
- fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // A2BGR30_Premultiplied
- fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // RGB30
- fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // A2RGB30_Premultiplied
- fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // Alpha8
- fetchTransformedBilinear64<BlendTransformedBilinearTiled>, // Grayscale8
- },
+static const SourceFetchProc sourceFetchGeneric[NBlendTypes] = {
+ fetchUntransformed, // Untransformed
+ fetchUntransformed, // Tiled
+ fetchTransformed<BlendTransformed>, // Transformed
+ fetchTransformed<BlendTransformedTiled>, // TransformedTiled
+ fetchTransformedBilinear<BlendTransformedBilinear>, // Bilinear
+ fetchTransformedBilinear<BlendTransformedBilinearTiled> // BilinearTiled
+};
+
+static SourceFetchProc sourceFetchARGB32PM[NBlendTypes] = {
+ fetchUntransformedARGB32PM, // Untransformed
+ fetchUntransformedARGB32PM, // Tiled
+ fetchTransformedARGB32PM<BlendTransformed>, // Transformed
+ fetchTransformedARGB32PM<BlendTransformedTiled>, // TransformedTiled
+ fetchTransformedBilinearARGB32PM<BlendTransformedBilinear>, // Bilinear
+ fetchTransformedBilinearARGB32PM<BlendTransformedBilinearTiled> // BilinearTiled
+};
+
+static const SourceFetchProc64 sourceFetchGeneric64[NBlendTypes] = {
+ fetchUntransformed64, // Untransformed
+ fetchUntransformed64, // Tiled
+ fetchTransformed64<BlendTransformed>, // Transformed
+ fetchTransformed64<BlendTransformedTiled>, // TransformedTiled
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // Bilinear
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled> // BilinearTiled
};
+static inline SourceFetchProc getSourceFetch(TextureBlendType blendType, QImage::Format format)
+{
+ if (format == QImage::Format_RGB32 || format == QImage::Format_ARGB32_Premultiplied)
+ return sourceFetchARGB32PM[blendType];
+ if (blendType == BlendUntransformed || blendType == BlendTiled)
+ return sourceFetchUntransformed[format];
+ return sourceFetchGeneric[blendType];
+}
+
+
#define FIXPT_BITS 8
#define FIXPT_SIZE (1<<FIXPT_BITS)
@@ -3939,8 +3669,8 @@ static inline Operator getOperator(const QSpanData *data, const QSpan *spans, in
break;
case QSpanData::Texture:
solidSource = !data->texture.hasAlpha;
- op.srcFetch = sourceFetch[getBlendType(data)][data->texture.format];
- op.srcFetch64 = sourceFetch64[getBlendType(data)][data->texture.format];
+ op.srcFetch = getSourceFetch(getBlendType(data), data->texture.format);
+ op.srcFetch64 = sourceFetchGeneric64[getBlendType(data)];
break;
default:
Q_UNREACHABLE();
@@ -5483,181 +5213,67 @@ static void blend_transformed_tiled_rgb565(int count, const QSpan *spans, void *
/* Image formats here are target formats */
-static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats] = {
- // Untransformed
- {
- 0, // Invalid
- blend_untransformed_generic, // Mono
- blend_untransformed_generic, // MonoLsb
- blend_untransformed_generic, // Indexed8
- blend_untransformed_generic, // RGB32
- blend_untransformed_generic, // ARGB32
- blend_untransformed_argb, // ARGB32_Premultiplied
- blend_untransformed_rgb565,
- blend_untransformed_generic,
- blend_untransformed_generic,
- blend_untransformed_generic,
- blend_untransformed_generic,
- blend_untransformed_generic,
- blend_untransformed_generic,
- blend_untransformed_generic,
- blend_untransformed_generic,
- blend_untransformed_generic,
- blend_untransformed_generic,
- blend_untransformed_generic,
- blend_untransformed_generic_rgb64,
- blend_untransformed_generic_rgb64,
- blend_untransformed_generic_rgb64,
- blend_untransformed_generic_rgb64,
- blend_untransformed_generic,
- blend_untransformed_generic,
- },
- // Tiled
- {
- 0, // Invalid
- blend_tiled_generic, // Mono
- blend_tiled_generic, // MonoLsb
- blend_tiled_generic, // Indexed8
- blend_tiled_generic, // RGB32
- blend_tiled_generic, // ARGB32
- blend_tiled_argb, // ARGB32_Premultiplied
- blend_tiled_rgb565,
- blend_tiled_generic,
- blend_tiled_generic,
- blend_tiled_generic,
- blend_tiled_generic,
- blend_tiled_generic,
- blend_tiled_generic,
- blend_tiled_generic,
- blend_tiled_generic,
- blend_tiled_generic,
- blend_tiled_generic,
- blend_tiled_generic,
- blend_tiled_generic_rgb64,
- blend_tiled_generic_rgb64,
- blend_tiled_generic_rgb64,
- blend_tiled_generic_rgb64,
- blend_tiled_generic,
- blend_tiled_generic,
- },
- // Transformed
- {
- 0, // Invalid
- blend_src_generic, // Mono
- blend_src_generic, // MonoLsb
- blend_src_generic, // Indexed8
- blend_src_generic, // RGB32
- blend_src_generic, // ARGB32
- blend_transformed_argb, // ARGB32_Premultiplied
- blend_transformed_rgb565,
- blend_src_generic, // ARGB8565_Premultiplied
- blend_src_generic, // RGB666
- blend_src_generic, // ARGB6666_Premultiplied
- blend_src_generic, // RGB555
- blend_src_generic, // ARGB8555_Premultiplied
- blend_src_generic, // RGB888
- blend_src_generic, // RGB444
- blend_src_generic, // ARGB4444_Premultiplied
- blend_src_generic, // RGBX8888
- blend_src_generic, // RGBA8888
- blend_src_generic, // RGBA8888_Premultiplied
- blend_src_generic_rgb64,
- blend_src_generic_rgb64,
- blend_src_generic_rgb64,
- blend_src_generic_rgb64,
- blend_src_generic,
- blend_src_generic,
- },
- // TransformedTiled
- {
- 0,
- blend_src_generic, // Mono
- blend_src_generic, // MonoLsb
- blend_src_generic, // Indexed8
- blend_src_generic, // RGB32
- blend_src_generic, // ARGB32
- blend_transformed_tiled_argb, // ARGB32_Premultiplied
- blend_transformed_tiled_rgb565,
- blend_src_generic, // ARGB8565_Premultiplied
- blend_src_generic, // RGB666
- blend_src_generic, // ARGB6666_Premultiplied
- blend_src_generic, // RGB555
- blend_src_generic, // ARGB8555_Premultiplied
- blend_src_generic, // RGB888
- blend_src_generic, // RGB444
- blend_src_generic, // ARGB4444_Premultiplied
- blend_src_generic, // RGBX8888
- blend_src_generic, // RGBA8888
- blend_src_generic, // RGBA8888_Premultiplied
- blend_src_generic_rgb64,
- blend_src_generic_rgb64,
- blend_src_generic_rgb64,
- blend_src_generic_rgb64,
- blend_src_generic,
- blend_src_generic,
- },
- // Bilinear
- {
- 0,
- blend_src_generic, // Mono
- blend_src_generic, // MonoLsb
- blend_src_generic, // Indexed8
- blend_src_generic, // RGB32
- blend_src_generic, // ARGB32
- blend_src_generic, // ARGB32_Premultiplied
- blend_transformed_bilinear_rgb565,
- blend_src_generic, // ARGB8565_Premultiplied
- blend_src_generic, // RGB666
- blend_src_generic, // ARGB6666_Premultiplied
- blend_src_generic, // RGB555
- blend_src_generic, // ARGB8555_Premultiplied
- blend_src_generic, // RGB888
- blend_src_generic, // RGB444
- blend_src_generic, // ARGB4444_Premultiplied
- blend_src_generic, // RGBX8888
- blend_src_generic, // RGBA8888
- blend_src_generic, // RGBA8888_Premultiplied
- blend_src_generic_rgb64,
- blend_src_generic_rgb64,
- blend_src_generic_rgb64,
- blend_src_generic_rgb64,
- blend_src_generic,
- blend_src_generic,
- },
- // BilinearTiled
- {
- 0,
- blend_src_generic, // Mono
- blend_src_generic, // MonoLsb
- blend_src_generic, // Indexed8
- blend_src_generic, // RGB32
- blend_src_generic, // ARGB32
- blend_src_generic, // ARGB32_Premultiplied
- blend_src_generic, // RGB16
- blend_src_generic, // ARGB8565_Premultiplied
- blend_src_generic, // RGB666
- blend_src_generic, // ARGB6666_Premultiplied
- blend_src_generic, // RGB555
- blend_src_generic, // ARGB8555_Premultiplied
- blend_src_generic, // RGB888
- blend_src_generic, // RGB444
- blend_src_generic, // ARGB4444_Premultiplied
- blend_src_generic, // RGBX8888
- blend_src_generic, // RGBA8888
- blend_src_generic, // RGBA8888_Premultiplied
- blend_src_generic_rgb64, // BGR30
- blend_src_generic_rgb64, // A2BGR30_Premultiplied
- blend_src_generic_rgb64, // RGB30
- blend_src_generic_rgb64, // A2RGB30_Premultiplied
- blend_src_generic, // Alpha8
- blend_src_generic, // Grayscale8
- }
+static const ProcessSpans processTextureSpansARGB32PM[NBlendTypes] = {
+ blend_untransformed_argb, // Untransformed
+ blend_tiled_argb, // Tiled
+ blend_transformed_argb, // Transformed
+ blend_transformed_tiled_argb, // TransformedTiled
+ blend_src_generic, // TransformedBilinear
+ blend_src_generic // TransformedBilinearTiled
+};
+
+static const ProcessSpans processTextureSpansRGB16[NBlendTypes] = {
+ blend_untransformed_rgb565, // Untransformed
+ blend_tiled_rgb565, // Tiled
+ blend_transformed_rgb565, // Transformed
+ blend_transformed_tiled_rgb565, // TransformedTiled
+ blend_transformed_bilinear_rgb565, // TransformedBilinear
+ blend_src_generic // TransformedBilinearTiled
+};
+
+static const ProcessSpans processTextureSpansGeneric[NBlendTypes] = {
+ blend_untransformed_generic, // Untransformed
+ blend_tiled_generic, // Tiled
+ blend_src_generic, // Transformed
+ blend_src_generic, // TransformedTiled
+ blend_src_generic, // TransformedBilinear
+ blend_src_generic // TransformedBilinearTiled
+};
+
+static const ProcessSpans processTextureSpansGeneric64[NBlendTypes] = {
+ blend_untransformed_generic_rgb64, // Untransformed
+ blend_tiled_generic_rgb64, // Tiled
+ blend_src_generic_rgb64, // Transformed
+ blend_src_generic_rgb64, // TransformedTiled
+ blend_src_generic_rgb64, // TransformedBilinear
+ blend_src_generic_rgb64 // TransformedBilinearTiled
};
void qBlendTexture(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
- ProcessSpans proc = processTextureSpans[getBlendType(data)][data->rasterBuffer->format];
+ TextureBlendType blendType = getBlendType(data);
+ ProcessSpans proc;
+ switch (data->rasterBuffer->format) {
+ case QImage::Format_ARGB32_Premultiplied:
+ proc = processTextureSpansARGB32PM[blendType];
+ break;
+ case QImage::Format_RGB16:
+ proc = processTextureSpansRGB16[blendType];
+ break;
+ case QImage::Format_BGR30:
+ case QImage::Format_A2BGR30_Premultiplied:
+ case QImage::Format_RGB30:
+ case QImage::Format_A2RGB30_Premultiplied:
+ proc = processTextureSpansGeneric64[blendType];
+ break;
+ case QImage::Format_Invalid:
+ Q_UNREACHABLE();
+ return;
+ default:
+ proc = processTextureSpansGeneric[blendType];
+ break;
+ }
proc(count, spans, userData);
}
@@ -6548,6 +6164,15 @@ static void qInitDrawhelperFunctions()
qt_fetch_radial_gradient = qt_fetch_radial_gradient_sse2;
+ extern void QT_FASTCALL comp_func_SourceOver_sse2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
+ extern void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, uint color, uint const_alpha);
+ extern void QT_FASTCALL comp_func_Source_sse2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
+ extern void QT_FASTCALL comp_func_Plus_sse2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
+ qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_sse2;
+ qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_sse2;
+ qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_sse2;
+ qt_functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_sse2;
+
#ifdef QT_COMPILER_SUPPORTS_SSSE3
if (qCpuHasFeature(SSSE3)) {
extern void qt_blend_argb32_on_argb32_ssse3(uchar *destPixels, int dbpl,
@@ -6563,8 +6188,7 @@ static void qInitDrawhelperFunctions()
qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
qStorePixels[QPixelLayout::BPP24] = storePixelsBPP24_ssse3;
- sourceFetch[BlendUntransformed][QImage::Format_RGB888] = qt_fetchUntransformed_888_ssse3;
- sourceFetch[BlendTiled][QImage::Format_RGB888] = qt_fetchUntransformed_888_ssse3;
+ sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_ssse3;
}
#endif // SSSE3
@@ -6592,24 +6216,39 @@ static void qInitDrawhelperFunctions()
}
#endif
-#if defined(QT_COMPILER_SUPPORTS_AVX2) && !defined(__AVX2__)
+#if defined(QT_COMPILER_SUPPORTS_AVX2)
if (qCpuHasFeature(AVX2)) {
+#if !defined(__AVX2__)
extern const uint *QT_FASTCALL convertARGB32ToARGB32PM_avx2(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *);
extern const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_avx2(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *);
qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_avx2;
qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_avx2;
+#endif
+ extern void qt_blend_rgb32_on_rgb32_avx2(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h, int const_alpha);
+ extern void qt_blend_argb32_on_argb32_avx2(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h, int const_alpha);
+ qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_avx2;
+ qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_avx2;
+ qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx2;
+ qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx2;
+ qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx2;
+ qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx2;
+ qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx2;
+ qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx2;
+
+ extern void QT_FASTCALL comp_func_SourceOver_avx2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
+ extern void QT_FASTCALL comp_func_solid_SourceOver_avx2(uint *destPixels, int length, uint color, uint const_alpha);
+ extern void QT_FASTCALL comp_func_Source_avx2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
+ qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_avx2;
+ qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_avx2;
+ qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_avx2;
}
#endif
- extern void QT_FASTCALL comp_func_SourceOver_sse2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
- extern void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, uint color, uint const_alpha);
- extern void QT_FASTCALL comp_func_Source_sse2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
- extern void QT_FASTCALL comp_func_Plus_sse2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
- qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_sse2;
- qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_sse2;
- qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_sse2;
- qt_functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_sse2;
#endif // SSE2
@@ -6634,8 +6273,7 @@ static void qInitDrawhelperFunctions()
qt_fetch_radial_gradient = qt_fetch_radial_gradient_neon;
- sourceFetch[BlendUntransformed][QImage::Format_RGB888] = qt_fetchUntransformed_888_neon;
- sourceFetch[BlendTiled][QImage::Format_RGB888] = qt_fetchUntransformed_888_neon;
+ sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_neon;
#if defined(ENABLE_PIXMAN_DRAWHELPERS)
// The RGB16 helpers are using Arm32 assemblythat has not been ported to AArch64
@@ -6696,14 +6334,9 @@ static void qInitDrawhelperFunctions()
destStoreProc[QImage::Format_ARGB32] = qt_destStoreARGB32_mips_dsp;
- sourceFetch[BlendUntransformed][QImage::Format_RGB888] = qt_fetchUntransformed_888_mips_dsp;
- sourceFetch[BlendTiled][QImage::Format_RGB888] = qt_fetchUntransformed_888_mips_dsp;
-
- sourceFetch[BlendUntransformed][QImage::Format_RGB444] = qt_fetchUntransformed_444_mips_dsp;
- sourceFetch[BlendTiled][QImage::Format_RGB444] = qt_fetchUntransformed_444_mips_dsp;
-
- sourceFetch[BlendUntransformed][QImage::Format_ARGB8565_Premultiplied] = qt_fetchUntransformed_argb8565_premultiplied_mips_dsp;
- sourceFetch[BlendTiled][QImage::Format_ARGB8565_Premultiplied] = qt_fetchUntransformed_argb8565_premultiplied_mips_dsp;
+ sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_mips_dsp;
+ sourceFetchUntransformed[QImage::Format_RGB444] = qt_fetchUntransformed_444_mips_dsp;
+ sourceFetchUntransformed[QImage::Format_ARGB8565_Premultiplied] = qt_fetchUntransformed_argb8565_premultiplied_mips_dsp;
#if defined(QT_COMPILER_SUPPORTS_MIPS_DSPR2)
qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_mips_dspr2;
diff --git a/src/gui/painting/qdrawhelper_avx2.cpp b/src/gui/painting/qdrawhelper_avx2.cpp
index 35a975c972..01ffd54918 100644
--- a/src/gui/painting/qdrawhelper_avx2.cpp
+++ b/src/gui/painting/qdrawhelper_avx2.cpp
@@ -37,12 +37,14 @@
**
****************************************************************************/
-#include <private/qdrawhelper_p.h>
+#include "qdrawhelper_p.h"
+#include "qdrawingprimitive_sse2_p.h"
#if defined(QT_COMPILER_SUPPORTS_AVX2)
QT_BEGIN_NAMESPACE
+// Autovectorized premultiply functions:
const uint *QT_FASTCALL convertARGB32ToARGB32PM_avx2(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
{
@@ -55,6 +57,307 @@ const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_avx2(uint *buffer, const uint
return qt_convertRGBA8888ToARGB32PM(buffer, src, count);
}
+// Vectorized blend functions:
+
+// See BYTE_MUL_SSE2 for details.
+inline static void BYTE_MUL_AVX2(__m256i &pixelVector, const __m256i &alphaChannel, const __m256i &colorMask, const __m256i &half)
+{
+ __m256i pixelVectorAG = _mm256_srli_epi16(pixelVector, 8);
+ __m256i pixelVectorRB = _mm256_and_si256(pixelVector, colorMask);
+
+ pixelVectorAG = _mm256_mullo_epi16(pixelVectorAG, alphaChannel);
+ pixelVectorRB = _mm256_mullo_epi16(pixelVectorRB, alphaChannel);
+
+ pixelVectorRB = _mm256_add_epi16(pixelVectorRB, _mm256_srli_epi16(pixelVectorRB, 8));
+ pixelVectorAG = _mm256_add_epi16(pixelVectorAG, _mm256_srli_epi16(pixelVectorAG, 8));
+ pixelVectorRB = _mm256_add_epi16(pixelVectorRB, half);
+ pixelVectorAG = _mm256_add_epi16(pixelVectorAG, half);
+
+ pixelVectorRB = _mm256_srli_epi16(pixelVectorRB, 8);
+ pixelVectorAG = _mm256_andnot_si256(colorMask, pixelVectorAG);
+
+ pixelVector = _mm256_or_si256(pixelVectorAG, pixelVectorRB);
+}
+
+// See INTERPOLATE_PIXEL_255_SSE2 for details.
+inline static void INTERPOLATE_PIXEL_255_AVX2(const __m256i &srcVector, __m256i &dstVector, const __m256i &alphaChannel, const __m256i &oneMinusAlphaChannel, const __m256i &colorMask, const __m256i &half)
+{
+ const __m256i srcVectorAG = _mm256_srli_epi16(srcVector, 8);
+ const __m256i dstVectorAG = _mm256_srli_epi16(dstVector, 8);
+ const __m256i srcVectorRB = _mm256_and_si256(srcVector, colorMask);
+ const __m256i dstVectorRB = _mm256_and_si256(dstVector, colorMask);
+ const __m256i srcVectorAGalpha = _mm256_mullo_epi16(srcVectorAG, alphaChannel);
+ const __m256i srcVectorRBalpha = _mm256_mullo_epi16(srcVectorRB, alphaChannel);
+ const __m256i dstVectorAGoneMinusAlpha = _mm256_mullo_epi16(dstVectorAG, oneMinusAlphaChannel);
+ const __m256i dstVectorRBoneMinusAlpha = _mm256_mullo_epi16(dstVectorRB, oneMinusAlphaChannel);
+ __m256i finalAG = _mm256_add_epi16(srcVectorAGalpha, dstVectorAGoneMinusAlpha);
+ __m256i finalRB = _mm256_add_epi16(srcVectorRBalpha, dstVectorRBoneMinusAlpha);
+ finalAG = _mm256_add_epi16(finalAG, _mm256_srli_epi16(finalAG, 8));
+ finalRB = _mm256_add_epi16(finalRB, _mm256_srli_epi16(finalRB, 8));
+ finalAG = _mm256_add_epi16(finalAG, half);
+ finalRB = _mm256_add_epi16(finalRB, half);
+ finalAG = _mm256_andnot_si256(colorMask, finalAG);
+ finalRB = _mm256_srli_epi16(finalRB, 8);
+
+ dstVector = _mm256_or_si256(finalAG, finalRB);
+}
+
+// See BLEND_SOURCE_OVER_ARGB32_SSE2 for details.
+inline static void BLEND_SOURCE_OVER_ARGB32_AVX2(quint32 *dst, const quint32 *src, const int length)
+{
+ const __m256i half = _mm256_set1_epi16(0x80);
+ const __m256i one = _mm256_set1_epi16(0xff);
+ const __m256i colorMask = _mm256_set1_epi32(0x00ff00ff);
+ const __m256i alphaMask = _mm256_set1_epi32(0xff000000);
+ const __m256i offsetMask = _mm256_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7);
+ const __m256i alphaShuffleMask = _mm256_set_epi8(char(0xff),15,char(0xff),15,char(0xff),11,char(0xff),11,char(0xff),7,char(0xff),7,char(0xff),3,char(0xff),3,
+ char(0xff),15,char(0xff),15,char(0xff),11,char(0xff),11,char(0xff),7,char(0xff),7,char(0xff),3,char(0xff),3);
+
+ const int minusOffsetToAlignDstOn32Bytes = (reinterpret_cast<quintptr>(dst) >> 2) & 0x7;
+
+ int x = 0;
+ // Prologue to handle all pixels until dst is 32-byte aligned in one step.
+ if (minusOffsetToAlignDstOn32Bytes != 0 && x < (length - 7)) {
+ const __m256i prologueMask = _mm256_sub_epi32(_mm256_set1_epi32(minusOffsetToAlignDstOn32Bytes - 1), offsetMask);
+ const __m256i srcVector = _mm256_maskload_epi32((const int *)&src[x - minusOffsetToAlignDstOn32Bytes], prologueMask);
+ const __m256i prologueAlphaMask = _mm256_blendv_epi8(_mm256_setzero_si256(), alphaMask, prologueMask);
+ if (!_mm256_testz_si256(srcVector, prologueAlphaMask)) {
+ if (_mm256_testc_si256(srcVector, prologueAlphaMask)) {
+ _mm256_maskstore_epi32((int *)&dst[x - minusOffsetToAlignDstOn32Bytes], prologueMask, srcVector);
+ } else {
+ __m256i alphaChannel = _mm256_shuffle_epi8(srcVector, alphaShuffleMask);
+ alphaChannel = _mm256_sub_epi16(one, alphaChannel);
+ __m256i dstVector = _mm256_maskload_epi32((int *)&dst[x - minusOffsetToAlignDstOn32Bytes], prologueMask);
+ BYTE_MUL_AVX2(dstVector, alphaChannel, colorMask, half);
+ dstVector = _mm256_add_epi8(dstVector, srcVector);
+ _mm256_maskstore_epi32((int *)&dst[x - minusOffsetToAlignDstOn32Bytes], prologueMask, dstVector);
+ }
+ }
+ x += (8 - minusOffsetToAlignDstOn32Bytes);
+ }
+
+ for (; x < (length - 7); x += 8) {
+ const __m256i srcVector = _mm256_lddqu_si256((const __m256i *)&src[x]);
+ if (!_mm256_testz_si256(srcVector, alphaMask)) {
+ if (_mm256_testc_si256(srcVector, alphaMask)) {
+ _mm256_store_si256((__m256i *)&dst[x], srcVector);
+ } else {
+ __m256i alphaChannel = _mm256_shuffle_epi8(srcVector, alphaShuffleMask);
+ alphaChannel = _mm256_sub_epi16(one, alphaChannel);
+ __m256i dstVector = _mm256_load_si256((__m256i *)&dst[x]);
+ BYTE_MUL_AVX2(dstVector, alphaChannel, colorMask, half);
+ dstVector = _mm256_add_epi8(dstVector, srcVector);
+ _mm256_store_si256((__m256i *)&dst[x], dstVector);
+ }
+ }
+ }
+
+ // Epilogue to handle all remaining pixels in one step.
+ if (x < length) {
+ const __m256i epilogueMask = _mm256_add_epi32(offsetMask, _mm256_set1_epi32(x - length));
+ const __m256i srcVector = _mm256_maskload_epi32((const int *)&src[x], epilogueMask);
+ const __m256i epilogueAlphaMask = _mm256_blendv_epi8(_mm256_setzero_si256(), alphaMask, epilogueMask);
+ if (!_mm256_testz_si256(srcVector, epilogueAlphaMask)) {
+ if (_mm256_testc_si256(srcVector, epilogueAlphaMask)) {
+ _mm256_maskstore_epi32((int *)&dst[x], epilogueMask, srcVector);
+ } else {
+ __m256i alphaChannel = _mm256_shuffle_epi8(srcVector, alphaShuffleMask);
+ alphaChannel = _mm256_sub_epi16(one, alphaChannel);
+ __m256i dstVector = _mm256_maskload_epi32((int *)&dst[x], epilogueMask);
+ BYTE_MUL_AVX2(dstVector, alphaChannel, colorMask, half);
+ dstVector = _mm256_add_epi8(dstVector, srcVector);
+ _mm256_maskstore_epi32((int *)&dst[x], epilogueMask, dstVector);
+ }
+ }
+ }
+}
+
+
+// See BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_SSE2 for details.
+inline static void BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_AVX2(quint32 *dst, const quint32 *src, const int length, const int const_alpha)
+{
+ int x = 0;
+
+ ALIGNMENT_PROLOGUE_32BYTES(dst, x, length)
+ blend_pixel(dst[x], src[x], const_alpha);
+
+ const __m256i half = _mm256_set1_epi16(0x80);
+ const __m256i one = _mm256_set1_epi16(0xff);
+ const __m256i colorMask = _mm256_set1_epi32(0x00ff00ff);
+ const __m256i alphaMask = _mm256_set1_epi32(0xff000000);
+ const __m256i alphaShuffleMask = _mm256_set_epi8(char(0xff),15,char(0xff),15,char(0xff),11,char(0xff),11,char(0xff),7,char(0xff),7,char(0xff),3,char(0xff),3,
+ char(0xff),15,char(0xff),15,char(0xff),11,char(0xff),11,char(0xff),7,char(0xff),7,char(0xff),3,char(0xff),3);
+ const __m256i constAlphaVector = _mm256_set1_epi16(const_alpha);
+ for (; x < (length - 7); x += 8) {
+ __m256i srcVector = _mm256_lddqu_si256((const __m256i *)&src[x]);
+ if (!_mm256_testz_si256(srcVector, alphaMask)) {
+ BYTE_MUL_AVX2(srcVector, constAlphaVector, colorMask, half);
+
+ __m256i alphaChannel = _mm256_shuffle_epi8(srcVector, alphaShuffleMask);
+ alphaChannel = _mm256_sub_epi16(one, alphaChannel);
+ __m256i dstVector = _mm256_load_si256((__m256i *)&dst[x]);
+ BYTE_MUL_AVX2(dstVector, alphaChannel, colorMask, half);
+ dstVector = _mm256_add_epi8(dstVector, srcVector);
+ _mm256_store_si256((__m256i *)&dst[x], dstVector);
+ }
+ }
+ for (; x < length; ++x)
+ blend_pixel(dst[x], src[x], const_alpha);
+}
+
+void qt_blend_argb32_on_argb32_avx2(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h,
+ int const_alpha)
+{
+ if (const_alpha == 256) {
+ for (int y = 0; y < h; ++y) {
+ const quint32 *src = reinterpret_cast<const quint32 *>(srcPixels);
+ quint32 *dst = reinterpret_cast<quint32 *>(destPixels);
+ BLEND_SOURCE_OVER_ARGB32_AVX2(dst, src, w);
+ destPixels += dbpl;
+ srcPixels += sbpl;
+ }
+ } else if (const_alpha != 0) {
+ const_alpha = (const_alpha * 255) >> 8;
+ for (int y = 0; y < h; ++y) {
+ const quint32 *src = reinterpret_cast<const quint32 *>(srcPixels);
+ quint32 *dst = reinterpret_cast<quint32 *>(destPixels);
+ BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_AVX2(dst, src, w, const_alpha);
+ destPixels += dbpl;
+ srcPixels += sbpl;
+ }
+ }
+}
+
+void qt_blend_rgb32_on_rgb32_avx2(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h,
+ int const_alpha)
+{
+ if (const_alpha == 256) {
+ for (int y = 0; y < h; ++y) {
+ const quint32 *src = reinterpret_cast<const quint32 *>(srcPixels);
+ quint32 *dst = reinterpret_cast<quint32 *>(destPixels);
+ ::memcpy(dst, src, w * sizeof(uint));
+ srcPixels += sbpl;
+ destPixels += dbpl;
+ }
+ return;
+ }
+ if (const_alpha == 0)
+ return;
+
+ const __m256i half = _mm256_set1_epi16(0x80);
+ const __m256i colorMask = _mm256_set1_epi32(0x00ff00ff);
+
+ const_alpha = (const_alpha * 255) >> 8;
+ int one_minus_const_alpha = 255 - const_alpha;
+ const __m256i constAlphaVector = _mm256_set1_epi16(const_alpha);
+ const __m256i oneMinusConstAlpha = _mm256_set1_epi16(one_minus_const_alpha);
+ for (int y = 0; y < h; ++y) {
+ const quint32 *src = reinterpret_cast<const quint32 *>(srcPixels);
+ quint32 *dst = reinterpret_cast<quint32 *>(destPixels);
+ int x = 0;
+
+ // First, align dest to 32 bytes:
+ ALIGNMENT_PROLOGUE_32BYTES(dst, x, w)
+ dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], one_minus_const_alpha);
+
+ // 2) interpolate pixels with AVX2
+ for (; x < (w - 7); x += 8) {
+ const __m256i srcVector = _mm256_lddqu_si256((const __m256i *)&src[x]);
+ if (!_mm256_testc_si256(srcVector, _mm256_setzero_si256())) {
+ __m256i dstVector = _mm256_load_si256((__m256i *)&dst[x]);
+ INTERPOLATE_PIXEL_255_AVX2(srcVector, dstVector, constAlphaVector, oneMinusConstAlpha, colorMask, half);
+ _mm256_store_si256((__m256i *)&dst[x], dstVector);
+ }
+ }
+
+ // 3) Epilogue
+ for (; x < w; ++x)
+ dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], one_minus_const_alpha);
+
+ srcPixels += sbpl;
+ destPixels += dbpl;
+ }
+}
+
+void QT_FASTCALL comp_func_SourceOver_avx2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha)
+{
+ Q_ASSERT(const_alpha < 256);
+
+ const quint32 *src = (const quint32 *) srcPixels;
+ quint32 *dst = (quint32 *) destPixels;
+
+ if (const_alpha == 255)
+ BLEND_SOURCE_OVER_ARGB32_AVX2(dst, src, length);
+ else
+ BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_AVX2(dst, src, length, const_alpha);
+}
+
+void QT_FASTCALL comp_func_Source_avx2(uint *dst, const uint *src, int length, uint const_alpha)
+{
+ if (const_alpha == 255) {
+ ::memcpy(dst, src, length * sizeof(uint));
+ } else {
+ const int ialpha = 255 - const_alpha;
+
+ int x = 0;
+
+ // 1) prologue, align on 32 bytes
+ ALIGNMENT_PROLOGUE_32BYTES(dst, x, length)
+ dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], ialpha);
+
+ // 2) interpolate pixels with AVX2
+ const __m256i half = _mm256_set1_epi16(0x80);
+ const __m256i colorMask = _mm256_set1_epi32(0x00ff00ff);
+ const __m256i constAlphaVector = _mm256_set1_epi16(const_alpha);
+ const __m256i oneMinusConstAlpha = _mm256_set1_epi16(ialpha);
+ for (; x < length - 7; x += 8) {
+ const __m256i srcVector = _mm256_lddqu_si256((const __m256i *)&src[x]);
+ __m256i dstVector = _mm256_load_si256((__m256i *)&dst[x]);
+ INTERPOLATE_PIXEL_255_AVX2(srcVector, dstVector, constAlphaVector, oneMinusConstAlpha, colorMask, half);
+ _mm256_store_si256((__m256i *)&dst[x], dstVector);
+ }
+
+ // 3) Epilogue
+ for (; x < length; ++x)
+ dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], ialpha);
+ }
+}
+
+void QT_FASTCALL comp_func_solid_SourceOver_avx2(uint *destPixels, int length, uint color, uint const_alpha)
+{
+ if ((const_alpha & qAlpha(color)) == 255) {
+ qt_memfill32(destPixels, color, length);
+ } else {
+ if (const_alpha != 255)
+ color = BYTE_MUL(color, const_alpha);
+
+ const quint32 minusAlphaOfColor = qAlpha(~color);
+ int x = 0;
+
+ quint32 *dst = (quint32 *) destPixels;
+ const __m256i colorVector = _mm256_set1_epi32(color);
+ const __m256i colorMask = _mm256_set1_epi32(0x00ff00ff);
+ const __m256i half = _mm256_set1_epi16(0x80);
+ const __m256i minusAlphaOfColorVector = _mm256_set1_epi16(minusAlphaOfColor);
+
+ ALIGNMENT_PROLOGUE_32BYTES(dst, x, length)
+ destPixels[x] = color + BYTE_MUL(destPixels[x], minusAlphaOfColor);
+
+ for (; x < length - 7; x += 8) {
+ __m256i dstVector = _mm256_load_si256((__m256i *)&dst[x]);
+ BYTE_MUL_AVX2(dstVector, minusAlphaOfColorVector, colorMask, half);
+ dstVector = _mm256_add_epi8(colorVector, dstVector);
+ _mm256_store_si256((__m256i *)&dst[x], dstVector);
+ }
+ for (; x < length; ++x)
+ destPixels[x] = color + BYTE_MUL(destPixels[x], minusAlphaOfColor);
+ }
+}
+
QT_END_NAMESPACE
#endif
diff --git a/src/gui/painting/qpaintengine_p.h b/src/gui/painting/qpaintengine_p.h
index 1a1df547bb..9d511f9bad 100644
--- a/src/gui/painting/qpaintengine_p.h
+++ b/src/gui/painting/qpaintengine_p.h
@@ -118,6 +118,11 @@ public:
virtual void systemStateChanged() { }
void drawBoxTextItem(const QPointF &p, const QTextItemInt &ti);
+
+ static QPaintEnginePrivate *get(QPaintEngine *paintEngine) { return paintEngine->d_func(); }
+
+ virtual QPaintEngine *aggregateEngine() { return 0; }
+ virtual Qt::HANDLE nativeHandle() { return 0; }
};
QT_END_NAMESPACE
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index a3a3f20b18..7fcac9b9f2 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -2439,7 +2439,7 @@ int QFontDatabasePrivate::addAppFont(const QByteArray &fontData, const QString &
}
if (font.fileName.isEmpty() && !fontData.isEmpty())
- font.fileName = QString::fromLatin1(":qmemoryfonts/") + QString::number(i);
+ font.fileName = QLatin1String(":qmemoryfonts/") + QString::number(i);
registerFont(&font);
if (font.families.isEmpty())
diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp
index 73d2e545ba..e228b3c840 100644
--- a/src/gui/text/qtextodfwriter.cpp
+++ b/src/gui/text/qtextodfwriter.cpp
@@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE
static QString pixelToPoint(qreal pixels)
{
// we hardcode 96 DPI, we do the same in the ODF importer to have a perfect roundtrip.
- return QString::number(pixels * 72 / 96) + QString::fromLatin1("pt");
+ return QString::number(pixels * 72 / 96) + QLatin1String("pt");
}
// strategies