No changes, just rename command line option in graphics benchmark test.
[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/image.h"
18 #include "wx/rawbmp.h"
19 #include "wx/stopwatch.h"
20 #include "wx/crt.h"
21
22 struct GraphicsBenchmarkOptions
23 {
24 GraphicsBenchmarkOptions()
25 {
26 mapMode = 0;
27 penWidth = 0;
28
29 width = 800;
30 height = 600;
31
32 numIters = 1000;
33
34 testBitmaps =
35 testImages =
36 testLines =
37 testRawBitmaps =
38 testRectangles = false;
39
40 usePaint =
41 useClient =
42 useMemory = false;
43
44 useDC =
45 useGC = false;
46 }
47
48 long mapMode,
49 penWidth,
50 width,
51 height,
52 numIters;
53
54 bool testBitmaps,
55 testImages,
56 testLines,
57 testRawBitmaps,
58 testRectangles;
59
60 bool usePaint,
61 useClient,
62 useMemory;
63
64 bool useDC,
65 useGC;
66 } opts;
67
68 class GraphicsBenchmarkFrame : public wxFrame
69 {
70 public:
71 GraphicsBenchmarkFrame()
72 : wxFrame(NULL, wxID_ANY, "wxWidgets Graphics Benchmark")
73 {
74 Connect(wxEVT_PAINT,
75 wxPaintEventHandler(GraphicsBenchmarkFrame::OnPaint));
76
77 m_bitmap.Create(64, 64, 32);
78
79 Show();
80 SetClientSize(opts.width, opts.height);
81 }
82
83 private:
84 void OnPaint(wxPaintEvent& WXUNUSED(event))
85 {
86 if ( opts.usePaint )
87 {
88 wxPaintDC dc(this);
89 wxGCDC gcdc(dc);
90 BenchmarkDCAndGC("paint", dc, gcdc);
91 }
92
93 if ( opts.useClient )
94 {
95 wxClientDC dc(this);
96 wxGCDC gcdc(dc);
97 BenchmarkDCAndGC("client", dc, gcdc);
98 }
99
100 if ( opts.useMemory )
101 {
102 wxBitmap bmp(opts.width, opts.height);
103 wxMemoryDC dc(bmp);
104 wxGCDC gcdc(dc);
105 BenchmarkDCAndGC("memory", dc, gcdc);
106 }
107
108 wxTheApp->ExitMainLoop();
109 }
110
111 void BenchmarkDCAndGC(const char* dckind, wxDC& dc, wxGCDC& gcdc)
112 {
113 if ( opts.useDC )
114 BenchmarkAll(wxString::Format("%6s DC", dckind), dc);
115 if ( opts.useGC )
116 BenchmarkAll(wxString::Format("%6s GC", dckind), gcdc);
117 }
118
119 void BenchmarkAll(const wxString& msg, wxDC& dc)
120 {
121 BenchmarkBitmaps(msg, dc);
122 BenchmarkImages(msg, dc);
123 BenchmarkLines(msg, dc);
124 BenchmarkRawBitmaps(msg, dc);
125 BenchmarkRectangles(msg, dc);
126 }
127
128 void BenchmarkLines(const wxString& msg, wxDC& dc)
129 {
130 if ( !opts.testLines )
131 return;
132
133 if ( opts.mapMode != 0 )
134 dc.SetMapMode((wxMappingMode)opts.mapMode);
135 if ( opts.penWidth != 0 )
136 dc.SetPen(wxPen(*wxWHITE, opts.penWidth));
137
138 wxPrintf("Benchmarking %s: ", msg);
139 fflush(stdout);
140
141 wxStopWatch sw;
142 int x = 0,
143 y = 0;
144 for ( int n = 0; n < opts.numIters; n++ )
145 {
146 int x1 = rand() % opts.width,
147 y1 = rand() % opts.height;
148
149 dc.DrawLine(x, y, x1, y1);
150
151 x = x1;
152 y = y1;
153 }
154
155 const long t = sw.Time();
156
157 wxPrintf("%ld lines done in %ldms = %gus/line\n",
158 opts.numIters, t, (1000. * t)/opts.numIters);
159 }
160
161
162 void BenchmarkRectangles(const wxString& msg, wxDC& dc)
163 {
164 if ( !opts.testRectangles )
165 return;
166
167 if ( opts.mapMode != 0 )
168 dc.SetMapMode((wxMappingMode)opts.mapMode);
169 if ( opts.penWidth != 0 )
170 dc.SetPen(wxPen(*wxWHITE, opts.penWidth));
171
172 dc.SetBrush( *wxRED_BRUSH );
173
174 wxPrintf("Benchmarking %s: ", msg);
175 fflush(stdout);
176
177 wxStopWatch sw;
178 for ( int n = 0; n < opts.numIters; n++ )
179 {
180 int x = rand() % opts.width,
181 y = rand() % opts.height;
182
183 dc.DrawRectangle(x, y, 32, 32);
184 }
185
186 const long t = sw.Time();
187
188 wxPrintf("%ld rects done in %ldms = %gus/rect\n",
189 opts.numIters, t, (1000. * t)/opts.numIters);
190 }
191
192 void BenchmarkBitmaps(const wxString& msg, wxDC& dc)
193 {
194 if ( !opts.testBitmaps )
195 return;
196
197 if ( opts.mapMode != 0 )
198 dc.SetMapMode((wxMappingMode)opts.mapMode);
199 if ( opts.penWidth != 0 )
200 dc.SetPen(wxPen(*wxWHITE, opts.penWidth));
201
202 wxPrintf("Benchmarking %s: ", msg);
203 fflush(stdout);
204
205 wxStopWatch sw;
206 for ( int n = 0; n < opts.numIters; n++ )
207 {
208 int x = rand() % opts.width,
209 y = rand() % opts.height;
210
211 dc.DrawBitmap(m_bitmap, x, y, true);
212 }
213
214 const long t = sw.Time();
215
216 wxPrintf("%ld bitmaps done in %ldms = %gus/bitmap\n",
217 opts.numIters, t, (1000. * t)/opts.numIters);
218 }
219
220 void BenchmarkImages(const wxString& msg, wxDC& dc)
221 {
222 if ( !opts.testImages )
223 return;
224
225 if ( opts.mapMode != 0 )
226 dc.SetMapMode((wxMappingMode)opts.mapMode);
227
228 wxPrintf("Benchmarking %s: ", msg);
229 fflush(stdout);
230
231 wxImage image(wxSize(opts.width, opts.height), false /* don't clear */);
232
233 wxStopWatch sw;
234 for ( int n = 0; n < opts.numIters; n++ )
235 {
236 image.Clear(n % 256);
237 dc.DrawBitmap(image, 0, 0);
238 }
239
240 const long t = sw.Time();
241
242 wxPrintf("%ld images done in %ldms = %gus/image or %d FPS\n",
243 opts.numIters, t, (1000. * t)/opts.numIters,
244 (1000*opts.numIters + t - 1)/t);
245 }
246
247 void BenchmarkRawBitmaps(const wxString& msg, wxDC& dc)
248 {
249 if ( !opts.testRawBitmaps )
250 return;
251
252 if ( opts.mapMode != 0 )
253 dc.SetMapMode((wxMappingMode)opts.mapMode);
254
255 wxPrintf("Benchmarking %s: ", msg);
256 fflush(stdout);
257
258 wxBitmap bitmap(opts.width, opts.height, 24);
259 wxNativePixelData data(bitmap);
260
261 wxStopWatch sw;
262 for ( int n = 0; n < opts.numIters; n++ )
263 {
264 const unsigned char c = n % 256;
265 {
266 wxNativePixelData::Iterator p(data);
267 for ( int y = 0; y < opts.height; ++y )
268 {
269 wxNativePixelData::Iterator rowStart = p;
270
271 for ( int x = 0; x < opts.width; ++x )
272 {
273 p.Red() =
274 p.Green() =
275 p.Blue() = c;
276 ++p;
277 }
278
279 p = rowStart;
280 p.OffsetY(data, 1);
281 }
282 }
283
284 dc.DrawBitmap(bitmap, 0, 0);
285 }
286
287 const long t = sw.Time();
288
289 wxPrintf("%ld raw bitmaps done in %ldms = %gus/bitmap or %d FPS\n",
290 opts.numIters, t, (1000. * t)/opts.numIters,
291 (1000*opts.numIters + t - 1)/t);
292 }
293
294
295 wxBitmap m_bitmap;
296 };
297
298 class GraphicsBenchmarkApp : public wxApp
299 {
300 public:
301 virtual void OnInitCmdLine(wxCmdLineParser& parser)
302 {
303 static const wxCmdLineEntryDesc desc[] =
304 {
305 { wxCMD_LINE_SWITCH, "", "bitmaps" },
306 { wxCMD_LINE_SWITCH, "", "images" },
307 { wxCMD_LINE_SWITCH, "", "lines" },
308 { wxCMD_LINE_SWITCH, "", "rawbmp" },
309 { wxCMD_LINE_SWITCH, "", "rectangles" },
310 { wxCMD_LINE_SWITCH, "", "paint" },
311 { wxCMD_LINE_SWITCH, "", "client" },
312 { wxCMD_LINE_SWITCH, "", "memory" },
313 { wxCMD_LINE_SWITCH, "", "dc" },
314 { wxCMD_LINE_SWITCH, "", "gc" },
315 { wxCMD_LINE_OPTION, "m", "map-mode", "", wxCMD_LINE_VAL_NUMBER },
316 { wxCMD_LINE_OPTION, "p", "pen-width", "", wxCMD_LINE_VAL_NUMBER },
317 { wxCMD_LINE_OPTION, "w", "width", "", wxCMD_LINE_VAL_NUMBER },
318 { wxCMD_LINE_OPTION, "h", "height", "", wxCMD_LINE_VAL_NUMBER },
319 { wxCMD_LINE_OPTION, "I", "images", "", wxCMD_LINE_VAL_NUMBER },
320 { wxCMD_LINE_OPTION, "N", "number-of-iterations", "", wxCMD_LINE_VAL_NUMBER },
321 { wxCMD_LINE_NONE },
322 };
323
324 parser.SetDesc(desc);
325 }
326
327 virtual bool OnCmdLineParsed(wxCmdLineParser& parser)
328 {
329 if ( parser.Found("m", &opts.mapMode) &&
330 (opts.mapMode < 1 || opts.mapMode > wxMM_METRIC) )
331 return false;
332 if ( parser.Found("p", &opts.penWidth) && opts.penWidth < 1 )
333 return false;
334 if ( parser.Found("w", &opts.width) && opts.width < 1 )
335 return false;
336 if ( parser.Found("h", &opts.height) && opts.height < 1 )
337 return false;
338 if ( parser.Found("N", &opts.numIters) && opts.numIters < 1 )
339 return false;
340
341 opts.testBitmaps = parser.Found("bitmaps");
342 opts.testImages = parser.Found("images");
343 opts.testLines = parser.Found("lines");
344 opts.testRawBitmaps = parser.Found("rawbmp");
345 opts.testRectangles = parser.Found("rectangles");
346 if ( !(opts.testBitmaps || opts.testImages || opts.testLines
347 || opts.testRawBitmaps || opts.testRectangles) )
348 {
349 // Do everything by default.
350 opts.testBitmaps =
351 opts.testImages =
352 opts.testLines =
353 opts.testRawBitmaps =
354 opts.testRectangles = true;
355 }
356
357 opts.usePaint = parser.Found("paint");
358 opts.useClient = parser.Found("client");
359 opts.useMemory = parser.Found("memory");
360 if ( !(opts.usePaint || opts.useClient || opts.useMemory) )
361 {
362 opts.usePaint =
363 opts.useClient =
364 opts.useMemory = true;
365 }
366
367 opts.useDC = parser.Found("dc");
368 opts.useGC = parser.Found("gc");
369 if ( !(opts.useDC || opts.useGC) )
370 {
371 opts.useDC =
372 opts.useGC = true;
373 }
374
375 return true;
376 }
377
378 virtual bool OnInit()
379 {
380 if ( !wxApp::OnInit() )
381 return false;
382
383 new GraphicsBenchmarkFrame;
384
385 return true;
386 }
387 };
388
389 IMPLEMENT_APP_CONSOLE(GraphicsBenchmarkApp)