1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
|
/* test_alphaComp.c
* vi:ts=4 sw=4
*
* (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
#include <freerdp/config.h>
#include <winpr/sysinfo.h>
#include "prim_test.h"
#define MAX_BLOCK_SIZE 256
#define SIZE_SQUARED (MAX_BLOCK_SIZE * MAX_BLOCK_SIZE)
/* ========================================================================= */
#define ALF(_c_) (((_c_)&0xFF000000U) >> 24)
#define RED(_c_) (((_c_)&0x00FF0000U) >> 16)
#define GRN(_c_) (((_c_)&0x0000FF00U) >> 8)
#define BLU(_c_) ((_c_)&0x000000FFU)
#define TOLERANCE 1
static inline const UINT32* PIXEL(const BYTE* _addr_, UINT32 _bytes_, UINT32 _x_, UINT32 _y_)
{
const BYTE* addr = _addr_ + _x_ * sizeof(UINT32) + _y_ * _bytes_;
return (const UINT32*)addr;
}
#define SRC1_WIDTH 6
#define SRC1_HEIGHT 6
#define SRC2_WIDTH 7
#define SRC2_HEIGHT 7
#define DST_WIDTH 9
#define DST_HEIGHT 9
#define TEST_WIDTH 4
#define TEST_HEIGHT 5
/* ------------------------------------------------------------------------- */
static UINT32 alpha_add(UINT32 c1, UINT32 c2)
{
UINT32 a1 = ALF(c1);
UINT32 r1 = RED(c1);
UINT32 g1 = GRN(c1);
UINT32 b1 = BLU(c1);
UINT32 a2 = ALF(c2);
UINT32 r2 = RED(c2);
UINT32 g2 = GRN(c2);
UINT32 b2 = BLU(c2);
UINT32 a3 = ((a1 * a1 + (255 - a1) * a2) / 255) & 0xff;
UINT32 r3 = ((a1 * r1 + (255 - a1) * r2) / 255) & 0xff;
UINT32 g3 = ((a1 * g1 + (255 - a1) * g2) / 255) & 0xff;
UINT32 b3 = ((a1 * b1 + (255 - a1) * b2) / 255) & 0xff;
return (a3 << 24) | (r3 << 16) | (g3 << 8) | b3;
}
/* ------------------------------------------------------------------------- */
static UINT32 colordist(UINT32 c1, UINT32 c2)
{
int d = 0;
int maxd = 0;
d = ABS((INT32)(ALF(c1) - ALF(c2)));
if (d > maxd)
maxd = d;
d = ABS((INT32)(RED(c1) - RED(c2)));
if (d > maxd)
maxd = d;
d = ABS((INT32)(GRN(c1) - GRN(c2)));
if (d > maxd)
maxd = d;
d = ABS((INT32)(BLU(c1) - BLU(c2)));
if (d > maxd)
maxd = d;
return maxd;
}
/* ------------------------------------------------------------------------- */
static BOOL check(const BYTE* pSrc1, UINT32 src1Step, const BYTE* pSrc2, UINT32 src2Step,
BYTE* pDst, UINT32 dstStep, UINT32 width, UINT32 height)
{
for (UINT32 y = 0; y < height; ++y)
{
for (UINT32 x = 0; x < width; ++x)
{
UINT32 s1 = *PIXEL(pSrc1, src1Step, x, y);
UINT32 s2 = *PIXEL(pSrc2, src2Step, x, y);
UINT32 c0 = alpha_add(s1, s2);
UINT32 c1 = *PIXEL(pDst, dstStep, x, y);
if (colordist(c0, c1) > TOLERANCE)
{
printf("alphaComp-general: [%" PRIu32 ",%" PRIu32 "] 0x%08" PRIx32 "+0x%08" PRIx32
"=0x%08" PRIx32 ", got 0x%08" PRIx32 "\n",
x, y, s1, s2, c0, c1);
return FALSE;
}
}
}
return TRUE;
}
static BOOL test_alphaComp_func(void)
{
pstatus_t status = 0;
BYTE ALIGN(src1[SRC1_WIDTH * SRC1_HEIGHT * 4]) = { 0 };
BYTE ALIGN(src2[SRC2_WIDTH * SRC2_HEIGHT * 4]) = { 0 };
BYTE ALIGN(dst1[DST_WIDTH * DST_HEIGHT * 4]) = { 0 };
UINT32* ptr = NULL;
winpr_RAND(src1, sizeof(src1));
/* Special-case the first two values */
src1[0] &= 0x00FFFFFFU;
src1[1] |= 0xFF000000U;
winpr_RAND(src2, sizeof(src2));
/* Set the second operand to fully-opaque. */
ptr = (UINT32*)src2;
for (UINT32 i = 0; i < sizeof(src2) / 4; ++i)
*ptr++ |= 0xFF000000U;
status = generic->alphaComp_argb(src1, 4 * SRC1_WIDTH, src2, 4 * SRC2_WIDTH, dst1,
4 * DST_WIDTH, TEST_WIDTH, TEST_HEIGHT);
if (status != PRIMITIVES_SUCCESS)
return FALSE;
if (!check(src1, 4 * SRC1_WIDTH, src2, 4 * SRC2_WIDTH, dst1, 4 * DST_WIDTH, TEST_WIDTH,
TEST_HEIGHT))
return FALSE;
status = optimized->alphaComp_argb((const BYTE*)src1, 4 * SRC1_WIDTH, (const BYTE*)src2,
4 * SRC2_WIDTH, (BYTE*)dst1, 4 * DST_WIDTH, TEST_WIDTH,
TEST_HEIGHT);
if (status != PRIMITIVES_SUCCESS)
return FALSE;
if (!check(src1, 4 * SRC1_WIDTH, src2, 4 * SRC2_WIDTH, dst1, 4 * DST_WIDTH, TEST_WIDTH,
TEST_HEIGHT))
return FALSE;
return TRUE;
}
static int test_alphaComp_speed(void)
{
BYTE ALIGN(src1[SRC1_WIDTH * SRC1_HEIGHT]) = { 0 };
BYTE ALIGN(src2[SRC2_WIDTH * SRC2_HEIGHT]) = { 0 };
BYTE ALIGN(dst1[DST_WIDTH * DST_HEIGHT]) = { 0 };
UINT32* ptr = NULL;
winpr_RAND(src1, sizeof(src1));
/* Special-case the first two values */
src1[0] &= 0x00FFFFFFU;
src1[1] |= 0xFF000000U;
winpr_RAND(src2, sizeof(src2));
/* Set the second operand to fully-opaque. */
ptr = (UINT32*)src2;
for (UINT32 i = 0; i < sizeof(src2) / 4; ++i)
*ptr++ |= 0xFF000000U;
if (!speed_test("add16s", "aligned", g_Iterations, (speed_test_fkt)generic->alphaComp_argb,
(speed_test_fkt)optimized->alphaComp_argb, src1, 4 * SRC1_WIDTH, src2,
4 * SRC2_WIDTH, dst1, 4 * DST_WIDTH, TEST_WIDTH, TEST_HEIGHT))
return FALSE;
return TRUE;
}
int TestPrimitivesAlphaComp(int argc, char* argv[])
{
WINPR_UNUSED(argc);
WINPR_UNUSED(argv);
prim_test_setup(FALSE);
if (!test_alphaComp_func())
return -1;
if (g_TestPrimitivesPerformance)
{
if (!test_alphaComp_speed())
return -1;
}
return 0;
}
|