1/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7#include "EdgeWalker_Test.h"
8#include "Intersection_Tests.h"
9
10static void* testSimplify4x4QuadralateralsMain(void* data)
11{
12    SkASSERT(data);
13    State4& state = *(State4*) data;
14    char pathStr[1024];
15    bzero(pathStr, sizeof(pathStr));
16    do {
17        int ax = state.a & 0x03;
18        int ay = state.a >> 2;
19        int bx = state.b & 0x03;
20        int by = state.b >> 2;
21        int cx = state.c & 0x03;
22        int cy = state.c >> 2;
23        int dx = state.d & 0x03;
24        int dy = state.d >> 2;
25        for (int e = 0 ; e < 16; ++e) {
26            int ex = e & 0x03;
27            int ey = e >> 2;
28            for (int f = e ; f < 16; ++f) {
29                int fx = f & 0x03;
30                int fy = f >> 2;
31                for (int g = f ; g < 16; ++g) {
32                    int gx = g & 0x03;
33                    int gy = g >> 2;
34                    for (int h = g ; h < 16; ++h) {
35                        int hx = h & 0x03;
36                        int hy = h >> 2;
37                        SkPath path, out;
38                        path.setFillType(SkPath::kWinding_FillType);
39                        path.moveTo(ax, ay);
40                        path.lineTo(bx, by);
41                        path.lineTo(cx, cy);
42                        path.lineTo(dx, dy);
43                        path.close();
44                        path.moveTo(ex, ey);
45                        path.lineTo(fx, fy);
46                        path.lineTo(gx, gy);
47                        path.lineTo(hx, hy);
48                        path.close();
49                        if (1) {  // gdb: set print elements 400
50                            char* str = pathStr;
51                            str += sprintf(str, "    path.moveTo(%d, %d);\n", ax, ay);
52                            str += sprintf(str, "    path.lineTo(%d, %d);\n", bx, by);
53                            str += sprintf(str, "    path.lineTo(%d, %d);\n", cx, cy);
54                            str += sprintf(str, "    path.lineTo(%d, %d);\n", dx, dy);
55                            str += sprintf(str, "    path.close();\n");
56                            str += sprintf(str, "    path.moveTo(%d, %d);\n", ex, ey);
57                            str += sprintf(str, "    path.lineTo(%d, %d);\n", fx, fy);
58                            str += sprintf(str, "    path.lineTo(%d, %d);\n", gx, gy);
59                            str += sprintf(str, "    path.lineTo(%d, %d);\n", hx, hy);
60                            str += sprintf(str, "    path.close();\n");
61                        }
62                        outputProgress(state, pathStr, SkPath::kWinding_FillType);
63                        testSimplifyx(path, false, out, state, pathStr);
64                        state.testsRun++;
65                        path.setFillType(SkPath::kEvenOdd_FillType);
66                        outputProgress(state, pathStr, SkPath::kEvenOdd_FillType);
67                        testSimplifyx(path, true, out, state, pathStr);
68                        state.testsRun++;
69                    }
70                }
71            }
72        }
73    } while (runNextTestSet(state));
74    return NULL;
75}
76
77void Simplify4x4QuadralateralsThreaded_Test(int& testsRun)
78{
79    SkDebugf("%s\n", __FUNCTION__);
80#ifdef SK_DEBUG
81    gDebugMaxWindSum = 4; // FIXME: 3?
82    gDebugMaxWindValue = 4;
83#endif
84    const char testStr[] = "testQuadralateral";
85    initializeTests(testStr, sizeof(testStr));
86    int testsStart = testsRun;
87    for (int a = 0; a < 16; ++a) {
88        for (int b = a ; b < 16; ++b) {
89            for (int c = b ; c < 16; ++c) {
90                for (int d = c; d < 16; ++d) {
91                    testsRun += dispatchTest4(testSimplify4x4QuadralateralsMain,
92                            a, b, c, d);
93                }
94                if (!gRunTestsInOneThread) SkDebugf(".");
95            }
96            if (!gRunTestsInOneThread) SkDebugf("%d", b);
97        }
98        if (!gRunTestsInOneThread) SkDebugf("\n%d", a);
99    }
100    testsRun += waitForCompletion();
101    SkDebugf("%s tests=%d total=%d\n", __FUNCTION__, testsRun - testsStart, testsRun);
102}
103
104
105static void* testSimplify4x4NondegeneratesMain(void* data) {
106    SkASSERT(data);
107    State4& state = *(State4*) data;
108    char pathStr[1024];
109    bzero(pathStr, sizeof(pathStr));
110    do {
111        int ax = state.a & 0x03;
112        int ay = state.a >> 2;
113        int bx = state.b & 0x03;
114        int by = state.b >> 2;
115        int cx = state.c & 0x03;
116        int cy = state.c >> 2;
117        for (int d = 0; d < 15; ++d) {
118            int dx = d & 0x03;
119            int dy = d >> 2;
120            for (int e = d + 1; e < 16; ++e) {
121                int ex = e & 0x03;
122                int ey = e >> 2;
123                for (int f = d + 1; f < 16; ++f) {
124                    if (e == f) {
125                        continue;
126                    }
127                    int fx = f & 0x03;
128                    int fy = f >> 2;
129                    if ((ex - dx) * (fy - dy) == (ey - dy) * (fx - dx)) {
130                        continue;
131                    }
132                    SkPath path, out;
133                    path.setFillType(SkPath::kWinding_FillType);
134                    path.moveTo(ax, ay);
135                    path.lineTo(bx, by);
136                    path.lineTo(cx, cy);
137                    path.close();
138                    path.moveTo(dx, dy);
139                    path.lineTo(ex, ey);
140                    path.lineTo(fx, fy);
141                    path.close();
142                    if (1) {
143                        char* str = pathStr;
144                        str += sprintf(str, "    path.moveTo(%d, %d);\n", ax, ay);
145                        str += sprintf(str, "    path.lineTo(%d, %d);\n", bx, by);
146                        str += sprintf(str, "    path.lineTo(%d, %d);\n", cx, cy);
147                        str += sprintf(str, "    path.close();\n");
148                        str += sprintf(str, "    path.moveTo(%d, %d);\n", dx, dy);
149                        str += sprintf(str, "    path.lineTo(%d, %d);\n", ex, ey);
150                        str += sprintf(str, "    path.lineTo(%d, %d);\n", fx, fy);
151                        str += sprintf(str, "    path.close();\n");
152                    }
153                    outputProgress(state, pathStr, SkPath::kWinding_FillType);
154                    testSimplifyx(path, false, out, state, pathStr);
155                    state.testsRun++;
156                    path.setFillType(SkPath::kEvenOdd_FillType);
157                    outputProgress(state, pathStr, SkPath::kEvenOdd_FillType);
158                    testSimplifyx(path, true, out, state, pathStr);
159                    state.testsRun++;
160                }
161            }
162        }
163    } while (runNextTestSet(state));
164    return NULL;
165}
166
167void SimplifyNondegenerate4x4TrianglesThreaded_Test(int& testsRun) {
168    SkDebugf("%s\n", __FUNCTION__);
169#ifdef SK_DEBUG
170    gDebugMaxWindSum = 2;
171    gDebugMaxWindValue = 2;
172#endif
173    const char testStr[] = "testNondegenerate";
174    initializeTests(testStr, sizeof(testStr));
175    int testsStart = testsRun;
176    for (int a = 0; a < 15; ++a) {
177        int ax = a & 0x03;
178        int ay = a >> 2;
179        for (int b = a + 1; b < 16; ++b) {
180            int bx = b & 0x03;
181            int by = b >> 2;
182            for (int c = a + 1; c < 16; ++c) {
183                if (b == c) {
184                    continue;
185                }
186                int cx = c & 0x03;
187                int cy = c >> 2;
188                if ((bx - ax) * (cy - ay) == (by - ay) * (cx - ax)) {
189                    continue;
190                }
191                testsRun += dispatchTest4(testSimplify4x4NondegeneratesMain,
192                        a, b, c, 0);
193            }
194            if (!gRunTestsInOneThread) SkDebugf(".");
195        }
196        if (!gRunTestsInOneThread) SkDebugf("\n%d", a);
197    }
198    testsRun += waitForCompletion();
199    SkDebugf("%s tests=%d total=%d\n", __FUNCTION__, testsRun - testsStart, testsRun);
200}
201
202static void* testSimplify4x4DegeneratesMain(void* data) {
203    SkASSERT(data);
204    State4& state = *(State4*) data;
205    char pathStr[1024];
206    bzero(pathStr, sizeof(pathStr));
207    do {
208        int ax = state.a & 0x03;
209        int ay = state.a >> 2;
210        int bx = state.b & 0x03;
211        int by = state.b >> 2;
212        int cx = state.c & 0x03;
213        int cy = state.c >> 2;
214        for (int d = 0; d < 16; ++d) {
215            int dx = d & 0x03;
216            int dy = d >> 2;
217            for (int e = d ; e < 16; ++e) {
218                int ex = e & 0x03;
219                int ey = e >> 2;
220                for (int f = d ; f < 16; ++f) {
221                    int fx = f & 0x03;
222                    int fy = f >> 2;
223                    if (state.d && (ex - dx) * (fy - dy)
224                            != (ey - dy) * (fx - dx)) {
225                        continue;
226                    }
227                    SkPath path, out;
228                    path.setFillType(SkPath::kWinding_FillType);
229                    path.moveTo(ax, ay);
230                    path.lineTo(bx, by);
231                    path.lineTo(cx, cy);
232                    path.close();
233                    path.moveTo(dx, dy);
234                    path.lineTo(ex, ey);
235                    path.lineTo(fx, fy);
236                    path.close();
237                    if (1) {
238                        char* str = pathStr;
239                        str += sprintf(str, "    path.moveTo(%d, %d);\n", ax, ay);
240                        str += sprintf(str, "    path.lineTo(%d, %d);\n", bx, by);
241                        str += sprintf(str, "    path.lineTo(%d, %d);\n", cx, cy);
242                        str += sprintf(str, "    path.close();\n");
243                        str += sprintf(str, "    path.moveTo(%d, %d);\n", dx, dy);
244                        str += sprintf(str, "    path.lineTo(%d, %d);\n", ex, ey);
245                        str += sprintf(str, "    path.lineTo(%d, %d);\n", fx, fy);
246                        str += sprintf(str, "    path.close();\n");
247                    }
248                    outputProgress(state, pathStr, SkPath::kWinding_FillType);
249                    testSimplifyx(path, false, out, state, pathStr);
250                    state.testsRun++;
251                    path.setFillType(SkPath::kEvenOdd_FillType);
252                    outputProgress(state, pathStr, SkPath::kEvenOdd_FillType);
253                    testSimplifyx(path, true, out, state, pathStr);
254                    state.testsRun++;
255                }
256            }
257        }
258    } while (runNextTestSet(state));
259    return NULL;
260}
261
262void SimplifyDegenerate4x4TrianglesThreaded_Test(int& testsRun) {
263    SkDebugf("%s\n", __FUNCTION__);
264#ifdef SK_DEBUG
265    gDebugMaxWindSum = 2;
266    gDebugMaxWindValue = 2;
267#endif
268    const char testStr[] = "testDegenerate";
269    initializeTests(testStr, sizeof(testStr));
270    int testsStart = testsRun;
271    for (int a = 0; a < 16; ++a) {
272        int ax = a & 0x03;
273        int ay = a >> 2;
274        for (int b = a ; b < 16; ++b) {
275            int bx = b & 0x03;
276            int by = b >> 2;
277            for (int c = a ; c < 16; ++c) {
278                int cx = c & 0x03;
279                int cy = c >> 2;
280                bool abcIsATriangle = (bx - ax) * (cy - ay) != (by - ay) * (cx - ax);
281                testsRun += dispatchTest4(testSimplify4x4DegeneratesMain,
282                        a, b, c, abcIsATriangle);
283            }
284            if (!gRunTestsInOneThread) SkDebugf(".");
285        }
286        if (!gRunTestsInOneThread) SkDebugf("\n%d", a);
287    }
288    testsRun += waitForCompletion();
289    SkDebugf("%s tests=%d total=%d\n", __FUNCTION__, testsRun - testsStart, testsRun);
290}
291