Tizen 2.0 Release
[framework/graphics/cairo.git] / perf / micro / spiral.c
1 /* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
2 /* cairo - a vector graphics library with display and print output
3  *
4  * Copyright (c) 2008  M Joonas Pihlaja
5  *
6  * Permission is hereby granted, free of charge, to any person
7  * obtaining a copy of this software and associated documentation
8  * files (the "Software"), to deal in the Software without
9  * restriction, including without limitation the rights to use,
10  * copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following
13  * conditions:
14  *
15  * The above copyright notice and this permission notice shall be
16  * included in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25  * OTHER DEALINGS IN THE SOFTWARE.
26  */
27 #include <assert.h>
28 #include "cairo-perf.h"
29
30 #define MAX_SEGMENTS 2560
31
32 typedef enum {
33     PIXALIGN,                   /* pixel aligned path */
34     NONALIGN                    /* unaligned path. */
35 } align_t;
36
37 typedef enum {
38     RECTCLOSE,                  /* keeps the path rectilinear */
39     DIAGCLOSE                   /* forces a diagonal */
40 } close_t;
41
42 static cairo_time_t
43 draw_spiral (cairo_t *cr,
44              cairo_fill_rule_t fill_rule,
45              align_t align,
46              close_t close,
47              int width, int height, int loops)
48 {
49     int i;
50     int n=0;
51     double x[MAX_SEGMENTS];
52     double y[MAX_SEGMENTS];
53     int step = 3;
54     int side = width < height ? width : height;
55
56     assert(5*(side/step/2+1)+2 < MAX_SEGMENTS);
57
58 #define L(x_,y_) (x[n] = (x_), y[n] = (y_), n++)
59 #define M(x_,y_) L(x_,y_)
60 #define v(t) L(x[n-1], y[n-1] + (t))
61 #define h(t) L(x[n-1] + (t), y[n-1])
62
63     switch (align) {
64     case PIXALIGN: M(0,0); break;
65     case NONALIGN: M(0.1415926, 0.7182818); break;
66     }
67
68     while (side >= step && side >= 0) {
69         v(side);
70         h(side);
71         v(-side);
72         h(-side+step);
73         v(step);
74         side -= 2*step;
75     }
76
77     switch (close) {
78     case RECTCLOSE: L(x[n-1],y[0]); break;
79     case DIAGCLOSE: L(x[0],y[0]); break;
80     }
81
82     assert(n < MAX_SEGMENTS);
83
84     cairo_save (cr);
85     cairo_set_source_rgb (cr, 0, 0, 0);
86     cairo_paint (cr);
87
88     cairo_translate (cr, 1, 1);
89     cairo_set_fill_rule (cr, fill_rule);
90     cairo_set_source_rgb (cr, 1, 0, 0);
91
92     cairo_new_path (cr);
93     cairo_move_to (cr, x[0], y[0]);
94     for (i = 1; i < n; i++) {
95         cairo_line_to (cr, x[i], y[i]);
96     }
97     cairo_close_path (cr);
98
99     cairo_perf_timer_start ();
100     cairo_perf_set_thread_aware (cr, FALSE);
101     while (loops--) {
102         if (loops == 0)
103             cairo_perf_set_thread_aware (cr, TRUE);
104         cairo_fill_preserve (cr);
105     }
106
107     cairo_perf_timer_stop ();
108
109     cairo_restore (cr);
110
111     return cairo_perf_timer_elapsed ();
112 }
113
114 static cairo_time_t
115 draw_spiral_box (cairo_t *cr,
116                  cairo_fill_rule_t fill_rule,
117                  align_t align,
118                  int width, int height, int loops)
119 {
120     const int step = 3;
121     int side = (width < height ? width : height) - 2;
122
123     cairo_save (cr);
124     cairo_set_source_rgb (cr, 0, 0, 0);
125     cairo_paint (cr);
126
127     cairo_set_source_rgb (cr, 1, 0, 0);
128     cairo_set_fill_rule (cr, fill_rule);
129     cairo_translate (cr, 1, 1);
130     if (align == NONALIGN)
131         cairo_translate (cr, 0.1415926, 0.7182818);
132
133     cairo_new_path (cr);
134     while (side >= step) {
135         cairo_rectangle (cr, 0, 0, side, side);
136         cairo_translate (cr, step, step);
137         side -= 2*step;
138     }
139
140     cairo_perf_timer_start ();
141     cairo_perf_set_thread_aware (cr, FALSE);
142     while (loops--) {
143         if (loops == 0)
144             cairo_perf_set_thread_aware (cr, TRUE);
145         cairo_fill_preserve (cr);
146     }
147
148     cairo_perf_timer_stop ();
149
150     cairo_restore (cr);
151
152     return cairo_perf_timer_elapsed ();
153 }
154
155 static cairo_time_t
156 draw_spiral_stroke (cairo_t *cr,
157                     align_t align,
158                     int width, int height, int loops)
159 {
160     const int step = 3;
161     int side = width < height ? width : height;
162
163     cairo_save (cr);
164     cairo_set_source_rgb (cr, 0, 0, 0);
165     cairo_paint (cr);
166
167     cairo_translate (cr, 1, 1);
168     cairo_set_source_rgb (cr, 1, 0, 0);
169     cairo_set_line_width (cr, 4.);
170     cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
171     cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
172
173     cairo_new_path (cr);
174     switch (align) {
175     case PIXALIGN: cairo_move_to (cr, 0,0); break;
176     case NONALIGN: cairo_move_to (cr, 0.1415926, 0.7182818); break;
177     }
178     while (side >= step) {
179         cairo_rel_line_to (cr, 0, side);
180         side -= step;
181         if (side <= 0)
182             break;
183
184         cairo_rel_line_to (cr, side, 0);
185         side -= step;
186         if (side <= 0)
187             break;
188
189         cairo_rel_line_to (cr, 0, -side);
190         side -= step;
191         if (side <= 0)
192             break;
193
194         cairo_rel_line_to (cr, -side, 0);
195         side -= step;
196         if (side <= 0)
197             break;
198     }
199
200     cairo_perf_timer_start ();
201     cairo_perf_set_thread_aware (cr, FALSE);
202     while (loops--) {
203         if (loops == 0)
204             cairo_perf_set_thread_aware (cr, TRUE);
205         cairo_stroke_preserve (cr);
206     }
207
208     cairo_perf_timer_stop ();
209
210     cairo_restore (cr);
211
212     return cairo_perf_timer_elapsed ();
213 }
214
215 static cairo_time_t
216 draw_spiral_eo_pa_re (cairo_t *cr, int width, int height, int loops)
217 {
218     return draw_spiral (cr,
219                         CAIRO_FILL_RULE_EVEN_ODD,
220                         PIXALIGN,
221                         RECTCLOSE,
222                         width, height, loops);
223 }
224
225 static cairo_time_t
226 draw_spiral_nz_pa_re (cairo_t *cr, int width, int height, int loops)
227 {
228     return draw_spiral (cr,
229                         CAIRO_FILL_RULE_WINDING,
230                         PIXALIGN,
231                         RECTCLOSE,
232                         width, height, loops);
233 }
234
235 static cairo_time_t
236 draw_spiral_eo_na_re (cairo_t *cr, int width, int height, int loops)
237 {
238     return draw_spiral (cr,
239                         CAIRO_FILL_RULE_EVEN_ODD,
240                         NONALIGN,
241                         RECTCLOSE,
242                         width, height, loops);
243 }
244
245 static cairo_time_t
246 draw_spiral_nz_na_re (cairo_t *cr, int width, int height, int loops)
247 {
248     return draw_spiral (cr,
249                         CAIRO_FILL_RULE_WINDING,
250                         NONALIGN,
251                         RECTCLOSE,
252                         width, height, loops);
253 }
254
255 static cairo_time_t
256 draw_spiral_eo_pa_di (cairo_t *cr, int width, int height, int loops)
257 {
258     return draw_spiral (cr,
259                         CAIRO_FILL_RULE_EVEN_ODD,
260                         PIXALIGN,
261                         DIAGCLOSE,
262                         width, height, loops);
263 }
264
265 static cairo_time_t
266 draw_spiral_nz_pa_di (cairo_t *cr, int width, int height, int loops)
267 {
268     return draw_spiral (cr,
269                         CAIRO_FILL_RULE_WINDING,
270                         PIXALIGN,
271                         DIAGCLOSE,
272                         width, height, loops);
273 }
274
275 static cairo_time_t
276 draw_spiral_eo_na_di (cairo_t *cr, int width, int height, int loops)
277 {
278     return draw_spiral (cr,
279                         CAIRO_FILL_RULE_EVEN_ODD,
280                         NONALIGN,
281                         DIAGCLOSE,
282                         width, height, loops);
283 }
284
285 static cairo_time_t
286 draw_spiral_nz_na_di (cairo_t *cr, int width, int height, int loops)
287 {
288     return draw_spiral (cr,
289                         CAIRO_FILL_RULE_WINDING,
290                         NONALIGN,
291                         DIAGCLOSE,
292                         width, height, loops);
293 }
294
295 static cairo_time_t
296 draw_spiral_nz_pa_box (cairo_t *cr, int width, int height, int loops)
297 {
298     return draw_spiral_box (cr,
299                             CAIRO_FILL_RULE_WINDING, PIXALIGN,
300                             width, height, loops);
301 }
302
303 static cairo_time_t
304 draw_spiral_nz_na_box (cairo_t *cr, int width, int height, int loops)
305 {
306     return draw_spiral_box (cr,
307                             CAIRO_FILL_RULE_WINDING, NONALIGN,
308                             width, height, loops);
309 }
310
311
312 static cairo_time_t
313 draw_spiral_eo_pa_box (cairo_t *cr, int width, int height, int loops)
314 {
315     return draw_spiral_box (cr,
316                             CAIRO_FILL_RULE_EVEN_ODD, PIXALIGN,
317                             width, height, loops);
318 }
319
320 static cairo_time_t
321 draw_spiral_eo_na_box (cairo_t *cr, int width, int height, int loops)
322 {
323     return draw_spiral_box (cr,
324                             CAIRO_FILL_RULE_EVEN_ODD, NONALIGN,
325                             width, height, loops);
326 }
327
328 static cairo_time_t
329 draw_spiral_stroke_pa (cairo_t *cr, int width, int height, int loops)
330 {
331     return draw_spiral_stroke (cr,
332                                PIXALIGN,
333                                width, height, loops);
334 }
335
336 static cairo_time_t
337 draw_spiral_stroke_na (cairo_t *cr, int width, int height, int loops)
338 {
339     return draw_spiral_stroke (cr,
340                                NONALIGN,
341                                width, height, loops);
342 }
343
344 cairo_bool_t
345 spiral_enabled (cairo_perf_t *perf)
346 {
347     return cairo_perf_can_run (perf, "spiral", NULL);
348 }
349
350 void
351 spiral (cairo_perf_t *perf, cairo_t *cr, int width, int height)
352 {
353     cairo_perf_run (perf, "spiral-box-nonalign-evenodd-fill", draw_spiral_eo_na_box, NULL);
354     cairo_perf_run (perf, "spiral-box-nonalign-nonzero-fill", draw_spiral_nz_na_box, NULL);
355     cairo_perf_run (perf, "spiral-box-pixalign-evenodd-fill", draw_spiral_eo_pa_box, NULL);
356     cairo_perf_run (perf, "spiral-box-pixalign-nonzero-fill", draw_spiral_nz_pa_box, NULL);
357     cairo_perf_run (perf, "spiral-diag-nonalign-evenodd-fill", draw_spiral_eo_na_di, NULL);
358     cairo_perf_run (perf, "spiral-diag-nonalign-nonzero-fill", draw_spiral_nz_na_di, NULL);
359     cairo_perf_run (perf, "spiral-diag-pixalign-evenodd-fill", draw_spiral_eo_pa_di, NULL);
360     cairo_perf_run (perf, "spiral-diag-pixalign-nonzero-fill", draw_spiral_nz_pa_di, NULL);
361     cairo_perf_run (perf, "spiral-rect-nonalign-evenodd-fill", draw_spiral_eo_na_re, NULL);
362     cairo_perf_run (perf, "spiral-rect-nonalign-nonzero-fill", draw_spiral_nz_na_re, NULL);
363     cairo_perf_run (perf, "spiral-rect-pixalign-evenodd-fill", draw_spiral_eo_pa_re, NULL);
364     cairo_perf_run (perf, "spiral-rect-pixalign-nonzero-fill", draw_spiral_nz_pa_re, NULL);
365     cairo_perf_run (perf, "spiral-nonalign-stroke", draw_spiral_stroke_na, NULL);
366     cairo_perf_run (perf, "spiral-pixalign-stroke", draw_spiral_stroke_pa, NULL);
367 }