Coverage Report

Created: 2025-07-12 07:23

/src/qtbase/src/gui/painting/qimagescale_sse4.cpp
Line
Count
Source (jump to first uncovered line)
1
/****************************************************************************
2
**
3
** Copyright (C) 2016 The Qt Company Ltd.
4
** Contact: https://www.qt.io/licensing/
5
**
6
** This file is part of the QtGui module of the Qt Toolkit.
7
**
8
** $QT_BEGIN_LICENSE:LGPL$
9
** Commercial License Usage
10
** Licensees holding valid commercial Qt licenses may use this file in
11
** accordance with the commercial license agreement provided with the
12
** Software or, alternatively, in accordance with the terms contained in
13
** a written agreement between you and The Qt Company. For licensing terms
14
** and conditions see https://www.qt.io/terms-conditions. For further
15
** information use the contact form at https://www.qt.io/contact-us.
16
**
17
** GNU Lesser General Public License Usage
18
** Alternatively, this file may be used under the terms of the GNU Lesser
19
** General Public License version 3 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL3 included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 3 requirements
23
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24
**
25
** GNU General Public License Usage
26
** Alternatively, this file may be used under the terms of the GNU
27
** General Public License version 2.0 or (at your option) the GNU General
28
** Public license version 3 or any later version approved by the KDE Free
29
** Qt Foundation. The licenses are as published by the Free Software
30
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31
** included in the packaging of this file. Please review the following
32
** information to ensure the GNU General Public License requirements will
33
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34
** https://www.gnu.org/licenses/gpl-3.0.html.
35
**
36
** $QT_END_LICENSE$
37
**
38
****************************************************************************/
39
40
#include "qimagescale_p.h"
41
#include "qimage.h"
42
#include <private/qdrawhelper_x86_p.h>
43
#include <private/qsimd_p.h>
44
45
#if QT_CONFIG(thread) && !defined(Q_OS_WASM)
46
#include "qsemaphore.h"
47
#include "qthreadpool.h"
48
#endif
49
50
#if defined(QT_COMPILER_SUPPORTS_SSE4_1)
51
52
QT_BEGIN_NAMESPACE
53
54
using namespace QImageScale;
55
56
template<typename T>
57
static inline void multithread_pixels_function(QImageScaleInfo *isi, int dh, const T &scaleSection)
58
0
{
59
0
#if QT_CONFIG(thread) && !defined(Q_OS_WASM)
60
0
    int segments = (qsizetype(isi->sh) * isi->sw) / (1<<16);
61
0
    segments = std::min(segments, dh);
62
0
    QThreadPool *threadPool = QThreadPool::globalInstance();
63
0
    if (segments > 1 && threadPool && !threadPool->contains(QThread::currentThread())) {
64
0
        QSemaphore semaphore;
65
0
        int y = 0;
66
0
        for (int i = 0; i < segments; ++i) {
67
0
            int yn = (dh - y) / (segments - i);
68
0
            threadPool->start([&, y, yn]() {
69
0
                scaleSection(y, y + yn);
70
0
                semaphore.release(1);
71
0
            });
Unexecuted instantiation: qimagescale_sse4.cpp:multithread_pixels_function<qt_qimageScaleAARGBA_up_x_down_y_sse4<false>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1}>(QImageScale::QImageScaleInfo*, int, qt_qimageScaleAARGBA_up_x_down_y_sse4<false>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1} const&)::{lambda()#1}::operator()() const
Unexecuted instantiation: qimagescale_sse4.cpp:multithread_pixels_function<qt_qimageScaleAARGBA_up_x_down_y_sse4<true>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1}>(QImageScale::QImageScaleInfo*, int, qt_qimageScaleAARGBA_up_x_down_y_sse4<true>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1} const&)::{lambda()#1}::operator()() const
Unexecuted instantiation: qimagescale_sse4.cpp:multithread_pixels_function<qt_qimageScaleAARGBA_down_x_up_y_sse4<false>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1}>(QImageScale::QImageScaleInfo*, int, qt_qimageScaleAARGBA_down_x_up_y_sse4<false>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1} const&)::{lambda()#1}::operator()() const
Unexecuted instantiation: qimagescale_sse4.cpp:multithread_pixels_function<qt_qimageScaleAARGBA_down_x_up_y_sse4<true>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1}>(QImageScale::QImageScaleInfo*, int, qt_qimageScaleAARGBA_down_x_up_y_sse4<true>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1} const&)::{lambda()#1}::operator()() const
Unexecuted instantiation: qimagescale_sse4.cpp:multithread_pixels_function<qt_qimageScaleAARGBA_down_xy_sse4<false>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1}>(QImageScale::QImageScaleInfo*, int, qt_qimageScaleAARGBA_down_xy_sse4<false>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1} const&)::{lambda()#1}::operator()() const
Unexecuted instantiation: qimagescale_sse4.cpp:multithread_pixels_function<qt_qimageScaleAARGBA_down_xy_sse4<true>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1}>(QImageScale::QImageScaleInfo*, int, qt_qimageScaleAARGBA_down_xy_sse4<true>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1} const&)::{lambda()#1}::operator()() const
72
0
            y += yn;
73
0
        }
