Run wxClientDC and wxMemoryDC tests too in the graphics benchmark.
[wxWidgets.git] / tests / benchmarks / graphics.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: graphics.cpp
3 // Purpose: Some benchmarks for measuring graphics operations performance
4 // Author: Vadim Zeitlin
5 // Created: 2008-04-13
6 // RCS-ID: $Id$
7 // Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 #include "wx/app.h"
12 #include "wx/frame.h"
13 #include "wx/cmdline.h"
14 #include "wx/dcclient.h"
15 #include "wx/dcmemory.h"
16 #include "wx/dcgraph.h"
17 #include "wx/stopwatch.h"
18 #include "wx/crt.h"
19
20 struct GraphicsBenchmarkOptions
21 {
22 GraphicsBenchmarkOptions()
23 {
24 mapMode = 0;
25 penWidth = 0;
26
27 width = 800;
28 height = 600;
29
30 numLines = 10000;
31
32 testBitmaps =
33 testLines =
34 testRectangles = false;
35 }
36
37 long mapMode,
38 penWidth,
39 width,
40 height,
41 numLines;
42
43 bool testBitmaps,
44 testLines,
45 testRectangles;
46 } opts;
47
48 class GraphicsBenchmarkFrame : public wxFrame
49 {
50 public:
51 GraphicsBenchmarkFrame()
52 : wxFrame(NULL, wxID_ANY, "wxWidgets Graphics Benchmark")
53 {
54 Connect(wxEVT_PAINT,
55 wxPaintEventHandler(GraphicsBenchmarkFrame::OnPaint));
56
57 m_bitmap.Create(64, 64, 32);
58
59 Show();
60 SetClientSize(opts.width, opts.height);
61 }
62
63 private:
64 void OnPaint(wxPaintEvent& WXUNUSED(event))
65 {
66 {
67 wxPaintDC dc(this);
68 wxGCDC gcdc(dc);
69 BenchmarkDCAndGC("paint", dc, gcdc);
70 }
71
72 {
73 wxClientDC dc(this);
74 wxGCDC gcdc(dc);
75 BenchmarkDCAndGC("client", dc, gcdc);
76 }
77
78 {
79 wxBitmap bmp(opts.width, opts.height);
80 wxMemoryDC dc(bmp);
81 wxGCDC gcdc(dc);
82 BenchmarkDCAndGC("memory", dc, gcdc);
83 }
84
85 wxTheApp->ExitMainLoop();
86 }
87
88 void BenchmarkDCAndGC(const char* dckind, wxDC& dc, wxGCDC& gcdc)
89 {
90 BenchmarkAll(wxString::Format("%6s DC", dckind), dc);
91 BenchmarkAll(wxString::Format("%6s GC", dckind), gcdc);
92 }
93
94 void BenchmarkAll(const wxString& msg, wxDC& dc)
95 {
96 BenchmarkLines(msg, dc);
97 BenchmarkRectangles(msg, dc);
98 BenchmarkBitmaps(msg, dc);
99 }
100
101 void BenchmarkLines(const wxString& msg, wxDC& dc)
102 {
103 if ( !opts.testLines )
104 return;
105
106 if ( opts.mapMode != 0 )
107 dc.SetMapMode((wxMappingMode)opts.mapMode);
108 if ( opts.penWidth != 0 )
109 dc.SetPen(wxPen(*wxWHITE, opts.penWidth));
110
111 wxPrintf("Benchmarking %s: ", msg);
112
113 wxStopWatch sw;
114 int x = 0,
115 y = 0;
116 for ( int n = 0; n < opts.numLines; n++ )
117 {
118 int x1 = rand() % opts.width,
119 y1 = rand() % opts.height;
120
121 dc.DrawLine(x, y, x1, y1);
122
123 x = x1;
124 y = y1;
125 }
126
127 const long t = sw.Time();
128
129 wxPrintf("%ld lines done in %ldms = %gus/line\n",
130 opts.numLines, t, (1000. * t)/opts.numLines);
131 }
132
133
134 void BenchmarkRectangles(const wxString& msg, wxDC& dc)
135 {
136 if ( !opts.testRectangles )
137 return;
138
139 if ( opts.mapMode != 0 )
140 dc.SetMapMode((wxMappingMode)opts.mapMode);
141 if ( opts.penWidth != 0 )
142 dc.SetPen(wxPen(*wxWHITE, opts.penWidth));
143
144 dc.SetBrush( *wxRED_BRUSH );
145
146 wxPrintf("Benchmarking %s: ", msg);
147
148 wxStopWatch sw;
149 for ( int n = 0; n < opts.numLines; n++ )
150 {
151 int x = rand() % opts.width,
152 y = rand() % opts.height;
153
154 dc.DrawRectangle(x, y, 32, 32);
155 }
156
157 const long t = sw.Time();
158
159 wxPrintf("%ld rects done in %ldms = %gus/rect\n",
160 opts.numLines, t, (1000. * t)/opts.numLines);
161 }
162
163 void BenchmarkBitmaps(const wxString& msg, wxDC& dc)
164 {
165 if ( !opts.testBitmaps )
166 return;
167
168 if ( opts.mapMode != 0 )
169 dc.SetMapMode((wxMappingMode)opts.mapMode);
170 if ( opts.penWidth != 0 )
171 dc.SetPen(wxPen(*wxWHITE, opts.penWidth));
172
173 wxPrintf("Benchmarking %s: ", msg);
174
175 wxStopWatch sw;
176 for ( int n = 0; n < opts.numLines; n++ )
177 {
178 int x = rand() % opts.width,
179 y = rand() % opts.height;
180
181 dc.DrawBitmap(m_bitmap, x, y, true);
182 }
183
184 const long t = sw.Time();
185
186 wxPrintf("%ld bitmaps done in %ldms = %gus/bitmap\n",
187 opts.numLines, t, (1000. * t)/opts.numLines);
188 }
189
190
191 wxBitmap m_bitmap;
192 };
193
194 class GraphicsBenchmarkApp : public wxApp
195 {
196 public:
197 virtual void OnInitCmdLine(wxCmdLineParser& parser)
198 {
199 static const wxCmdLineEntryDesc desc[] =
200 {
201 { wxCMD_LINE_SWITCH, "", "bitmaps" },
202 { wxCMD_LINE_SWITCH, "", "lines" },
203 { wxCMD_LINE_SWITCH, "", "rectangles" },
204 { wxCMD_LINE_OPTION, "m", "map-mode", "", wxCMD_LINE_VAL_NUMBER },
205 { wxCMD_LINE_OPTION, "p", "pen-width", "", wxCMD_LINE_VAL_NUMBER },
206 { wxCMD_LINE_OPTION, "w", "width", "", wxCMD_LINE_VAL_NUMBER },
207 { wxCMD_LINE_OPTION, "h", "height", "", wxCMD_LINE_VAL_NUMBER },
208 { wxCMD_LINE_OPTION, "L", "lines", "", wxCMD_LINE_VAL_NUMBER },
209 { wxCMD_LINE_NONE },
210 };
211
212 parser.SetDesc(desc);
213 }
214
215 virtual bool OnCmdLineParsed(wxCmdLineParser& parser)
216 {
217 if ( parser.Found("m", &opts.mapMode) &&
218 (opts.mapMode < 1 || opts.mapMode > wxMM_METRIC) )
219 return false;
220 if ( parser.Found("p", &opts.penWidth) && opts.penWidth < 1 )
221 return false;
222 if ( parser.Found("w", &opts.width) && opts.width < 1 )
223 return false;
224 if ( parser.Found("h", &opts.height) && opts.height < 1 )
225 return false;
226 if ( parser.Found("L", &opts.numLines) && opts.numLines < 1 )
227 return false;
228
229 opts.testBitmaps = parser.Found("bitmaps");
230 opts.testLines = parser.Found("lines");
231 opts.testRectangles = parser.Found("rectangles");
232 if ( !(opts.testBitmaps || opts.testLines || opts.testRectangles) )
233 {
234 // Do everything by default.
235 opts.testBitmaps =
236 opts.testLines =
237 opts.testRectangles = true;
238 }
239
240 return true;
241 }
242
243 virtual bool OnInit()
244 {
245 if ( !wxApp::OnInit() )
246 return false;
247
248 new GraphicsBenchmarkFrame;
249
250 return true;
251 }
252 };
253
254 IMPLEMENT_APP_CONSOLE(GraphicsBenchmarkApp)