diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-03-23 12:32:28 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-03-25 12:52:59 +0100 |
commit | 328ab29c2542c2b7229530053a9232a71f70aae9 (patch) | |
tree | 24615ceaf4a19b30264dd47df76334d1337a357c /src | |
parent | 917ec6c2d4b9ed814a2da9c4d553fc16ee8f7d1e (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.cpp | 103 |
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); |