74
0
        semaphore.acquire(segments);
75
0
        return;
76
0
    }
77
0
#endif
78
0
    scaleSection(0, dh);
79
0
}
Unexecuted instantiation: qimagescale_sse4.cpp:void multithread_pixels_function<qt_qimageScaleAARGBA_up_x_down_y_sse4<false>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1}>(QImageScale::QImageScaleInfo*, int, qt_qimageScaleAARGBA_up_x_down_y_sse4<false>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1} const&)
Unexecuted instantiation: qimagescale_sse4.cpp:void multithread_pixels_function<qt_qimageScaleAARGBA_up_x_down_y_sse4<true>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1}>(QImageScale::QImageScaleInfo*, int, qt_qimageScaleAARGBA_up_x_down_y_sse4<true>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1} const&)
Unexecuted instantiation: qimagescale_sse4.cpp:void multithread_pixels_function<qt_qimageScaleAARGBA_down_x_up_y_sse4<false>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1}>(QImageScale::QImageScaleInfo*, int, qt_qimageScaleAARGBA_down_x_up_y_sse4<false>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1} const&)
Unexecuted instantiation: qimagescale_sse4.cpp:void multithread_pixels_function<qt_qimageScaleAARGBA_down_x_up_y_sse4<true>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1}>(QImageScale::QImageScaleInfo*, int, qt_qimageScaleAARGBA_down_x_up_y_sse4<true>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1} const&)
Unexecuted instantiation: qimagescale_sse4.cpp:void multithread_pixels_function<qt_qimageScaleAARGBA_down_xy_sse4<false>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1}>(QImageScale::QImageScaleInfo*, int, qt_qimageScaleAARGBA_down_xy_sse4<false>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1} const&)
Unexecuted instantiation: qimagescale_sse4.cpp:void multithread_pixels_function<qt_qimageScaleAARGBA_down_xy_sse4<true>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1}>(QImageScale::QImageScaleInfo*, int, qt_qimageScaleAARGBA_down_xy_sse4<true>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1} const&)
80
81
inline static __m128i Q_DECL_VECTORCALL
82
qt_qimageScaleAARGBA_helper(const unsigned int *pix, int xyap, int Cxy, int step, const __m128i vxyap, const __m128i vCxy)
83
0
{
84
0
    __m128i vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix));
85
0
    __m128i vx = _mm_mullo_epi32(vpix, vxyap);
86
0
    int i;
87
0
    for (i = (1 << 14) - xyap; i > Cxy; i -= Cxy) {
88
0
        pix += step;
89
0
        vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix));
90
0
        vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, vCxy));
91
0
    }
92
0
    pix += step;
93
0
    vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix));
94
0
    vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, _mm_set1_epi32(i)));
95
0
    return vx;
96
0
}
97
98
template<bool RGB>
99
void qt_qimageScaleAARGBA_up_x_down_y_sse4(QImageScaleInfo *isi, unsigned int *dest,
100
                                           int dw, int dh, int dow, int sow)
