GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 72.2% 601 / 0 / 832
Functions: 67.9% 38 / 0 / 56
Branches: 34.2% 263 / 0 / 770

filters/overlay/intel/masked_merge_avx2_impl.hpp
Line Branch Exec Source
1 // AviSynth+ Copyright 2026- AviSynth+ Project
2 // SPDX-License-Identifier: GPL-2.0-or-later
3 //
4 // AVX2 masked-merge implementation templates.
5 //
6 // Implementation-include — NO include guards intentionally.
7 // Each including TU gets its own compilation with that TU's SIMD flags.
8 // All definitions are static so each TU has its own private copy;
9 // the linker never sees them as the same symbol.
10 //
11 // Requires the following to be visible in the including TU before this file:
12 // AVX2 intrinsics (<intrin.h> or <x86intrin.h>, <immintrin.h>)
13 // blend_common.h — MaskMode, MagicDiv, get_magic_div, magic_div_rt,
14 // prepare_effective_mask_for_row
15 // <vector>
16
17 // Provides simd_magic_div_32_avx2 + prepare_effective_mask_for_row_avx2.
18 #include "masked_rowprep_avx2_impl.h"
19
20 // ---------------------------------------------------------------------------
21 // 8-bit row — mask already has opacity baked in by rowprep.
22 // 32-wide 16-bit mulhi arithmetic (fast, overflow-safe).
23 // ---------------------------------------------------------------------------
24 #if defined(GCC) || defined(CLANG)
25 __attribute__((__target__("avx2")))
26 #endif
27 244 static void blend8_masked_avx2_row(
28 uint8_t* p1, const uint8_t* p2, const uint8_t* mask,
29 int width)
30 {
31 244 constexpr uint32_t half = 127u;
32 244 constexpr uint32_t max_val = 255u;
33
34 244 const __m256i v_half = _mm256_set1_epi16((short)half);
35 244 const __m256i v_max = _mm256_set1_epi16((short)max_val);
36 244 const __m256i v_magic = _mm256_set1_epi16((short)0x8081);
37
38 138 auto magic_byte = [&](__m256i x) {
39 414 return _mm256_srli_epi16(_mm256_mulhi_epu16(x, v_magic), 7);
40 244 };
41
42 244 int x = 0;
43
2/2
✓ Branch 45 → 15 taken 69 times.
✓ Branch 45 → 46 taken 244 times.
313 for (; x <= width - 32; x += 32) {
44 138 __m256i mr = _mm256_loadu_si256((__m256i*)(mask + x));
45
46 // Unpack 32 bytes to 2x 16x16-bit halves
47 69 __m256i m_lo = _mm256_cvtepu8_epi16(_mm256_castsi256_si128(mr));
48 69 __m256i m_hi = _mm256_cvtepu8_epi16(_mm256_extracti128_si256(mr, 1));
49
50 69 __m256i ar = _mm256_loadu_si256((__m256i*)(p1 + x));
51 69 __m256i br = _mm256_loadu_si256((__m256i*)(p2 + x));
52
53 138 auto blend16 = [&](__m256i a, __m256i b, __m256i m) {
54 138 __m256i invm = _mm256_sub_epi16(v_max, m);
55 690 return magic_byte(_mm256_add_epi16(
56 138 _mm256_add_epi16(_mm256_mullo_epi16(a, invm), _mm256_mullo_epi16(b, m)), v_half));
57 69 };
58
59 276 __m256i r_lo = blend16(_mm256_cvtepu8_epi16(_mm256_castsi256_si128(ar)),
60 _mm256_cvtepu8_epi16(_mm256_castsi256_si128(br)), m_lo);
61 207 __m256i r_hi = blend16(_mm256_cvtepu8_epi16(_mm256_extracti128_si256(ar, 1)),
62 _mm256_cvtepu8_epi16(_mm256_extracti128_si256(br, 1)), m_hi);
63
64 69 __m256i packed = _mm256_packus_epi16(r_lo, r_hi);
65 69 packed = _mm256_permute4x64_epi64(packed, _MM_SHUFFLE(3, 1, 2, 0));
66 69 _mm256_storeu_si256((__m256i*)(p1 + x), packed);
67 }
68
2/2
✓ Branch 48 → 47 taken 2572 times.
✓ Branch 48 → 49 taken 244 times.
2816 for (; x < width; ++x) {
69 2572 const uint32_t ms = mask[x];
70 2572 const uint32_t a = p1[x], b_v = p2[x];
71 2572 const uint32_t tr = a * (max_val - ms) + b_v * ms + half;
72 2572 p1[x] = (uint8_t)((tr * 0x8081u) >> 23);
73 }
74 244 }
75
76 // ---------------------------------------------------------------------------
77 // 16-bit row (10, 12, 14, 16 bits) — mask already has opacity baked in.
78 // 32-bit arithmetic, 8 pixels per step.
79 // ---------------------------------------------------------------------------
80 template<int bits_per_pixel>
81 #if defined(GCC) || defined(CLANG)
82 __attribute__((__target__("avx2")))
83 #endif
84 186 static void blend16_masked_avx2_row(
85 uint16_t* p1, const uint16_t* p2, const uint16_t* mask,
86 int width)
87 {
88 186 constexpr MagicDiv m_div = get_magic_div(bits_per_pixel);
89 186 constexpr uint32_t max_val = (1u << bits_per_pixel) - 1;
90 186 constexpr uint32_t half = max_val / 2;
91
92 186 const __m256i v_half = _mm256_set1_epi32((int)half);
93 186 const __m256i v_max = _mm256_set1_epi32((int)max_val);
94
95 186 int x = 0;
96
8/8
void blend16_masked_avx2_row<10>(unsigned short*, unsigned short const*, unsigned short const*, int):
✓ Branch 53 → 7 taken 20 times.
✓ Branch 53 → 54 taken 10 times.
void blend16_masked_avx2_row<12>(unsigned short*, unsigned short const*, unsigned short const*, int):
✓ Branch 53 → 7 taken 20 times.
✓ Branch 53 → 54 taken 10 times.
void blend16_masked_avx2_row<14>(unsigned short*, unsigned short const*, unsigned short const*, int):
✓ Branch 53 → 7 taken 20 times.
✓ Branch 53 → 54 taken 10 times.
void blend16_masked_avx2_row<16>(unsigned short*, unsigned short const*, unsigned short const*, int):
✓ Branch 53 → 7 taken 242 times.
✓ Branch 53 → 54 taken 156 times.
488 for (; x <= width - 8; x += 8) {
97 604 __m256i m = _mm256_cvtepu16_epi32(_mm_loadu_si128((__m128i*)(mask + x)));
98 604 __m256i a = _mm256_cvtepu16_epi32(_mm_loadu_si128((__m128i*)(p1 + x)));
99 906 __m256i b = _mm256_cvtepu16_epi32(_mm_loadu_si128((__m128i*)(p2 + x)));
100 302 __m256i invm = _mm256_sub_epi32(v_max, m);
101 1510 __m256i res = simd_magic_div_32_avx2(
102 _mm256_add_epi32(
103 _mm256_add_epi32(_mm256_mullo_epi32(a, invm), _mm256_mullo_epi32(b, m)),
104 v_half),
105 302 m_div.div, m_div.shift);
106
107 // Pack 8x32 → 8x16 with correct order
108 604 __m256i packed = _mm256_packus_epi32(res, _mm256_setzero_si256());
109 302 __m128i lo = _mm256_castsi256_si128(packed);
110 302 __m128i hi = _mm256_extracti128_si256(packed, 1);
111 302 _mm_storeu_si128((__m128i*)(p1 + x), _mm_unpacklo_epi64(lo, hi));
112 }
113
8/8
void blend16_masked_avx2_row<10>(unsigned short*, unsigned short const*, unsigned short const*, int):
✓ Branch 58 → 55 taken 30 times.
✓ Branch 58 → 59 taken 10 times.
void blend16_masked_avx2_row<12>(unsigned short*, unsigned short const*, unsigned short const*, int):
✓ Branch 58 → 55 taken 30 times.
✓ Branch 58 → 59 taken 10 times.
void blend16_masked_avx2_row<14>(unsigned short*, unsigned short const*, unsigned short const*, int):
✓ Branch 58 → 55 taken 30 times.
✓ Branch 58 → 59 taken 10 times.
void blend16_masked_avx2_row<16>(unsigned short*, unsigned short const*, unsigned short const*, int):
✓ Branch 58 → 55 taken 288 times.
✓ Branch 58 → 59 taken 156 times.
564 for (; x < width; ++x) {
114 378 const uint32_t ms = mask[x];
115 378 const uint32_t a = p1[x];
116 756 p1[x] = (uint16_t)magic_div_rt<uint16_t>(a * (max_val - ms) + (uint32_t)p2[x] * ms + half, m_div);
117 }
118 186 }
119
120 // ---------------------------------------------------------------------------
121 // float row — mask already has opacity baked in (range 0.0 to 1.0).
122 // Linear interpolation: p1[x] = p1[x] * (1.0f - mask[x]) + p2[x] * mask[x]
123 // 8 pixels per step.
124 // ---------------------------------------------------------------------------
125 #if defined(GCC) || defined(CLANG)
126 __attribute__((__target__("avx2")))
127 #endif
128 30 static void blend_masked_float_avx2_row(
129 float* p1, const float* p2, const float* mask, int width)
130 {
131 30 int x = 0;
132 // const __m256 v_one = _mm256_set1_ps(1.0f); in case of 1-x implementation
133
134
2/2
✓ Branch 17 → 3 taken 50 times.
✓ Branch 17 → 18 taken 30 times.
80 for (; x <= width - 8; x += 8) {
135 50 __m256 m = _mm256_loadu_ps(mask + x);
136 50 __m256 a = _mm256_loadu_ps(p1 + x);
137 100 __m256 b = _mm256_loadu_ps(p2 + x);
138
139 // Standard lerp: a + m * (b - a)
140 // This is generally more accurate and faster (1 mul, 2 adds) than
141 // a * (1-m) + b * m (2 muls, 2 adds).
142 50 __m256 diff = _mm256_sub_ps(b, a);
143 50 __m256 res = _mm256_add_ps(a, _mm256_mul_ps(m, diff));
144
145 50 _mm256_storeu_ps(p1 + x, res);
146 }
147
148 // Scalar tail
149
2/2
✓ Branch 20 → 19 taken 70 times.
✓ Branch 20 → 21 taken 30 times.
100 for (; x < width; ++x) {
150 70 const float m = mask[x];
151 70 const float a = p1[x];
152 70 const float b = p2[x];
153 70 p1[x] = a + m * (b - a);
154 }
155 30 }
156
157 // ---------------------------------------------------------------------------
158 // Inner loop — full_opacity known at compile time.
159 // Rowprep bakes opacity when !full_opacity; blend row receives pre-scaled mask.
160 // MASK444 + full_opacity: returns mask ptr directly (no buffer, no copy).
161 // MASK444 + !full_opacity: copies row with opacity scaling into buffer.
162 // ---------------------------------------------------------------------------
163 template<MaskMode maskMode, bool full_opacity>
164 #if defined(GCC) || defined(CLANG)
165 __attribute__((__target__("avx2")))
166 #endif
167 117 static void masked_merge_avx2_impl_inner(
168 BYTE* p1, const BYTE* p2, const BYTE* mask,
169 int p1_pitch, int p2_pitch, int mask_pitch,
170 int width, int height, int opacity, int bits_per_pixel)
171 {
172 117 const MagicDiv mag = get_magic_div(bits_per_pixel);
173 117 const int max_val = (1 << bits_per_pixel) - 1;
174 117 const int half = max_val / 2;
175
176
28/32
void masked_merge_avx2_impl_inner<(MaskMode)0, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 13 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)0, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 13 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)1, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 3 → 4 taken 5 times.
✓ Branch 3 → 13 taken 2 times.
void masked_merge_avx2_impl_inner<(MaskMode)1, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 3 → 4 taken 2 times.
✓ Branch 3 → 13 taken 2 times.
void masked_merge_avx2_impl_inner<(MaskMode)2, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 3 → 4 taken 2 times.
✓ Branch 3 → 13 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)2, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 13 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)3, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 13 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)3, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 13 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)4, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 3 → 4 taken 2 times.
✓ Branch 3 → 13 taken 3 times.
void masked_merge_avx2_impl_inner<(MaskMode)4, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 3 → 4 taken 2 times.
✓ Branch 3 → 13 taken 2 times.
void masked_merge_avx2_impl_inner<(MaskMode)5, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 13 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)5, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 13 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)6, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 13 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)6, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 13 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)7, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 3 → 4 taken 26 times.
✓ Branch 3 → 13 taken 15 times.
void masked_merge_avx2_impl_inner<(MaskMode)7, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 3 → 4 taken 27 times.
✓ Branch 3 → 12 taken 12 times.
117 if (bits_per_pixel == 8) {
177 73 const uint8_t* maskp = reinterpret_cast<const uint8_t*>(mask);
178 73 const int mpx = mask_pitch;
179 73 const int mask_adv = (maskMode == MASK420 || maskMode == MASK420_MPEG2 || maskMode == MASK420_TOPLEFT) ? mpx * 2 : mpx;
180
181 73 std::vector<uint8_t> eff_buf;
182
13/30
void masked_merge_avx2_impl_inner<(MaskMode)0, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)0, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)1, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 5 → 6 taken 5 times.
✗ Branch 5 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)1, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 5 → 6 taken 2 times.
✗ Branch 5 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)2, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 5 → 6 taken 2 times.
✗ Branch 5 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)2, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)3, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)3, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)4, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 5 → 6 taken 2 times.
✗ Branch 5 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)4, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 5 → 6 taken 2 times.
✗ Branch 5 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)5, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)5, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)6, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)6, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)7, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 5 → 6 taken 26 times.
✗ Branch 5 → 43 not taken.
46 if constexpr (maskMode != MASK444 || !full_opacity) eff_buf.resize(width);
183
184
28/32
void masked_merge_avx2_impl_inner<(MaskMode)0, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 10 → 7 not taken.
✗ Branch 10 → 11 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)0, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 10 → 7 not taken.
✗ Branch 10 → 11 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)1, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 10 → 7 taken 19 times.
✓ Branch 10 → 11 taken 5 times.
void masked_merge_avx2_impl_inner<(MaskMode)1, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 10 → 7 taken 10 times.
✓ Branch 10 → 11 taken 2 times.
void masked_merge_avx2_impl_inner<(MaskMode)2, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 10 → 7 taken 12 times.
✓ Branch 10 → 11 taken 2 times.
void masked_merge_avx2_impl_inner<(MaskMode)2, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 10 → 7 taken 5 times.
✓ Branch 10 → 11 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)3, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 10 → 7 taken 5 times.
✓ Branch 10 → 11 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)3, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 10 → 7 taken 5 times.
✓ Branch 10 → 11 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)4, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 10 → 7 taken 10 times.
✓ Branch 10 → 11 taken 2 times.
void masked_merge_avx2_impl_inner<(MaskMode)4, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 10 → 7 taken 10 times.
✓ Branch 10 → 11 taken 2 times.
void masked_merge_avx2_impl_inner<(MaskMode)5, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 10 → 7 taken 5 times.
✓ Branch 10 → 11 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)5, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 10 → 7 taken 5 times.
✓ Branch 10 → 11 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)6, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 10 → 7 taken 5 times.
✓ Branch 10 → 11 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)6, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 10 → 7 taken 5 times.
✓ Branch 10 → 11 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)7, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 10 → 7 taken 99 times.
✓ Branch 10 → 11 taken 26 times.
void masked_merge_avx2_impl_inner<(MaskMode)7, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 9 → 6 taken 49 times.
✓ Branch 9 → 10 taken 27 times.
317 for (int y = 0; y < height; y++) {
185
14/32
void masked_merge_avx2_impl_inner<(MaskMode)0, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)0, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)1, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 7 → 8 taken 19 times.
✗ Branch 7 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)1, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 7 → 8 taken 10 times.
✗ Branch 7 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)2, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 7 → 8 taken 12 times.
✗ Branch 7 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)2, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 7 → 8 taken 5 times.
✗ Branch 7 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)3, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 7 → 8 taken 5 times.
✗ Branch 7 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)3, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 7 → 8 taken 5 times.
✗ Branch 7 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)4, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 7 → 8 taken 10 times.
✗ Branch 7 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)4, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 7 → 8 taken 10 times.
✗ Branch 7 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)5, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 7 → 8 taken 5 times.
✗ Branch 7 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)5, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 7 → 8 taken 5 times.
✗ Branch 7 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)6, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 7 → 8 taken 5 times.
✗ Branch 7 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)6, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 7 → 8 taken 5 times.
✗ Branch 7 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)7, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 7 → 8 taken 99 times.
✗ Branch 7 → 43 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)7, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 6 → 7 taken 49 times.
✗ Branch 6 → 41 not taken.
244 const uint8_t* eff = prepare_effective_mask_for_row_avx2<maskMode, uint8_t, full_opacity>(
186 maskp, mpx, width, eff_buf, opacity, half, mag);
187 244 blend8_masked_avx2_row(
188 reinterpret_cast<uint8_t*>(p1), reinterpret_cast<const uint8_t*>(p2), eff, width);
189 244 p1 += p1_pitch; p2 += p2_pitch; maskp += mask_adv;
190 }
191 73 return;
192 73 }
193
194 44 const uint16_t* maskp = reinterpret_cast<const uint16_t*>(mask);
195 44 const int mpx = mask_pitch / 2;
196 44 const int mask_adv = (maskMode == MASK420 || maskMode == MASK420_MPEG2 || maskMode == MASK420_TOPLEFT) ? mpx * 2 : mpx;
197
198 44 std::vector<uint16_t> eff_buf;
199
13/30
void masked_merge_avx2_impl_inner<(MaskMode)0, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 46 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)0, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 46 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)1, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 14 → 15 taken 2 times.
✗ Branch 14 → 46 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)1, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 14 → 15 taken 2 times.
✗ Branch 14 → 46 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)2, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 46 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)2, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 46 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)3, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 46 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)3, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 46 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)4, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 14 → 15 taken 3 times.
✗ Branch 14 → 46 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)4, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 14 → 15 taken 2 times.
✗ Branch 14 → 46 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)5, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 46 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)5, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 46 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)6, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 46 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)6, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 46 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)7, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 14 → 15 taken 15 times.
✗ Branch 14 → 46 not taken.
32 if constexpr (maskMode != MASK444 || !full_opacity) eff_buf.resize(width);
200
201 #define BLEND16_LOOP_AVX2(bpp) \
202 for (int y = 0; y < height; y++) { \
203 const uint16_t* eff = prepare_effective_mask_for_row_avx2<maskMode, uint16_t, full_opacity>( \
204 maskp, mpx, width, eff_buf, opacity, half, mag); \
205 blend16_masked_avx2_row<bpp>( \
206 reinterpret_cast<uint16_t*>(p1), reinterpret_cast<const uint16_t*>(p2), eff, width); \
207 p1 += p1_pitch; p2 += p2_pitch; maskp += mask_adv; \
208 } break;
209
210
20/80
void masked_merge_avx2_impl_inner<(MaskMode)0, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 22 not taken.
✗ Branch 15 → 28 not taken.
✗ Branch 15 → 34 not taken.
✗ Branch 15 → 40 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)0, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 22 not taken.
✗ Branch 15 → 28 not taken.
✗ Branch 15 → 34 not taken.
✗ Branch 15 → 40 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)1, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 22 not taken.
✗ Branch 15 → 28 not taken.
✓ Branch 15 → 34 taken 2 times.
✗ Branch 15 → 40 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)1, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 22 not taken.
✗ Branch 15 → 28 not taken.
✓ Branch 15 → 34 taken 2 times.
✗ Branch 15 → 40 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)2, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 22 not taken.
✗ Branch 15 → 28 not taken.
✓ Branch 15 → 34 taken 1 time.
✗ Branch 15 → 40 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)2, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 22 not taken.
✗ Branch 15 → 28 not taken.
✓ Branch 15 → 34 taken 1 time.
✗ Branch 15 → 40 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)3, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 22 not taken.
✗ Branch 15 → 28 not taken.
✓ Branch 15 → 34 taken 1 time.
✗ Branch 15 → 40 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)3, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 22 not taken.
✗ Branch 15 → 28 not taken.
✓ Branch 15 → 34 taken 1 time.
✗ Branch 15 → 40 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)4, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 22 not taken.
✗ Branch 15 → 28 not taken.
✓ Branch 15 → 34 taken 3 times.
✗ Branch 15 → 40 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)4, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 22 not taken.
✗ Branch 15 → 28 not taken.
✓ Branch 15 → 34 taken 2 times.
✗ Branch 15 → 40 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)5, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 22 not taken.
✗ Branch 15 → 28 not taken.
✓ Branch 15 → 34 taken 1 time.
✗ Branch 15 → 40 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)5, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 22 not taken.
✗ Branch 15 → 28 not taken.
✓ Branch 15 → 34 taken 1 time.
✗ Branch 15 → 40 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)6, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 22 not taken.
✗ Branch 15 → 28 not taken.
✓ Branch 15 → 34 taken 1 time.
✗ Branch 15 → 40 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)6, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 22 not taken.
✗ Branch 15 → 28 not taken.
✓ Branch 15 → 34 taken 1 time.
✗ Branch 15 → 40 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)7, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 15 → 16 taken 1 time.
✓ Branch 15 → 22 taken 1 time.
✓ Branch 15 → 28 taken 1 time.
✓ Branch 15 → 34 taken 12 times.
✗ Branch 15 → 40 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)7, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 13 → 14 taken 1 time.
✓ Branch 13 → 20 taken 1 time.
✓ Branch 13 → 26 taken 1 time.
✓ Branch 13 → 32 taken 9 times.
✗ Branch 13 → 38 not taken.
44 switch (bits_per_pixel) {
211
8/96
void masked_merge_avx2_impl_inner<(MaskMode)0, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 46 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 46 not taken.
✗ Branch 20 → 17 not taken.
✗ Branch 20 → 21 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)0, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 46 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 46 not taken.
✗ Branch 20 → 17 not taken.
✗ Branch 20 → 21 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)1, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 46 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 46 not taken.
✗ Branch 20 → 17 not taken.
✗ Branch 20 → 21 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)1, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 46 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 46 not taken.
✗ Branch 20 → 17 not taken.
✗ Branch 20 → 21 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)2, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 46 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 46 not taken.
✗ Branch 20 → 17 not taken.
✗ Branch 20 → 21 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)2, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 46 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 46 not taken.
✗ Branch 20 → 17 not taken.
✗ Branch 20 → 21 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)3, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 46 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 46 not taken.
✗ Branch 20 → 17 not taken.
✗ Branch 20 → 21 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)3, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 46 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 46 not taken.
✗ Branch 20 → 17 not taken.
✗ Branch 20 → 21 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)4, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 46 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 46 not taken.
✗ Branch 20 → 17 not taken.
✗ Branch 20 → 21 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)4, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 46 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 46 not taken.
✗ Branch 20 → 17 not taken.
✗ Branch 20 → 21 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)5, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 46 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 46 not taken.
✗ Branch 20 → 17 not taken.
✗ Branch 20 → 21 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)5, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 46 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 46 not taken.
✗ Branch 20 → 17 not taken.
✗ Branch 20 → 21 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)6, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 46 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 46 not taken.
✗ Branch 20 → 17 not taken.
✗ Branch 20 → 21 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)6, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 46 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 46 not taken.
✗ Branch 20 → 17 not taken.
✗ Branch 20 → 21 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)7, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 17 → 18 taken 5 times.
✗ Branch 17 → 46 not taken.
✓ Branch 18 → 19 taken 5 times.
✗ Branch 18 → 46 not taken.
✓ Branch 20 → 17 taken 5 times.
✓ Branch 20 → 21 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)7, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 15 → 16 taken 5 times.
✗ Branch 15 → 44 not taken.
✓ Branch 16 → 17 taken 5 times.
✗ Branch 16 → 44 not taken.
✓ Branch 18 → 15 taken 5 times.
✓ Branch 18 → 19 taken 1 time.
12 case 10: BLEND16_LOOP_AVX2(10)
212
8/96
void masked_merge_avx2_impl_inner<(MaskMode)0, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 46 not taken.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 46 not taken.
✗ Branch 26 → 23 not taken.
✗ Branch 26 → 27 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)0, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 46 not taken.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 46 not taken.
✗ Branch 26 → 23 not taken.
✗ Branch 26 → 27 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)1, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 46 not taken.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 46 not taken.
✗ Branch 26 → 23 not taken.
✗ Branch 26 → 27 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)1, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 46 not taken.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 46 not taken.
✗ Branch 26 → 23 not taken.
✗ Branch 26 → 27 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)2, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 46 not taken.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 46 not taken.
✗ Branch 26 → 23 not taken.
✗ Branch 26 → 27 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)2, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 46 not taken.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 46 not taken.
✗ Branch 26 → 23 not taken.
✗ Branch 26 → 27 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)3, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 46 not taken.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 46 not taken.
✗ Branch 26 → 23 not taken.
✗ Branch 26 → 27 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)3, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 46 not taken.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 46 not taken.
✗ Branch 26 → 23 not taken.
✗ Branch 26 → 27 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)4, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 46 not taken.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 46 not taken.
✗ Branch 26 → 23 not taken.
✗ Branch 26 → 27 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)4, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 46 not taken.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 46 not taken.
✗ Branch 26 → 23 not taken.
✗ Branch 26 → 27 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)5, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 46 not taken.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 46 not taken.
✗ Branch 26 → 23 not taken.
✗ Branch 26 → 27 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)5, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 46 not taken.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 46 not taken.
✗ Branch 26 → 23 not taken.
✗ Branch 26 → 27 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)6, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 46 not taken.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 46 not taken.
✗ Branch 26 → 23 not taken.
✗ Branch 26 → 27 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)6, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 46 not taken.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 46 not taken.
✗ Branch 26 → 23 not taken.
✗ Branch 26 → 27 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)7, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 23 → 24 taken 5 times.
✗ Branch 23 → 46 not taken.
✓ Branch 24 → 25 taken 5 times.
✗ Branch 24 → 46 not taken.
✓ Branch 26 → 23 taken 5 times.
✓ Branch 26 → 27 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)7, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 21 → 22 taken 5 times.
✗ Branch 21 → 44 not taken.
✓ Branch 22 → 23 taken 5 times.
✗ Branch 22 → 44 not taken.
✓ Branch 24 → 21 taken 5 times.
✓ Branch 24 → 25 taken 1 time.
12 case 12: BLEND16_LOOP_AVX2(12)
213
8/96
void masked_merge_avx2_impl_inner<(MaskMode)0, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 46 not taken.
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 46 not taken.
✗ Branch 32 → 29 not taken.
✗ Branch 32 → 33 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)0, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 46 not taken.
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 46 not taken.
✗ Branch 32 → 29 not taken.
✗ Branch 32 → 33 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)1, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 46 not taken.
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 46 not taken.
✗ Branch 32 → 29 not taken.
✗ Branch 32 → 33 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)1, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 46 not taken.
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 46 not taken.
✗ Branch 32 → 29 not taken.
✗ Branch 32 → 33 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)2, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 46 not taken.
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 46 not taken.
✗ Branch 32 → 29 not taken.
✗ Branch 32 → 33 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)2, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 46 not taken.
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 46 not taken.
✗ Branch 32 → 29 not taken.
✗ Branch 32 → 33 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)3, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 46 not taken.
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 46 not taken.
✗ Branch 32 → 29 not taken.
✗ Branch 32 → 33 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)3, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 46 not taken.
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 46 not taken.
✗ Branch 32 → 29 not taken.
✗ Branch 32 → 33 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)4, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 46 not taken.
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 46 not taken.
✗ Branch 32 → 29 not taken.
✗ Branch 32 → 33 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)4, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 46 not taken.
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 46 not taken.
✗ Branch 32 → 29 not taken.
✗ Branch 32 → 33 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)5, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 46 not taken.
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 46 not taken.
✗ Branch 32 → 29 not taken.
✗ Branch 32 → 33 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)5, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 46 not taken.
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 46 not taken.
✗ Branch 32 → 29 not taken.
✗ Branch 32 → 33 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)6, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 46 not taken.
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 46 not taken.
✗ Branch 32 → 29 not taken.
✗ Branch 32 → 33 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)6, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 46 not taken.
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 46 not taken.
✗ Branch 32 → 29 not taken.
✗ Branch 32 → 33 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)7, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 29 → 30 taken 5 times.
✗ Branch 29 → 46 not taken.
✓ Branch 30 → 31 taken 5 times.
✗ Branch 30 → 46 not taken.
✓ Branch 32 → 29 taken 5 times.
✓ Branch 32 → 33 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)7, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 27 → 28 taken 5 times.
✗ Branch 27 → 44 not taken.
✓ Branch 28 → 29 taken 5 times.
✗ Branch 28 → 44 not taken.
✓ Branch 30 → 27 taken 5 times.
✓ Branch 30 → 31 taken 1 time.
12 case 14: BLEND16_LOOP_AVX2(14)
214
56/96
void masked_merge_avx2_impl_inner<(MaskMode)0, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 35 → 36 not taken.
✗ Branch 35 → 46 not taken.
✗ Branch 36 → 37 not taken.
✗ Branch 36 → 46 not taken.
✗ Branch 38 → 35 not taken.
✗ Branch 38 → 39 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)0, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 35 → 36 not taken.
✗ Branch 35 → 46 not taken.
✗ Branch 36 → 37 not taken.
✗ Branch 36 → 46 not taken.
✗ Branch 38 → 35 not taken.
✗ Branch 38 → 39 not taken.
void masked_merge_avx2_impl_inner<(MaskMode)1, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 35 → 36 taken 10 times.
✗ Branch 35 → 46 not taken.
✓ Branch 36 → 37 taken 10 times.
✗ Branch 36 → 46 not taken.
✓ Branch 38 → 35 taken 10 times.
✓ Branch 38 → 39 taken 2 times.
void masked_merge_avx2_impl_inner<(MaskMode)1, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 35 → 36 taken 10 times.
✗ Branch 35 → 46 not taken.
✓ Branch 36 → 37 taken 10 times.
✗ Branch 36 → 46 not taken.
✓ Branch 38 → 35 taken 10 times.
✓ Branch 38 → 39 taken 2 times.
void masked_merge_avx2_impl_inner<(MaskMode)2, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 35 → 36 taken 5 times.
✗ Branch 35 → 46 not taken.
✓ Branch 36 → 37 taken 5 times.
✗ Branch 36 → 46 not taken.
✓ Branch 38 → 35 taken 5 times.
✓ Branch 38 → 39 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)2, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 35 → 36 taken 5 times.
✗ Branch 35 → 46 not taken.
✓ Branch 36 → 37 taken 5 times.
✗ Branch 36 → 46 not taken.
✓ Branch 38 → 35 taken 5 times.
✓ Branch 38 → 39 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)3, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 35 → 36 taken 5 times.
✗ Branch 35 → 46 not taken.
✓ Branch 36 → 37 taken 5 times.
✗ Branch 36 → 46 not taken.
✓ Branch 38 → 35 taken 5 times.
✓ Branch 38 → 39 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)3, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 35 → 36 taken 5 times.
✗ Branch 35 → 46 not taken.
✓ Branch 36 → 37 taken 5 times.
✗ Branch 36 → 46 not taken.
✓ Branch 38 → 35 taken 5 times.
✓ Branch 38 → 39 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)4, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 35 → 36 taken 15 times.
✗ Branch 35 → 46 not taken.
✓ Branch 36 → 37 taken 15 times.
✗ Branch 36 → 46 not taken.
✓ Branch 38 → 35 taken 15 times.
✓ Branch 38 → 39 taken 3 times.
void masked_merge_avx2_impl_inner<(MaskMode)4, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 35 → 36 taken 10 times.
✗ Branch 35 → 46 not taken.
✓ Branch 36 → 37 taken 10 times.
✗ Branch 36 → 46 not taken.
✓ Branch 38 → 35 taken 10 times.
✓ Branch 38 → 39 taken 2 times.
void masked_merge_avx2_impl_inner<(MaskMode)5, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 35 → 36 taken 5 times.
✗ Branch 35 → 46 not taken.
✓ Branch 36 → 37 taken 5 times.
✗ Branch 36 → 46 not taken.
✓ Branch 38 → 35 taken 5 times.
✓ Branch 38 → 39 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)5, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 35 → 36 taken 5 times.
✗ Branch 35 → 46 not taken.
✓ Branch 36 → 37 taken 5 times.
✗ Branch 36 → 46 not taken.
✓ Branch 38 → 35 taken 5 times.
✓ Branch 38 → 39 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)6, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 35 → 36 taken 5 times.
✗ Branch 35 → 46 not taken.
✓ Branch 36 → 37 taken 5 times.
✗ Branch 36 → 46 not taken.
✓ Branch 38 → 35 taken 5 times.
✓ Branch 38 → 39 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)6, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 35 → 36 taken 5 times.
✗ Branch 35 → 46 not taken.
✓ Branch 36 → 37 taken 5 times.
✗ Branch 36 → 46 not taken.
✓ Branch 38 → 35 taken 5 times.
✓ Branch 38 → 39 taken 1 time.
void masked_merge_avx2_impl_inner<(MaskMode)7, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 35 → 36 taken 40 times.
✗ Branch 35 → 46 not taken.
✓ Branch 36 → 37 taken 10 times.
✗ Branch 36 → 46 not taken.
✓ Branch 38 → 35 taken 40 times.
✓ Branch 38 → 39 taken 12 times.
void masked_merge_avx2_impl_inner<(MaskMode)7, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 33 → 34 taken 31 times.
✗ Branch 33 → 44 not taken.
✓ Branch 34 → 35 taken 10 times.
✗ Branch 34 → 44 not taken.
✓ Branch 36 → 33 taken 31 times.
✓ Branch 36 → 37 taken 9 times.
194 case 16: BLEND16_LOOP_AVX2(16)
215 }
216 #undef BLEND16_LOOP_AVX2
217 44 }
218
219 // ---------------------------------------------------------------------------
220 // Inner loop — full_opacity known at compile time.
221 // Rowprep bakes opacity when !full_opacity; blend row receives pre-scaled mask.
222 // MASK444 + full_opacity: returns mask ptr directly (no buffer, no copy).
223 // MASK444 + !full_opacity: copies row with opacity scaling into buffer.
224 // ---------------------------------------------------------------------------
225 template<MaskMode maskMode, bool full_opacity>
226 #if defined(GCC) || defined(CLANG)
227 __attribute__((__target__("avx2")))
228 #endif
229 6 static void masked_merge_float_avx2_impl_inner(
230 BYTE* p1, const BYTE* p2, const BYTE* mask,
231 int p1_pitch, int p2_pitch, int mask_pitch,
232 int width, int height, float opacity)
233 {
234 6 const float* maskp = reinterpret_cast<const float*>(mask);
235 6 const int mpx = mask_pitch / sizeof(float);
236 6 const int mask_adv = (maskMode == MASK420 || maskMode == MASK420_MPEG2 || maskMode == MASK420_TOPLEFT) ? mpx * 2 : mpx;
237
238 6 std::vector<float> eff_buf;
239
5/30
void masked_merge_float_avx2_impl_inner<(MaskMode)0, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)0, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)1, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)1, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)2, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)2, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)3, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)3, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)4, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)4, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)5, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)5, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)6, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)6, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)7, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 11 not taken.
5 if constexpr (maskMode != MASK444 || !full_opacity) eff_buf.resize(width);
240
241
12/32
void masked_merge_float_avx2_impl_inner<(MaskMode)0, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 8 → 5 not taken.
✗ Branch 8 → 9 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)0, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 8 → 5 not taken.
✗ Branch 8 → 9 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)1, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 8 → 5 taken 5 times.
✓ Branch 8 → 9 taken 1 time.
void masked_merge_float_avx2_impl_inner<(MaskMode)1, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 8 → 5 taken 5 times.
✓ Branch 8 → 9 taken 1 time.
void masked_merge_float_avx2_impl_inner<(MaskMode)2, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 8 → 5 not taken.
✗ Branch 8 → 9 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)2, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 8 → 5 not taken.
✗ Branch 8 → 9 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)3, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 8 → 5 not taken.
✗ Branch 8 → 9 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)3, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 8 → 5 not taken.
✗ Branch 8 → 9 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)4, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 8 → 5 taken 5 times.
✓ Branch 8 → 9 taken 1 time.
void masked_merge_float_avx2_impl_inner<(MaskMode)4, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 8 → 5 taken 5 times.
✓ Branch 8 → 9 taken 1 time.
void masked_merge_float_avx2_impl_inner<(MaskMode)5, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 8 → 5 not taken.
✗ Branch 8 → 9 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)5, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 8 → 5 not taken.
✗ Branch 8 → 9 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)6, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 8 → 5 not taken.
✗ Branch 8 → 9 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)6, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 8 → 5 not taken.
✗ Branch 8 → 9 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)7, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 8 → 5 taken 5 times.
✓ Branch 8 → 9 taken 1 time.
void masked_merge_float_avx2_impl_inner<(MaskMode)7, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 7 → 4 taken 5 times.
✓ Branch 7 → 8 taken 1 time.
36 for (int y = 0; y < height; y++) {
242
6/32
void masked_merge_float_avx2_impl_inner<(MaskMode)0, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)0, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)1, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 5 → 6 taken 5 times.
✗ Branch 5 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)1, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 5 → 6 taken 5 times.
✗ Branch 5 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)2, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)2, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)3, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)3, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)4, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 5 → 6 taken 5 times.
✗ Branch 5 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)4, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 5 → 6 taken 5 times.
✗ Branch 5 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)5, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)5, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)6, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)6, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)7, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 5 → 6 taken 5 times.
✗ Branch 5 → 11 not taken.
void masked_merge_float_avx2_impl_inner<(MaskMode)7, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 4 → 5 taken 5 times.
✗ Branch 4 → 10 not taken.
30 const float* eff = prepare_effective_mask_for_row_float_avx2<maskMode, full_opacity>(
243 maskp, mpx, width, eff_buf, opacity);
244 30 blend_masked_float_avx2_row(
245 reinterpret_cast<float*>(p1), reinterpret_cast<const float*>(p2), eff, width);
246 30 p1 += p1_pitch; p2 += p2_pitch; maskp += mask_adv;
247 }
248 6 }
249
250 // ---------------------------------------------------------------------------
251 // Outer: dispatch on full_opacity (opacity == max_pixel_value) at the call site.
252 // ---------------------------------------------------------------------------
253 template<MaskMode maskMode>
254 #if defined(GCC) || defined(CLANG)
255 __attribute__((__target__("avx2")))
256 #endif
257 117 static void masked_merge_avx2_impl(
258 BYTE* p1, const BYTE* p2, const BYTE* mask,
259 int p1_pitch, int p2_pitch, int mask_pitch,
260 int width, int height, int opacity, int bits_per_pixel)
261 {
262 117 const int max_val = (1 << bits_per_pixel) - 1;
263
14/16
void masked_merge_avx2_impl<(MaskMode)0>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
void masked_merge_avx2_impl<(MaskMode)1>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 2 → 3 taken 4 times.
✓ Branch 2 → 4 taken 7 times.
void masked_merge_avx2_impl<(MaskMode)2>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 2 → 3 taken 2 times.
✓ Branch 2 → 4 taken 3 times.
void masked_merge_avx2_impl<(MaskMode)3>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 2 → 3 taken 2 times.
✓ Branch 2 → 4 taken 2 times.
void masked_merge_avx2_impl<(MaskMode)4>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 2 → 3 taken 4 times.
✓ Branch 2 → 4 taken 5 times.
void masked_merge_avx2_impl<(MaskMode)5>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 2 → 3 taken 2 times.
✓ Branch 2 → 4 taken 2 times.
void masked_merge_avx2_impl<(MaskMode)6>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 2 → 3 taken 2 times.
✓ Branch 2 → 4 taken 2 times.
void masked_merge_avx2_impl<(MaskMode)7>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 2 → 3 taken 39 times.
✓ Branch 2 → 4 taken 41 times.
117 if (opacity == max_val)
264 55 masked_merge_avx2_impl_inner<maskMode, true>(
265 p1, p2, mask, p1_pitch, p2_pitch, mask_pitch, width, height, opacity, bits_per_pixel);
266 else
267 62 masked_merge_avx2_impl_inner<maskMode, false>(
268 p1, p2, mask, p1_pitch, p2_pitch, mask_pitch, width, height, opacity, bits_per_pixel);
269 117 }
270
271 template<MaskMode maskMode>
272 #if defined(GCC) || defined(CLANG)
273 __attribute__((__target__("avx2")))
274 #endif
275 6 static void masked_merge_float_avx2_impl(
276 BYTE* p1, const BYTE* p2, const BYTE* mask,
277 int p1_pitch, int p2_pitch, int mask_pitch,
278 int width, int height, float opacity)
279 {
280
6/16
void masked_merge_float_avx2_impl<(MaskMode)0>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
void masked_merge_float_avx2_impl<(MaskMode)1>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 2 → 3 taken 1 time.
✓ Branch 2 → 4 taken 1 time.
void masked_merge_float_avx2_impl<(MaskMode)2>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
void masked_merge_float_avx2_impl<(MaskMode)3>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
void masked_merge_float_avx2_impl<(MaskMode)4>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 2 → 3 taken 1 time.
✓ Branch 2 → 4 taken 1 time.
void masked_merge_float_avx2_impl<(MaskMode)5>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
void masked_merge_float_avx2_impl<(MaskMode)6>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
void masked_merge_float_avx2_impl<(MaskMode)7>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 2 → 3 taken 1 time.
✓ Branch 2 → 4 taken 1 time.
6 if (opacity >= 1.0f)
281 3 masked_merge_float_avx2_impl_inner<maskMode, true>(
282 p1, p2, mask, p1_pitch, p2_pitch, mask_pitch, width, height, opacity);
283 else
284 3 masked_merge_float_avx2_impl_inner<maskMode, false>(
285 p1, p2, mask, p1_pitch, p2_pitch, mask_pitch, width, height, opacity);
286 6 }
287
288