summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2022-03-23 12:32:28 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2022-03-25 12:52:59 +0100
commit328ab29c2542c2b7229530053a9232a71f70aae9 (patch)
tree24615ceaf4a19b30264dd47df76334d1337a357c /src
parent917ec6c2d4b9ed814a2da9c4d553fc16ee8f7d1e (diff)
Avoid fetching destination when not used
Previously this optimization would only trigger if all spans were opaque, with this change it can also trigger with singular spans. Change-Id: I79f362072ece7b6082463d32fc91000d5ff319b5 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/gui/painting/qdrawhelper.cpp103
1 files changed, 82 insertions, 21 deletions
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 18911e3ee9..2b616e5cc2 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2021 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
@@ -484,10 +484,54 @@ static QRgbaFloat32 *QT_FASTCALL destFetchFP(QRgbaFloat32 *buffer, QRasterBuffer
return const_cast<QRgbaFloat32 *>(qFetchToRGBA32F[rasterBuffer->format](buffer, rasterBuffer->scanLine(y), x, length, nullptr, nullptr));
}
+static QRgbaFloat32 *QT_FASTCALL destFetchRGBFP(QRgbaFloat32 *, QRasterBuffer *rasterBuffer, int x, int y, int)
+{
+ return reinterpret_cast<QRgbaFloat32 *>(rasterBuffer->scanLine(y)) + x;
+}
+
static QRgbaFloat32 *QT_FASTCALL destFetchFPUndefined(QRgbaFloat32 *buffer, QRasterBuffer *, int, int, int)
{
return buffer;
}
+static DestFetchProcFP destFetchProcFP[QImage::NImageFormats] =
+{
+ nullptr, // Format_Invalid
+ nullptr, // Format_Mono,
+ nullptr, // Format_MonoLSB
+ nullptr, // Format_Indexed8
+ destFetchFP, // Format_RGB32
+ destFetchFP, // Format_ARGB32,
+ destFetchFP, // Format_ARGB32_Premultiplied
+ destFetchFP, // Format_RGB16
+ destFetchFP, // Format_ARGB8565_Premultiplied
+ destFetchFP, // Format_RGB666
+ destFetchFP, // Format_ARGB6666_Premultiplied
+ destFetchFP, // Format_RGB555
+ destFetchFP, // Format_ARGB8555_Premultiplied
+ destFetchFP, // Format_RGB888
+ destFetchFP, // Format_RGB444
+ destFetchFP, // Format_ARGB4444_Premultiplied
+ destFetchFP, // Format_RGBX8888
+ destFetchFP, // Format_RGBA8888
+ destFetchFP, // Format_RGBA8888_Premultiplied
+ destFetchFP, // Format_BGR30
+ destFetchFP, // Format_A2BGR30_Premultiplied
+ destFetchFP, // Format_RGB30
+ destFetchFP, // Format_A2RGB30_Premultiplied
+ destFetchFP, // Format_Alpha8
+ destFetchFP, // Format_Grayscale8
+ destFetchFP, // Format_RGBX64
+ destFetchFP, // Format_RGBA64
+ destFetchFP, // Format_RGBA64_Premultiplied
+ destFetchFP, // Format_Grayscale16
+ destFetchFP, // Format_BGR888
+ destFetchFP, // Format_RGBX16FPx4
+ destFetchFP, // Format_RGBA16FPx4
+ destFetchFP, // Format_RGBA16FPx4_Premultiplied
+ destFetchRGBFP, // Format_RGBX32FPx4
+ destFetchFP, // Format_RGBA32FPx4
+ destFetchRGBFP, // Format_RGBA32FPx4_Premultiplied
+};
#endif
/*
@@ -3660,11 +3704,10 @@ static inline Operator getOperator(const QSpanData *data, const QSpan *spans, in
op.destFetch64 = nullptr;
#endif
#if QT_CONFIG(raster_fp)
- if (data->rasterBuffer->format > QImage::Format_Indexed8)
- op.destFetchFP = destFetchFP;
- else
+ op.destFetchFP = destFetchProcFP[data->rasterBuffer->format];
+#else
+ op.destFetchFP = nullptr;
#endif
- op.destFetchFP = nullptr;
if (op.mode == QPainter::CompositionMode_Source &&
(data->type != QSpanData::Texture || data->texture.const_alpha == 256)) {
const QSpan *lastSpan = spans + spanCount;
@@ -3686,7 +3729,8 @@ static inline Operator getOperator(const QSpanData *data, const QSpan *spans, in
op.destFetch64 = destFetch64Undefined;
#endif
#if QT_CONFIG(raster_fp)
- op.destFetchFP = destFetchFPUndefined;
+ if (op.destFetchFP != destFetchRGBFP)
+ op.destFetchFP = destFetchFPUndefined;
#endif
}
}
@@ -3915,6 +3959,7 @@ void handleSpans(int count, const QSpan *spans, const QSpanData *data, T &handle
uint const_alpha = 256;
if (data->type == QSpanData::Texture)
const_alpha = data->texture.const_alpha;
+ const bool solidSource = handler.op.mode == QPainter::CompositionMode_Source && const_alpha == 256;
int coverage = 0;
while (count) {
@@ -3926,9 +3971,10 @@ void handleSpans(int count, const QSpan *spans, const QSpanData *data, T &handle
int x = spans->x;
const int y = spans->y;
int right = x + spans->len;
+ const bool fetchDest = !solidSource || spans->coverage < 255;
// compute length of adjacent spans
- for (int i = 1; i < count && spans[i].y == y && spans[i].x == right; ++i)
+ for (int i = 1; i < count && spans[i].y == y && spans[i].x == right && fetchDest == (!solidSource || spans[i].coverage < 255); ++i)
right += spans[i].len;
int length = right - x;
@@ -3939,7 +3985,7 @@ void handleSpans(int count, const QSpan *spans, const QSpanData *data, T &handle
int process_length = l;
int process_x = x;
- const auto *src = handler.fetch(process_x, y, process_length);
+ const auto *src = handler.fetch(process_x, y, process_length, fetchDest);
int offset = 0;
while (l > 0) {
if (x == spans->x) // new span?
@@ -3966,8 +4012,8 @@ void handleSpans(int count, const QSpan *spans, const QSpanData *data, T &handle
struct QBlendBase
{
- QSpanData *data;
- Operator op;
+ const QSpanData *data;
+ const Operator op;
};
class BlendSrcGeneric : public QBlendBase
@@ -3976,14 +4022,17 @@ public:
uint *dest = nullptr;
alignas(16) uint buffer[BufferSize];
alignas(16) uint src_buffer[BufferSize];
- BlendSrcGeneric(QSpanData *d, const Operator &o)
+ BlendSrcGeneric(const QSpanData *d, const Operator &o)
: QBlendBase{d, o}
{
}
- const uint *fetch(int x, int y, int len)
+ const uint *fetch(int x, int y, int len, bool fetchDest)
{
- dest = op.destFetch(buffer, data->rasterBuffer, x, y, len);
+ if (fetchDest || op.destFetch == destFetchARGB32P)
+ dest = op.destFetch(buffer, data->rasterBuffer, x, y, len);
+ else
+ dest = buffer;
return op.srcFetch(src_buffer, &op, data, y, x, len);
}
@@ -4006,7 +4055,7 @@ public:
QRgba64 *dest = nullptr;
alignas(16) QRgba64 buffer[BufferSize];
alignas(16) QRgba64 src_buffer[BufferSize];
- BlendSrcGenericRGB64(QSpanData *d, const Operator &o)
+ BlendSrcGenericRGB64(const QSpanData *d, const Operator &o)
: QBlendBase{d, o}
{
}
@@ -4016,9 +4065,12 @@ public:
return op.func64 && op.destFetch64;
}
- const QRgba64 *fetch(int x, int y, int len)
+ const QRgba64 *fetch(int x, int y, int len, bool fetchDest)
{
- dest = op.destFetch64(buffer, data->rasterBuffer, x, y, len);
+ if (fetchDest || op.destFetch64 == destFetchRGB64)
+ dest = op.destFetch64(buffer, data->rasterBuffer, x, y, len);
+ else
+ dest = buffer;
return op.srcFetch64(src_buffer, &op, data, y, x, len);
}
@@ -4052,9 +4104,12 @@ public:
return op.funcFP && op.destFetchFP && op.srcFetchFP;
}
- const QRgbaFloat32 *fetch(int x, int y, int len)
+ const QRgbaFloat32 *fetch(int x, int y, int len, bool fetchDest)
{
- dest = op.destFetchFP(buffer, data->rasterBuffer, x, y, len);
+ if (fetchDest || op.destFetchFP == destFetchRGBFP)
+ dest = op.destFetchFP(buffer, data->rasterBuffer, x, y, len);
+ else
+ dest = buffer;
return op.srcFetchFP(src_buffer, &op, data, y, x, len);
}
@@ -4122,6 +4177,7 @@ static void blend_untransformed_generic(int count, const QSpan *spans, void *use
const int image_height = data->texture.height;
int xoff = -qRound(-data->dx);
int yoff = -qRound(-data->dy);
+ const bool solidSource = op.mode == QPainter::CompositionMode_Source && data->texture.const_alpha == 256 && op.destFetch != destFetchARGB32P;
for (; count--; spans++) {
if (!spans->len)
@@ -4130,6 +4186,7 @@ static void blend_untransformed_generic(int count, const QSpan *spans, void *use
int length = spans->len;
int sx = xoff + x;
int sy = yoff + spans->y;
+ const bool fetchDest = !solidSource || spans->coverage < 255;
if (sy >= 0 && sy < image_height && sx < image_width) {
if (sx < 0) {
x -= sx;
@@ -4143,7 +4200,7 @@ static void blend_untransformed_generic(int count, const QSpan *spans, void *use
while (length) {
int l = qMin(BufferSize, length);
const uint *src = op.srcFetch(src_buffer, &op, data, sy, sx, l);
- uint *dest = op.destFetch(buffer, data->rasterBuffer, x, spans->y, l);
+ uint *dest = fetchDest ? op.destFetch(buffer, data->rasterBuffer, x, spans->y, l) : buffer;
op.func(dest, src, l, coverage);
if (op.destStore)
op.destStore(data->rasterBuffer, x, spans->y, dest, l);
@@ -4173,6 +4230,7 @@ static void blend_untransformed_generic_rgb64(int count, const QSpan *spans, voi
const int image_height = data->texture.height;
int xoff = -qRound(-data->dx);
int yoff = -qRound(-data->dy);
+ const bool solidSource = op.mode == QPainter::CompositionMode_Source && data->texture.const_alpha == 256 && op.destFetch64 != destFetchRGB64;
for (; count--; spans++) {
if (!spans->len)
@@ -4181,6 +4239,7 @@ static void blend_untransformed_generic_rgb64(int count, const QSpan *spans, voi
int length = spans->len;
int sx = xoff + x;
int sy = yoff + spans->y;
+ const bool fetchDest = !solidSource || spans->coverage < 255;
if (sy >= 0 && sy < image_height && sx < image_width) {
if (sx < 0) {
x -= sx;
@@ -4194,7 +4253,7 @@ static void blend_untransformed_generic_rgb64(int count, const QSpan *spans, voi
while (length) {
int l = qMin(BufferSize, length);
const QRgba64 *src = op.srcFetch64(src_buffer, &op, data, sy, sx, l);
- QRgba64 *dest = op.destFetch64(buffer, data->rasterBuffer, x, spans->y, l);
+ QRgba64 *dest = fetchDest ? op.destFetch64(buffer, data->rasterBuffer, x, spans->y, l) : buffer;
op.func64(dest, src, l, coverage);
if (op.destStore64)
op.destStore64(data->rasterBuffer, x, spans->y, dest, l);
@@ -4225,6 +4284,7 @@ static void blend_untransformed_generic_fp(int count, const QSpan *spans, void *
const int image_height = data->texture.height;
int xoff = -qRound(-data->dx);
int yoff = -qRound(-data->dy);
+ const bool solidSource = op.mode == QPainter::CompositionMode_Source && data->texture.const_alpha == 256 && op.destFetchFP != destFetchRGBFP;
for (; count--; spans++) {
if (!spans->len)
@@ -4233,6 +4293,7 @@ static void blend_untransformed_generic_fp(int count, const QSpan *spans, void *
int length = spans->len;
int sx = xoff + x;
int sy = yoff + spans->y;
+ const bool fetchDest = !solidSource || spans->coverage < 255;
if (sy >= 0 && sy < image_height && sx < image_width) {
if (sx < 0) {
x -= sx;
@@ -4246,7 +4307,7 @@ static void blend_untransformed_generic_fp(int count, const QSpan *spans, void *
while (length) {
int l = qMin(BufferSize, length);
const QRgbaFloat32 *src = op.srcFetchFP(src_buffer, &op, data, sy, sx, l);
- QRgbaFloat32 *dest = op.destFetchFP(buffer, data->rasterBuffer, x, spans->y, l);
+ QRgbaFloat32 *dest = fetchDest ? op.destFetchFP(buffer, data->rasterBuffer, x, spans->y, l) : buffer;
op.funcFP(dest, src, l, coverage);
if (op.destStoreFP)
op.destStoreFP(data->rasterBuffer, x, spans->y, dest, l);