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

            
27
/* Measure the overhead in setting a single pixel */
28

            
29
#include "cairo-perf.h"
30

            
31
#include <pixman.h>
32

            
33
static cairo_time_t
34
pixel_direct (cairo_t *cr, int width, int height, int loops)
35
{
36
    cairo_surface_t *surface, *image;
37
    uint32_t *data;
38
    int stride, bpp;
39

            
40
    surface = cairo_get_target (cr);
41
    image = cairo_surface_map_to_image (surface, NULL);
42
    data = (uint32_t *) cairo_image_surface_get_data (image);
43
    stride = cairo_image_surface_get_stride (image) / sizeof (uint32_t);
44

            
45
    switch (cairo_image_surface_get_format (image)) {
46
    default:
47
    case CAIRO_FORMAT_INVALID:
48
    case CAIRO_FORMAT_A1: bpp = 0; break;
49
    case CAIRO_FORMAT_A8: bpp = 8; break;
50
    case CAIRO_FORMAT_RGB16_565: bpp = 16; break;
51
    case CAIRO_FORMAT_RGB24:
52
    case CAIRO_FORMAT_RGB30:
53
    case CAIRO_FORMAT_ARGB32: bpp = 32; break;
54
    case CAIRO_FORMAT_RGB96F: bpp = 96; break;
55
    case CAIRO_FORMAT_RGBA128F: bpp = 128; break;
56
    }
57

            
58
    cairo_perf_timer_start ();
59

            
60
    while (loops--)
61
	pixman_fill (data, stride, bpp, 0, 0, 1, 1, -1);
62

            
63
    cairo_perf_timer_stop ();
64

            
65
    cairo_surface_unmap_image (surface, image);
66

            
67
    return cairo_perf_timer_elapsed ();
68
}
69

            
70
static cairo_time_t
71
pixel_paint (cairo_t *cr, int width, int height, int loops)
72
{
73
    cairo_perf_timer_start ();
74

            
75
    while (loops--)
76
	cairo_paint (cr);
77

            
78
    cairo_perf_timer_stop ();
79

            
80
    return cairo_perf_timer_elapsed ();
81
}
82

            
83
static cairo_time_t
84
pixel_mask (cairo_t *cr, int width, int height, int loops)
85
{
86
    cairo_surface_t *mask;
87
    cairo_t *cr2;
88

            
89
    mask = cairo_surface_create_similar (cairo_get_target (cr),
90
					 CAIRO_CONTENT_ALPHA,
91
					 1, 1);
92
    cr2 = cairo_create (mask);
93
    cairo_set_source_rgb (cr2, 1,1,1);
94
    cairo_paint (cr2);
95
    cairo_destroy (cr2);
96

            
97
    cairo_perf_timer_start ();
98

            
99
    while (loops--)
100
	cairo_mask_surface (cr, mask, 0, 0);
101

            
102
    cairo_perf_timer_stop ();
103

            
104
    cairo_surface_destroy (mask);
105

            
106
    return cairo_perf_timer_elapsed ();
107
}
108

            
109
static cairo_time_t
110
pixel_rectangle (cairo_t *cr, int width, int height, int loops)
111
{
112
    cairo_new_path (cr);
113
    cairo_rectangle (cr, 0, 0, 1, 1);
114

            
115
    cairo_perf_timer_start ();
116

            
117
    while (loops--)
118
	cairo_fill_preserve (cr);
119

            
120
    cairo_perf_timer_stop ();
121

            
122
    cairo_new_path (cr);
123
    return cairo_perf_timer_elapsed ();
124
}
125

            
126
static cairo_time_t
127
pixel_subrectangle (cairo_t *cr, int width, int height, int loops)
128
{
129
    cairo_new_path (cr);
130
    cairo_rectangle (cr, 0.1, 0.1, .8, .8);
131

            
132
    cairo_perf_timer_start ();
133

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

            
137
    cairo_perf_timer_stop ();
138

            
139
    cairo_new_path (cr);
140
    return cairo_perf_timer_elapsed ();
141
}
142

            
143
static cairo_time_t
144
pixel_triangle (cairo_t *cr, int width, int height, int loops)
145
{
146
    cairo_new_path (cr);
147
    cairo_move_to (cr, 0, 0);
148
    cairo_line_to (cr, 1, 1);
149
    cairo_line_to (cr, 0, 1);
150

            
151
    cairo_perf_timer_start ();
152

            
153
    while (loops--)
154
	cairo_fill_preserve (cr);
155

            
156
    cairo_perf_timer_stop ();
157

            
158
    cairo_new_path (cr);
159
    return cairo_perf_timer_elapsed ();
160
}
161

            
162
static cairo_time_t
163
pixel_circle (cairo_t *cr, int width, int height, int loops)
164
{
165
    cairo_new_path (cr);
166
    cairo_arc (cr, 0.5, 0.5, 0.5, 0, 2 * M_PI);
167

            
168
    cairo_perf_timer_start ();
169

            
170
    while (loops--)
171
	cairo_fill_preserve (cr);
172

            
173
    cairo_perf_timer_stop ();
174

            
175
    cairo_new_path (cr);
176
    return cairo_perf_timer_elapsed ();
177
}
178

            
179
static cairo_time_t
180
pixel_stroke (cairo_t *cr, int width, int height, int loops)
181
{
182
    cairo_set_line_width (cr, 1.);
183
    cairo_new_path (cr);
184
    cairo_move_to (cr, 0, 0.5);
185
    cairo_line_to (cr, 1, 0.5);
186

            
187
    cairo_perf_timer_start ();
188

            
189
    while (loops--)
190
	cairo_stroke_preserve (cr);
191

            
192
    cairo_perf_timer_stop ();
193

            
194
    cairo_new_path (cr);
195
    return cairo_perf_timer_elapsed ();
196
}
197

            
198
cairo_bool_t
199
pixel_enabled (cairo_perf_t *perf)
200
{
201
    return cairo_perf_can_run (perf, "pixel", NULL);
202
}
203

            
204
void
205
pixel (cairo_perf_t *perf, cairo_t *cr, int width, int height)
206
{
207
    cairo_set_source_rgb (cr, 1., 1., 1.);
208

            
209
    cairo_perf_run (perf, "pixel-direct", pixel_direct, NULL);
210
    cairo_perf_run (perf, "pixel-paint", pixel_paint, NULL);
211
    cairo_perf_run (perf, "pixel-mask", pixel_mask, NULL);
212
    cairo_perf_run (perf, "pixel-rectangle", pixel_rectangle, NULL);
213
    cairo_perf_run (perf, "pixel-subrectangle", pixel_subrectangle, NULL);
214
    cairo_perf_run (perf, "pixel-triangle", pixel_triangle, NULL);
215
    cairo_perf_run (perf, "pixel-circle", pixel_circle, NULL);
216
    cairo_perf_run (perf, "pixel-stroke", pixel_stroke, NULL);
217
}
218

            
219
cairo_bool_t
220
a1_pixel_enabled (cairo_perf_t *perf)
221
{
222
    return cairo_perf_can_run (perf, "a1-pixel", NULL);
223
}
224

            
225
void
226
a1_pixel (cairo_perf_t *perf, cairo_t *cr, int width, int height)
227
{
228
    cairo_set_source_rgb (cr, 1., 1., 1.);
229
    cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
230

            
231
    cairo_perf_run (perf, "a1-pixel-direct", pixel_direct, NULL);
232
    cairo_perf_run (perf, "a1-pixel-paint", pixel_paint, NULL);
233
    cairo_perf_run (perf, "a1-pixel-mask", pixel_mask, NULL);
234
    cairo_perf_run (perf, "a1-pixel-rectangle", pixel_rectangle, NULL);
235
    cairo_perf_run (perf, "a1-pixel-subrectangle", pixel_subrectangle, NULL);
236
    cairo_perf_run (perf, "a1-pixel-triangle", pixel_triangle, NULL);
237
    cairo_perf_run (perf, "a1-pixel-circle", pixel_circle, NULL);
238
    cairo_perf_run (perf, "a1-pixel-stroke", pixel_stroke, NULL);
239
}