101
0
{
102
0
    const unsigned int **ypoints = isi->ypoints;
103
0
    const int *xpoints = isi->xpoints;
104
0
    const int *xapoints = isi->xapoints;
105
0
    const int *yapoints = isi->yapoints;
106
107
0
    const __m128i v256 = _mm_set1_epi32(256);
108
109
    /* go through every scanline in the output buffer */
110
0
    auto scaleSection = [&] (int yStart, int yEnd) {
111
0
        for (int y = yStart; y < yEnd; ++y) {
112
0
            const int Cy = yapoints[y] >> 16;
113
0
            const int yap = yapoints[y] & 0xffff;
114
0
            const __m128i vCy = _mm_set1_epi32(Cy);
115
0
            const __m128i vyap = _mm_set1_epi32(yap);
116
117
0
            unsigned int *dptr = dest + (y * dow);
118
0
            for (int x = 0; x < dw; x++) {
119
0
                const unsigned int *sptr = ypoints[y] + xpoints[x];
120
0
                __m128i vx = qt_qimageScaleAARGBA_helper(sptr, yap, Cy, sow, vyap, vCy);
121
122
0
                const int xap = xapoints[x];
123
0
                if (xap > 0) {
124
0
                    const __m128i vxap = _mm_set1_epi32(xap);
125
0
                    const __m128i vinvxap = _mm_sub_epi32(v256, vxap);
126
0
                    __m128i vr = qt_qimageScaleAARGBA_helper(sptr + 1, yap, Cy, sow, vyap, vCy);
127
128
0
                    vx = _mm_mullo_epi32(vx, vinvxap);
129
0
                    vr = _mm_mullo_epi32(vr, vxap);
130
0
                    vx = _mm_add_epi32(vx, vr);
131
0
                    vx = _mm_srli_epi32(vx, 8);
132
0
                }
133
0
                vx = _mm_srli_epi32(vx, 14);
134
0
                vx = _mm_packus_epi32(vx, vx);
135
0
                vx = _mm_packus_epi16(vx, vx);
136
0
                *dptr = _mm_cvtsi128_si32(vx);
137
0
                if (RGB)
138
0
                    *dptr |= 0xff000000;
139
0
                dptr++;
140
0
            }
141
0
        }
142
0
    };
Unexecuted instantiation: qt_qimageScaleAARGBA_up_x_down_y_sse4<false>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1}::operator()(int, int) const
Unexecuted instantiation: qt_qimageScaleAARGBA_up_x_down_y_sse4<true>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1}::operator()(int, int) const
143
0
    multithread_pixels_function(isi, dh, scaleSection);
144
0
}
Unexecuted instantiation: void qt_qimageScaleAARGBA_up_x_down_y_sse4<false>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)
Unexecuted instantiation: void qt_qimageScaleAARGBA_up_x_down_y_sse4<true>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)
145
146
template<bool RGB>
147
void qt_qimageScaleAARGBA_down_x_up_y_sse4(QImageScaleInfo *isi, unsigned int *dest,
148
                                           int dw, int dh, int dow, int sow)
149
0
{
150
0
    const unsigned int **ypoints = isi->ypoints;
151
0
    int *xpoints = isi->xpoints;
152
0
    int *xapoints = isi->xapoints;
153
0
    int *yapoints = isi->yapoints;
154
155
0
    const __m128i v256 = _mm_set1_epi32(256);
156
157
    /* go through every scanline in the output buffer */
158
0
    auto scaleSection = [&] (int yStart, int yEnd) {
159
0
        for (int y = yStart; y < yEnd; ++y) {
160
0
            unsigned int *dptr = dest + (y * dow);
161
0
            for (int x = 0; x < dw; x++) {
162
0
                int Cx = xapoints[x] >> 16;
163
0
                int xap = xapoints[x] & 0xffff;
164
0
                const __m128i vCx = _mm_set1_epi32(Cx);
165
0
                const __m128i vxap = _mm_set1_epi32(xap);
166
167
0
                const unsigned int *sptr = ypoints[y] + xpoints[x];
168
0
                __m128i vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, vxap, vCx);
169
170
0
                int yap = yapoints[y];
171
0
                if (yap > 0) {
172
0
                    const __m128i vyap = _mm_set1_epi32(yap);
173
0
                    const __m128i vinvyap = _mm_sub_epi32(v256, vyap);
174
0
                    __m128i vr = qt_qimageScaleAARGBA_helper(sptr + sow, xap, Cx, 1, vxap, vCx);
175
176
0
                    vx = _mm_mullo_epi32(vx, vinvyap);
177
0
                    vr = _mm_mullo_epi32(vr, vyap);
178
0
                    vx = _mm_add_epi32(vx, vr);
179
0
                    vx = _mm_srli_epi32(vx, 8);
180
0
                }
181
0
                vx = _mm_srli_epi32(vx, 14);
182
0
                vx = _mm_packus_epi32(vx, vx);
183
0
                vx = _mm_packus_epi16(vx, vx);
184
0
                *dptr = _mm_cvtsi128_si32(vx);
185
0
                if (RGB)
186
0
                    *dptr |= 0xff000000;
187
0
                dptr++;
188
0
            }
189
0
        }
190
0
    };
Unexecuted instantiation: qt_qimageScaleAARGBA_down_x_up_y_sse4<false>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1}::operator()(int, int) const
Unexecuted instantiation: qt_qimageScaleAARGBA_down_x_up_y_sse4<true>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1}::operator()(int, int) const
191
0
    multithread_pixels_function(isi, dh, scaleSection);
