internal pixmap data classes optimizations

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2021-06-23 09:45:44 +03:00
parent ca1d93dfe1
commit 684883ad49
3 changed files with 33 additions and 21 deletions

View file

@ -173,11 +173,12 @@ void QRasterPixmapData::setMask(const QBitmap &mask)
switch (image.depth()) { switch (image.depth()) {
case 1: { case 1: {
const QImage imageMask = mask.toImage().convertToFormat(image.format()); const QImage imageMask = mask.toImage().convertToFormat(image.format());
const int bpl = image.bytesPerLine();
uchar *dest = image.bits();
for (int y = 0; y < h; ++y) { for (int y = 0; y < h; ++y) {
const uchar *mscan = imageMask.scanLine(y); const uchar *mscan = imageMask.constScanLine(y);
uchar *tscan = image.scanLine(y); uchar *tscan = QFAST_SCAN_LINE(dest, bpl, y);
int bytesPerLine = image.bytesPerLine(); for (int i = 0; i < bpl; ++i)
for (int i = 0; i < bytesPerLine; ++i)
tscan[i] &= mscan[i]; tscan[i] &= mscan[i];
} }
break; break;
@ -185,9 +186,11 @@ void QRasterPixmapData::setMask(const QBitmap &mask)
default: { default: {
const QImage imageMask = mask.toImage().convertToFormat(QImage::Format_MonoLSB); const QImage imageMask = mask.toImage().convertToFormat(QImage::Format_MonoLSB);
image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
const int bpl = image.bytesPerLine();
uchar *dest = image.bits();
for (int y = 0; y < h; ++y) { for (int y = 0; y < h; ++y) {
const uchar *mscan = imageMask.scanLine(y); const uchar *mscan = imageMask.constScanLine(y);
QRgb *tscan = (QRgb *)image.scanLine(y); QRgb *tscan = reinterpret_cast<QRgb*>(QFAST_SCAN_LINE(dest, bpl, y));
for (int x = 0; x < w; ++x) { for (int x = 0; x < w; ++x) {
if (!(mscan[x>>3] & qt_pixmap_bit_mask[x&7])) if (!(mscan[x>>3] & qt_pixmap_bit_mask[x&7]))
tscan[x] = 0; tscan[x] = 0;

View file

@ -1346,16 +1346,18 @@ QImage QX11PixmapData::takeQImageFromXImage(XImage *xi) const
if ((QSysInfo::ByteOrder == QSysInfo::LittleEndian && xi->byte_order == MSBFirst) if ((QSysInfo::ByteOrder == QSysInfo::LittleEndian && xi->byte_order == MSBFirst)
|| (QSysInfo::ByteOrder == QSysInfo::BigEndian && xi->byte_order == LSBFirst)) || (QSysInfo::ByteOrder == QSysInfo::BigEndian && xi->byte_order == LSBFirst))
{ {
const int bpl = image.bytesPerLine();
uchar* dest = image.bits();
for (int i=0; i < image.height(); i++) { for (int i=0; i < image.height(); i++) {
if (depth() == 16) { if (depth() == 16) {
ushort *p = (ushort*)image.scanLine(i); ushort *p = reinterpret_cast<ushort*>(QFAST_SCAN_LINE(dest, bpl, i));
const ushort *end = p + image.width(); const ushort *end = p + image.width();
while (p < end) { while (p < end) {
*p = ((*p << 8) & 0xff00) | ((*p >> 8) & 0x00ff); *p = ((*p << 8) & 0xff00) | ((*p >> 8) & 0x00ff);
p++; p++;
} }
} else { } else {
uint *p = (uint*)image.scanLine(i); uint *p = reinterpret_cast<uint*>(QFAST_SCAN_LINE(dest, bpl, i));
const uint *end = p + image.width(); const uint *end = p + image.width();
while (p < end) { while (p < end) {
*p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000) *p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000)
@ -1563,9 +1565,12 @@ QImage QX11PixmapData::toImage(const XImage *xi, const QRect &rect) const
} }
} else if (xi->bits_per_pixel == d) { // compatible depth } else if (xi->bits_per_pixel == d) { // compatible depth
char *xidata = xi->data; // copy each scanline char *xidata = xi->data; // copy each scanline
int bpl = qMin(image.bytesPerLine(),xi->bytes_per_line); const int qbpl = image.bytesPerLine();
const int bpl = qMin(qbpl, xi->bytes_per_line);
uchar* qdata = image.bits();
for (int y=0; y<xi->height; y++) { for (int y=0; y<xi->height; y++) {
memcpy(image.scanLine(y), xidata, bpl); uchar* tscan = QFAST_SCAN_LINE(qdata, qbpl, y);
memcpy(tscan, xidata, bpl);
xidata += xi->bytes_per_line; xidata += xi->bytes_per_line;
} }
} else { } else {

View file

@ -25,6 +25,7 @@
#include "qimagereader.h" #include "qimagereader.h"
#include "qpixmap_raster_p.h" #include "qpixmap_raster_p.h"
#include "qapplication_p.h" #include "qapplication_p.h"
#include "qdrawhelper_p.h"
#include "qguicommon_p.h" #include "qguicommon_p.h"
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -132,11 +133,12 @@ void QPixmapData::setMask(const QBitmap &mask)
switch (image.depth()) { switch (image.depth()) {
case 1: { case 1: {
const QImage imageMask = mask.toImage().convertToFormat(image.format()); const QImage imageMask = mask.toImage().convertToFormat(image.format());
const int bpl = image.bytesPerLine();
uchar *dest = image.bits();
for (int y = 0; y < h; ++y) { for (int y = 0; y < h; ++y) {
const uchar *mscan = imageMask.scanLine(y); const uchar *mscan = imageMask.constScanLine(y);
uchar *tscan = image.scanLine(y); uchar *tscan = QFAST_SCAN_LINE(dest, bpl, y);
int bytesPerLine = image.bytesPerLine(); for (int i = 0; i < bpl; ++i)
for (int i = 0; i < bytesPerLine; ++i)
tscan[i] &= mscan[i]; tscan[i] &= mscan[i];
} }
break; break;
@ -144,9 +146,11 @@ void QPixmapData::setMask(const QBitmap &mask)
default: { default: {
const QImage imageMask = mask.toImage().convertToFormat(QImage::Format_MonoLSB); const QImage imageMask = mask.toImage().convertToFormat(QImage::Format_MonoLSB);
image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
const int bpl = image.bytesPerLine();
uchar *dest = image.bits();
for (int y = 0; y < h; ++y) { for (int y = 0; y < h; ++y) {
const uchar *mscan = imageMask.scanLine(y); const uchar *mscan = imageMask.constScanLine(y);
QRgb *tscan = (QRgb *)image.scanLine(y); QRgb *tscan = reinterpret_cast<QRgb*>(QFAST_SCAN_LINE(dest, bpl, y));
for (int x = 0; x < w; ++x) { for (int x = 0; x < w; ++x) {
if (!(mscan[x>>3] & qt_pixmap_bit_mask[x&7])) if (!(mscan[x>>3] & qt_pixmap_bit_mask[x&7]))
tscan[x] = 0; tscan[x] = 0;
@ -178,14 +182,14 @@ QBitmap QPixmapData::mask() const
mask.setColor(1, QColor(Qt::color1).rgba()); mask.setColor(1, QColor(Qt::color1).rgba());
const int bpl = mask.bytesPerLine(); const int bpl = mask.bytesPerLine();
uchar *dest = mask.bits();
for (int y = 0; y < h; ++y) { for (int y = 0; y < h; ++y) {
const QRgb *src = reinterpret_cast<const QRgb*>(image.scanLine(y)); const QRgb *src = reinterpret_cast<const QRgb*>(image.constScanLine(y));
uchar *dest = mask.scanLine(y); uchar *tscan = QFAST_SCAN_LINE(dest, bpl, y);
memset(dest, 0, bpl); ::memset(tscan, 0, bpl);
for (int x = 0; x < w; ++x) { for (int x = 0; x < w; ++x) {
if (qAlpha(*src) > 0) if (qAlpha(*src) > 0)
dest[x >> 3] |= qt_pixmap_bit_mask[x & 7]; tscan[x >> 3] |= qt_pixmap_bit_mask[x & 7];
++src; ++src;
} }
} }