1
/*
2
 * Copyright © 2005 Owen Taylor
3
 * Copyright © 2007 Dan Amelang
4
 * Copyright © 2007 Chris Wilson
5
 *
6
 * Permission to use, copy, modify, distribute, and sell this software
7
 * and its documentation for any purpose is hereby granted without
8
 * fee, provided that the above copyright notice appear in all copies
9
 * and that both that copyright notice and this permission notice
10
 * appear in supporting documentation, and that the name of
11
 * the authors not be used in advertising or publicity pertaining to
12
 * distribution of the software without specific, written prior
13
 * permission. The authors make no representations about the
14
 * suitability of this software for any purpose.  It is provided "as
15
 * is" without express or implied warranty.
16
 *
17
 * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
18
 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
19
 * FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
20
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
21
 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
22
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
23
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
 *
25
 * Authors: Chris Wilson <chris@chris-wilson.co.uk>
26
 */
27

            
28
/* This perf case is derived from the bug report
29
 *   Gradient on 'rounded rectangle' MUCH slower than normal rectangle
30
 *   https://bugs.freedesktop.org/show_bug.cgi?id=4263.
31
 */
32

            
33
#include "cairo-perf.h"
34

            
35
#define RECTANGLE_COUNT (1000)
36

            
37
#if 0
38
#define MODE cairo_perf_run
39
#else
40
#define MODE cairo_perf_cover_sources_and_operators
41
#endif
42

            
43
static struct
44
{
45
    double x;
46
    double y;
47
    double width;
48
    double height;
49
} rects[RECTANGLE_COUNT];
50

            
51
static void
52
rounded_rectangle (cairo_t *cr,
53
		   double x, double y, double w, double h,
54
		   double radius)
55
{
56
    cairo_move_to (cr, x+radius, y);
57
    cairo_arc (cr, x+w-radius, y+radius,   radius, M_PI + M_PI / 2, M_PI * 2        );
58
    cairo_arc (cr, x+w-radius, y+h-radius, radius, 0,               M_PI / 2        );
59
    cairo_arc (cr, x+radius,   y+h-radius, radius, M_PI/2,          M_PI            );
60
    cairo_arc (cr, x+radius,   y+radius,   radius, M_PI,            270 * M_PI / 180);
61
}
62

            
63
static cairo_time_t
64
do_rectangle (cairo_t *cr, int width, int height, int loops)
65
{
66
    cairo_perf_timer_start ();
67

            
68
    while (loops--) {
69
	rounded_rectangle (cr, 0, 0, width, height, 3.0);
70
	cairo_fill (cr);
71
    }
72

            
73
    cairo_perf_timer_stop ();
74

            
75
    return cairo_perf_timer_elapsed ();
76
}
77

            
78
static cairo_time_t
79
do_rectangles (cairo_t *cr, int width, int height, int loops)
80
{
81
    int i;
82

            
83
    cairo_perf_timer_start ();
84

            
85
    while (loops--) {
86
	for (i = 0; i < RECTANGLE_COUNT; i++) {
87
	    rounded_rectangle (cr,
88
			       rects[i].x, rects[i].y,
89
			       rects[i].width, rects[i].height,
90
			       3.0);
91
	    cairo_fill (cr);
92
	}
93
    }
94

            
95
    cairo_perf_timer_stop ();
96

            
97
    return cairo_perf_timer_elapsed ();
98
}
99

            
100
static cairo_time_t
101
do_rectangles_once (cairo_t *cr, int width, int height, int loops)
102
{
103
    int i;
104

            
105
    cairo_perf_timer_start ();
106

            
107
    while (loops--) {
108
	for (i = 0; i < RECTANGLE_COUNT; i++) {
109
	    rounded_rectangle (cr,
110
			       rects[i].x, rects[i].y,
111
			       rects[i].width, rects[i].height,
112
			       3.0);
113
	}
114
	cairo_fill (cr);
115
    }
116

            
117
    cairo_perf_timer_stop ();
118

            
119
    return cairo_perf_timer_elapsed ();
120
}
121

            
122
cairo_bool_t
123
rounded_rectangles_enabled (cairo_perf_t *perf)
124
{
125
    return cairo_perf_can_run (perf, "rounded-rectangles", NULL);
126
}
127

            
128
void
129
rounded_rectangles (cairo_perf_t *perf, cairo_t *cr, int width, int height)
130
{
131
    int i;
132

            
133
    srand (8478232);
134
    for (i = 0; i < RECTANGLE_COUNT; i++) {
135
        rects[i].x = rand () % width;
136
        rects[i].y = rand () % height;
137
        rects[i].width  = (rand () % (width / 10)) + 1;
138
        rects[i].height = (rand () % (height / 10)) + 1;
139
    }
140

            
141
    MODE (perf, "one-rounded-rectangle", do_rectangle, NULL);
142
    MODE (perf, "rounded-rectangles", do_rectangles, NULL);
143
    MODE (perf, "rounded-rectangles-once", do_rectangles_once, NULL);
144
}