192
0
}
Unexecuted instantiation: void qt_qimageScaleAARGBA_down_x_up_y_sse4<false>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)
Unexecuted instantiation: void qt_qimageScaleAARGBA_down_x_up_y_sse4<true>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)
193
194
template<bool RGB>
195
void qt_qimageScaleAARGBA_down_xy_sse4(QImageScaleInfo *isi, unsigned int *dest,
196
                                       int dw, int dh, int dow, int sow)
197
0
{
198
0
    const unsigned int **ypoints = isi->ypoints;
199
0
    int *xpoints = isi->xpoints;
200
0
    int *xapoints = isi->xapoints;
201
0
    int *yapoints = isi->yapoints;
202
203
0
    auto scaleSection = [&] (int yStart, int yEnd) {
204
0
        for (int y = yStart; y < yEnd; ++y) {
205
0
            int Cy = yapoints[y] >> 16;
206
0
            int yap = yapoints[y] & 0xffff;
207
0
            const __m128i vCy = _mm_set1_epi32(Cy);
208
0
            const __m128i vyap = _mm_set1_epi32(yap);
209
210
0
            unsigned int *dptr = dest + (y * dow);
211
0
            for (int x = 0; x < dw; x++) {
212
0
                const int Cx = xapoints[x] >> 16;
213
0
                const int xap = xapoints[x] & 0xffff;
214
0
                const __m128i vCx = _mm_set1_epi32(Cx);
215
0
                const __m128i vxap = _mm_set1_epi32(xap);
216
217
0
                const unsigned int *sptr = ypoints[y] + xpoints[x];
218
0
                __m128i vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, vxap, vCx);
219
0
                __m128i vr = _mm_mullo_epi32(_mm_srli_epi32(vx, 4), vyap);
220
221
0
                int j;
222
0
                for (j = (1 << 14) - yap; j > Cy; j -= Cy) {
223
0
                    sptr += sow;
224
0
                    vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, vxap, vCx);
225
0
                    vr = _mm_add_epi32(vr, _mm_mullo_epi32(_mm_srli_epi32(vx, 4), vCy));
226
0
                }
227
0
                sptr += sow;
228
0
                vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, vxap, vCx);
229
0
                vr = _mm_add_epi32(vr, _mm_mullo_epi32(_mm_srli_epi32(vx, 4), _mm_set1_epi32(j)));
230
231
0
                vr = _mm_srli_epi32(vr, 24);
232
0
                vr = _mm_packus_epi32(vr, _mm_setzero_si128());
233
0
                vr = _mm_packus_epi16(vr, _mm_setzero_si128());
234
0
                *dptr = _mm_cvtsi128_si32(vr);
235
0
                if (RGB)
236
0
                    *dptr |= 0xff000000;
237
0
                dptr++;
238
0
            }
239
0
        }
240
0
    };
Unexecuted instantiation: qt_qimageScaleAARGBA_down_xy_sse4<false>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1}::operator()(int, int) const
Unexecuted instantiation: qt_qimageScaleAARGBA_down_xy_sse4<true>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)::{lambda(int, int)#1}::operator()(int, int) const
241
0
    multithread_pixels_function(isi, dh, scaleSection);
242
0
}
Unexecuted instantiation: void qt_qimageScaleAARGBA_down_xy_sse4<false>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)
Unexecuted instantiation: void qt_qimageScaleAARGBA_down_xy_sse4<true>(QImageScale::QImageScaleInfo*, unsigned int*, int, int, int, int)
243
244
template void qt_qimageScaleAARGBA_up_x_down_y_sse4<false>(QImageScaleInfo *isi, unsigned int *dest,
245
                                                           int dw, int dh, int dow, int sow);
246
247
template void qt_qimageScaleAARGBA_up_x_down_y_sse4<true>(QImageScaleInfo *isi, unsigned int *dest,
248
                                                          int dw, int dh, int dow, int sow);
249
250
template void qt_qimageScaleAARGBA_down_x_up_y_sse4<false>(QImageScaleInfo *isi, unsigned int *dest,
251
                                                           int dw, int dh, int dow, int sow);
252
253
template void qt_qimageScaleAARGBA_down_x_up_y_sse4<true>(QImageScaleInfo *isi, unsigned int *dest,
254
                                                          int dw, int dh, int dow, int sow);
255
256
template void qt_qimageScaleAARGBA_down_xy_sse4<false>(QImageScaleInfo *isi, unsigned int *dest,
257
                                                       int dw, int dh, int dow, int sow);
258
259
template void qt_qimageScaleAARGBA_down_xy_sse4<true>(QImageScaleInfo *isi, unsigned int *dest,
260
                                                      int dw, int dh, int dow, int sow);
261
262
QT_END_NAMESPACE
263
264
#endif