1
/*
2
 * Copyright © 2006 Red Hat, Inc.
3
 *
4
 *
5
 * Permission is hereby granted, free of charge, to any person
6
 * obtaining a copy of this software and associated documentation
7
 * files (the "Software"), to deal in the Software without
8
 * restriction, including without limitation the rights to use, copy,
9
 * modify, merge, publish, distribute, sublicense, and/or sell copies
10
 * of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be
14
 * included in all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
 * SOFTWARE.
24
 *
25
 * Author: Carl D. Worth <cworth@cworth.org>
26
 */
27

            
28
#include "cairo-perf.h"
29

            
30
/* This test case is designed to illustrate a performance bug that
31
 * exists in cairo in which using cairo_stroke is much slower than
32
 * cairo_fill to draw an identical figure, (and in particular a figure
33
 * that is much more natural to draw with cairo_stroke). The figure is
34
 * a 100x100 square outline 1-pixel wide, nicely pixel aligned.
35
 *
36
 * The performance bug should affect any path whose resulting contour
37
 * consists only of pixel-aligned horizontal and vertical elements.
38
 *
39
 * Initial testing on on machine shows stroke as 5x slower than fill
40
 * for the xlib backend and 16x slower for the image backend.
41
 */
42

            
43
static cairo_time_t
44
box_outline_stroke (cairo_t *cr, int width, int height, int loops)
45
{
46
    cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
47
    cairo_paint (cr);
48

            
49
    cairo_rectangle (cr,
50
		     1.5, 1.5,
51
		     width - 3, height - 3);
52
    cairo_set_line_width (cr, 1.0);
53
    cairo_set_source_rgb (cr, 1, 0, 0); /* red */
54

            
55
    cairo_perf_timer_start ();
56

            
57
    while (loops--)
58
	cairo_stroke_preserve (cr);
59

            
60
    cairo_perf_timer_stop ();
61

            
62
    cairo_new_path (cr);
63

            
64
    return cairo_perf_timer_elapsed ();
65
}
66

            
67
static cairo_time_t
68
box_outline_alpha_stroke (cairo_t *cr, int width, int height, int loops)
69
{
70
    cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
71
    cairo_paint (cr);
72

            
73
    cairo_rectangle (cr,
74
		     1.5, 1.5,
75
		     width - 3, height - 3);
76
    cairo_set_line_width (cr, 1.0);
77
    cairo_set_source_rgba (cr, 1, 0, 0, .5); /* red */
78

            
79
    cairo_perf_timer_start ();
80

            
81
    while (loops--)
82
	cairo_stroke_preserve (cr);
83

            
84
    cairo_perf_timer_stop ();
85

            
86
    cairo_new_path (cr);
87

            
88
    return cairo_perf_timer_elapsed ();
89
}
90

            
91
static cairo_time_t
92
box_outline_aa_stroke (cairo_t *cr, int width, int height, int loops)
93
{
94
    cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
95
    cairo_paint (cr);
96

            
97
    cairo_translate (cr, .5, .5);
98
    cairo_rectangle (cr,
99
		     1.5, 1.5,
100
		     width - 3, height - 3);
101
    cairo_set_line_width (cr, 1.0);
102
    cairo_set_source_rgb (cr, 1, 0, 0); /* red */
103

            
104
    cairo_perf_timer_start ();
105

            
106
    while (loops--)
107
	cairo_stroke_preserve (cr);
108

            
109
    cairo_perf_timer_stop ();
110

            
111
    cairo_new_path (cr);
112

            
113
    return cairo_perf_timer_elapsed ();
114
}
115

            
116
static cairo_time_t
117
box_outline_fill (cairo_t *cr, int width, int height, int loops)
118
{
119
    cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
120
    cairo_paint (cr);
121

            
122
    cairo_rectangle (cr,
123
		     1.0, 1.0,
124
		     width - 2, height - 2);
125
    cairo_rectangle (cr,
126
		     2.0, 2.0,
127
		     width - 4, height - 4);
128
    cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
129
    cairo_set_source_rgb (cr, 0, 1, 0); /* green */
130

            
131
    cairo_perf_timer_start ();
132

            
133
    while (loops--)
134
	cairo_fill_preserve (cr);
135

            
136
    cairo_perf_timer_stop ();
137

            
138
    cairo_new_path (cr);
139

            
140
    return cairo_perf_timer_elapsed ();
141
}
142

            
143
static cairo_time_t
144
box_outline_alpha_fill (cairo_t *cr, int width, int height, int loops)
145
{
146
    cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
147
    cairo_paint (cr);
148

            
149
    cairo_rectangle (cr,
150
		     1.0, 1.0,
151
		     width - 2, height - 2);
152
    cairo_rectangle (cr,
153
		     2.0, 2.0,
154
		     width - 4, height - 4);
155
    cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
156
    cairo_set_source_rgba (cr, 0, 1, 0, .5); /* green */
157

            
158
    cairo_perf_timer_start ();
159

            
160
    while (loops--)
161
	cairo_fill_preserve (cr);
162

            
163
    cairo_perf_timer_stop ();
164

            
165
    cairo_new_path (cr);
166

            
167
    return cairo_perf_timer_elapsed ();
168
}
169

            
170
static cairo_time_t
171
box_outline_aa_fill (cairo_t *cr, int width, int height, int loops)
172
{
173
    cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
174
    cairo_paint (cr);
175

            
176
    cairo_translate (cr, .5, .5);
177
    cairo_rectangle (cr,
178
		     1.0, 1.0,
179
		     width - 2, height - 2);
180
    cairo_rectangle (cr,
181
		     2.0, 2.0,
182
		     width - 4, height - 4);
183
    cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
184
    cairo_set_source_rgb (cr, 0, 1, 0); /* green */
185

            
186
    cairo_perf_timer_start ();
187

            
188
    while (loops--)
189
	cairo_fill_preserve (cr);
190

            
191
    cairo_perf_timer_stop ();
192

            
193
    cairo_new_path (cr);
194

            
195
    return cairo_perf_timer_elapsed ();
196
}
197

            
198
cairo_bool_t
199
box_outline_enabled (cairo_perf_t *perf)
200
{
201
    return cairo_perf_can_run (perf, "box-outline", NULL);
202
}
203

            
204
void
205
box_outline (cairo_perf_t *perf, cairo_t *cr, int width, int height)
206
{
207
    cairo_perf_run (perf, "box-outline-stroke", box_outline_stroke, NULL);
208
    cairo_perf_run (perf, "box-outline-fill", box_outline_fill, NULL);
209

            
210
    cairo_perf_run (perf, "box-outline-alpha-stroke", box_outline_alpha_stroke, NULL);
211
    cairo_perf_run (perf, "box-outline-alpha-fill", box_outline_alpha_fill, NULL);
212

            
213
    cairo_perf_run (perf, "box-outline-aa-stroke", box_outline_aa_stroke, NULL);
214
    cairo_perf_run (perf, "box-outline-aa-fill", box_outline_aa_fill, NULL);
215
}