1 | /*
|
---|
2 | * SWT006_02.java
|
---|
3 | */
|
---|
4 |
|
---|
5 | /*
|
---|
6 | * Copyright (c) 2002, 2004 EclipseOS2 Team.
|
---|
7 | * This file is made available under the terms of the Common Public License v1.0
|
---|
8 | * which accompanies this distribution, and is available at
|
---|
9 | * http://www.eclipse.org/legal/cpl-v10.html
|
---|
10 | */
|
---|
11 |
|
---|
12 | import java.util.ArrayList;
|
---|
13 | import java.util.Iterator;
|
---|
14 | import org.eclipse.swt.*;
|
---|
15 | import org.eclipse.swt.widgets.*;
|
---|
16 | import org.eclipse.swt.events.*;
|
---|
17 | import org.eclipse.swt.graphics.*;
|
---|
18 | import org.eclipse.swt.layout.FormAttachment;
|
---|
19 | import org.eclipse.swt.layout.FormData;
|
---|
20 | import org.eclipse.swt.layout.FormLayout;
|
---|
21 |
|
---|
22 | /**
|
---|
23 | * This example tests the rate of image blitting operations in
|
---|
24 | * different modes as well as the overall speed of painting (including
|
---|
25 | * the time to prepare the next frame and to process events).
|
---|
26 | *
|
---|
27 | * Numbers shown in the title have the following meanings:
|
---|
28 | * B = rate of blitting operations (blits/second)
|
---|
29 | * O = overal rate of the output of one frame (blits/second)
|
---|
30 | * T = total time spent to blitting (milliseconds)
|
---|
31 | *
|
---|
32 | * Note that these values are very relative and hardly depend on the current
|
---|
33 | * mashine configuration as well as on intervals defined at the beginning of
|
---|
34 | * the SWT006_02 class. This relativeness is caused by unpreciseness of the
|
---|
35 | * method used to measure time (System.currentTimeMillis()), but it is enough
|
---|
36 | * to compare different modes of blitting.
|
---|
37 | *
|
---|
38 | * Due to a very small amount of time needed to blit one image without scaling,
|
---|
39 | * transparency and alpha (less than 1 ms on today computers) an image is
|
---|
40 | * drawn 100 times per every frame to make calculations a little more precise.
|
---|
41 | *
|
---|
42 | * Both test threads (UI and frame generator) are running on the
|
---|
43 | * maximum priority (Thread.MAX_PRIORITY) for better results.
|
---|
44 | *
|
---|
45 | * Note that when the display is in 256-color mode the moving wheel picture
|
---|
46 | * will be completely invisible due to palette-based mode limitations (its
|
---|
47 | * alpha is 4 out of 256 and the system matches its colors to colors of the
|
---|
48 | * background image).
|
---|
49 | *
|
---|
50 | */
|
---|
51 |
|
---|
52 | public class SWT006_02 extends SWTTestCase {
|
---|
53 |
|
---|
54 | static {
|
---|
55 | STEP= "006";
|
---|
56 | TEST = "02";
|
---|
57 | DESC = "Image output rate";
|
---|
58 | }
|
---|
59 |
|
---|
60 | // time to sleep before drawing the next frame
|
---|
61 | final long sleepInterval = 5;
|
---|
62 | // how frequently to update the FPS data
|
---|
63 | final long updateInterval = 100;
|
---|
64 | // how many times an image is drawn into every frame
|
---|
65 | final int imagesPerFrame = 100;
|
---|
66 |
|
---|
67 | //final long sleepInterval = 1000;
|
---|
68 | //final long updateInterval = 1000;
|
---|
69 | //final int imagesPerFrame = 1;
|
---|
70 |
|
---|
71 | Display display;
|
---|
72 | Shell shell;
|
---|
73 |
|
---|
74 | public static void main (String [] args) {
|
---|
75 | go (new SWT006_02 ());
|
---|
76 | }
|
---|
77 |
|
---|
78 | class FrameData {
|
---|
79 | static final int x = 10;
|
---|
80 | static final int y = 10;
|
---|
81 | static final int w = 200;
|
---|
82 | static final int h = 200;
|
---|
83 | int sw = w, sh = h;
|
---|
84 |
|
---|
85 | boolean ready;
|
---|
86 | boolean terminate;
|
---|
87 | boolean reset = true;
|
---|
88 |
|
---|
89 | int mode = 0;
|
---|
90 | static final int LAST_MODE = 5;
|
---|
91 |
|
---|
92 | String lastBlit = "{notready}";
|
---|
93 | String lastOverall = "{notready}";
|
---|
94 | String lastTime = "{notready}";
|
---|
95 | String getResults () {
|
---|
96 | return "[#"+mode+"] B=" + fd.lastBlit + " O=" + fd.lastOverall + " T=" + fd.lastTime;
|
---|
97 | }
|
---|
98 | }
|
---|
99 |
|
---|
100 | final FrameData fd = new FrameData ();
|
---|
101 |
|
---|
102 | Shell createTopShell (Display display) {
|
---|
103 |
|
---|
104 | this.display = display;
|
---|
105 | final Image frame = new Image (display, fd.w * 2, fd.h * 2);
|
---|
106 |
|
---|
107 | shell = new Shell (display,
|
---|
108 | SWT.SHELL_TRIM | SWT.NO_REDRAW_RESIZE | SWT.NO_BACKGROUND);
|
---|
109 |
|
---|
110 | final Thread runner = new Thread () {
|
---|
111 |
|
---|
112 | final Display display = SWT006_02.this.display;
|
---|
113 | boolean reset;
|
---|
114 |
|
---|
115 | public synchronized void run () {
|
---|
116 | int x = 0, y = 0;
|
---|
117 | boolean dir = true;
|
---|
118 | int maxXY = Math.min (fd.w, fd.h) - 40;
|
---|
119 |
|
---|
120 | Image back = new Image (display, fd.w * 2, fd.h * 2);
|
---|
121 | Image fore = new Image (display, fd.w, fd.h);
|
---|
122 | GC frameGc = new GC (frame);
|
---|
123 | GC backGc = new GC (back);
|
---|
124 | GC foreGc = new GC (fore);
|
---|
125 |
|
---|
126 | long startTime, lastUpdate, sleepTime, blitTime, frames;
|
---|
127 | startTime = lastUpdate = sleepTime = blitTime = frames = 0;
|
---|
128 | long time;
|
---|
129 |
|
---|
130 | {
|
---|
131 | Color clr = new Color (display, 255, 0, 0);
|
---|
132 | backGc.setForeground (clr);
|
---|
133 | Rectangle r = back.getBounds();
|
---|
134 | drawGrid (backGc, 0, 0, r.width, r.height, 10);
|
---|
135 | clr.dispose();
|
---|
136 | }
|
---|
137 |
|
---|
138 | while (!fd.terminate) {
|
---|
139 | synchronized (fd) {
|
---|
140 | try {
|
---|
141 | while (fd.ready) {
|
---|
142 | fd.wait();
|
---|
143 | }
|
---|
144 | } catch (InterruptedException e) {
|
---|
145 | break;
|
---|
146 | }
|
---|
147 | reset = fd.reset;
|
---|
148 | if (fd.reset) {
|
---|
149 | x = 0; y = 0;
|
---|
150 | dir = true;
|
---|
151 | sleepTime = blitTime = frames = 0;
|
---|
152 | startTime = lastUpdate = System.currentTimeMillis();
|
---|
153 | switch (fd.mode) {
|
---|
154 | case 0 :
|
---|
155 | fd.sw = fd.w;
|
---|
156 | fd.sh = fd.h;
|
---|
157 | break;
|
---|
158 | case 1 :
|
---|
159 | fd.sw = fd.w * 2;
|
---|
160 | break;
|
---|
161 | case 2 : {
|
---|
162 | ImageData i = fore.getImageData();
|
---|
163 | ImageData id = new ImageData (fd.w, fd.h, i.depth, i.palette);
|
---|
164 | id.transparentPixel = id.palette.getPixel(new RGB (255, 255, 255));
|
---|
165 | id.alpha = -1;
|
---|
166 | foreGc.dispose();
|
---|
167 | fore.dispose();
|
---|
168 | fore = new Image (display, id);
|
---|
169 | foreGc = new GC (fore);
|
---|
170 | fd.sw = fd.w;
|
---|
171 | fd.sh = fd.h;
|
---|
172 | break;
|
---|
173 | }
|
---|
174 | case 3 :
|
---|
175 | fd.sw = fd.w * 2;
|
---|
176 | break;
|
---|
177 | case 4 : {
|
---|
178 | ImageData i = fore.getImageData();
|
---|
179 | ImageData id = new ImageData (fd.w, fd.h, i.depth, i.palette);
|
---|
180 | id.transparentPixel = -1;
|
---|
181 | id.alpha = 4;
|
---|
182 | foreGc.dispose();
|
---|
183 | fore.dispose();
|
---|
184 | fore = new Image (display, id);
|
---|
185 | foreGc = new GC (fore);
|
---|
186 | fd.sw = fd.w;
|
---|
187 | fd.sh = fd.h;
|
---|
188 | break;
|
---|
189 | }
|
---|
190 | case 5 :
|
---|
191 | fd.sw = fd.w * 2;
|
---|
192 | break;
|
---|
193 | }
|
---|
194 | fd.reset = false;
|
---|
195 | } else {
|
---|
196 | frames += imagesPerFrame;
|
---|
197 | time = System.currentTimeMillis();
|
---|
198 | if (time - lastUpdate >= updateInterval) {
|
---|
199 | final String info1 =
|
---|
200 | div1000 (frames * 1000,
|
---|
201 | time - startTime - sleepTime);
|
---|
202 | final String info2 =
|
---|
203 | div1000 (frames * 1000, blitTime);
|
---|
204 | final String info3 =
|
---|
205 | div1000 (blitTime, 1000);
|
---|
206 | lastUpdate = time;
|
---|
207 | display.asyncExec( new Runnable () {
|
---|
208 | public void run() {
|
---|
209 | if (!shell.isDisposed ())
|
---|
210 | SWT006_02.this.updateTitle (info1, info2, info3);
|
---|
211 | }
|
---|
212 | });
|
---|
213 | }
|
---|
214 | if (sleepInterval > 0) {
|
---|
215 | time = System.currentTimeMillis();
|
---|
216 | try {
|
---|
217 | fd.wait (sleepInterval);
|
---|
218 | } catch (InterruptedException e) {
|
---|
219 | break;
|
---|
220 | }
|
---|
221 | sleepTime += System.currentTimeMillis() - time;
|
---|
222 | }
|
---|
223 | }
|
---|
224 | }
|
---|
225 |
|
---|
226 | foreGc.fillRectangle (fore.getBounds());
|
---|
227 | Color clr = foreGc.getBackground();
|
---|
228 | foreGc.setBackground (foreGc.getForeground());
|
---|
229 | foreGc.fillOval (x, y, 40, 40);
|
---|
230 | foreGc.setBackground (clr);
|
---|
231 | foreGc.fillOval (x + 10, y + 10, 20, 20);
|
---|
232 |
|
---|
233 | frameGc.drawImage (back, 0, 0);
|
---|
234 |
|
---|
235 | time = System.currentTimeMillis();
|
---|
236 | for (int i = 0; i < imagesPerFrame; i++) {
|
---|
237 | frameGc.drawImage (fore, 0, 0, fd.w, fd.h,
|
---|
238 | 0, 0, fd.sw, fd.sh);
|
---|
239 | }
|
---|
240 | blitTime += System.currentTimeMillis() - time;
|
---|
241 |
|
---|
242 | if (dir) {
|
---|
243 | x ++; y ++;
|
---|
244 | if (x == maxXY) dir = false;
|
---|
245 | } else {
|
---|
246 | x --; y --;
|
---|
247 | if (x == 0) dir = true;
|
---|
248 | }
|
---|
249 |
|
---|
250 | synchronized (fd) {
|
---|
251 | if (!fd.reset) {
|
---|
252 | fd.ready = true;
|
---|
253 | display.asyncExec( new Runnable () {
|
---|
254 | public void run() {
|
---|
255 | if (!shell.isDisposed ()) {
|
---|
256 | if (reset) {
|
---|
257 | shell.redraw();
|
---|
258 | } else {
|
---|
259 | shell.redraw (
|
---|
260 | fd.x, fd.y,
|
---|
261 | fd.sw, fd.sh, false);
|
---|
262 | }
|
---|
263 | }
|
---|
264 | }
|
---|
265 | });
|
---|
266 | }
|
---|
267 | }
|
---|
268 | }
|
---|
269 | foreGc.dispose();
|
---|
270 | backGc.dispose();
|
---|
271 | frameGc.dispose();
|
---|
272 | fore.dispose();
|
---|
273 | back.dispose();
|
---|
274 | System.out.println ("runner: terminated.");
|
---|
275 | }
|
---|
276 | };
|
---|
277 |
|
---|
278 | shell.addDisposeListener (new DisposeListener () {
|
---|
279 | public void widgetDisposed (DisposeEvent e) {
|
---|
280 | synchronized (fd) {
|
---|
281 | System.out.println (fd.getResults());
|
---|
282 | fd.ready = false;
|
---|
283 | fd.terminate = true;
|
---|
284 | fd.notifyAll ();
|
---|
285 | }
|
---|
286 | synchronized (runner) {;}
|
---|
287 | frame.dispose();
|
---|
288 | }
|
---|
289 | });
|
---|
290 |
|
---|
291 | shell.addPaintListener(new PaintListener () {
|
---|
292 |
|
---|
293 | public void paintControl(PaintEvent event) {
|
---|
294 |
|
---|
295 | GC gc = event.gc;
|
---|
296 | Rectangle r = new Rectangle (fd.x, fd.y, fd.sw, fd.sh);
|
---|
297 |
|
---|
298 | if (!gc.getClipping ().equals (r)) {
|
---|
299 | r = shell.getClientArea();
|
---|
300 | int frameX2 = fd.sw + fd.x;
|
---|
301 | int frameY2 = fd.sh + fd.y;
|
---|
302 | gc.fillRectangle (0, 0, frameX2, fd.y);
|
---|
303 | gc.fillRectangle (0, 0, fd.x, frameY2);
|
---|
304 | if (r.width > frameX2)
|
---|
305 | gc.fillRectangle(frameX2, 0, r.width, r.height);
|
---|
306 | if (r.height > frameY2)
|
---|
307 | gc.fillRectangle(0, frameY2, frameX2, r.height);
|
---|
308 | gc.drawRectangle (fd.x - 1, fd.y - 1, fd.sw + 1, fd.sh + 1);
|
---|
309 | }
|
---|
310 |
|
---|
311 | synchronized (fd) {
|
---|
312 | if (fd.ready) {
|
---|
313 | gc.drawImage (frame, 0, 0, fd.sw, fd.sh,
|
---|
314 | fd.x, fd.y, fd.sw, fd.sh);
|
---|
315 | fd.ready = false;
|
---|
316 | fd.notify();
|
---|
317 | }
|
---|
318 | }
|
---|
319 | }
|
---|
320 | });
|
---|
321 |
|
---|
322 | final Button next = new Button (shell, SWT.PUSH);
|
---|
323 | next.setText ("Next >");
|
---|
324 | next.addSelectionListener (new SelectionAdapter () {
|
---|
325 | public void widgetSelected (SelectionEvent e) {
|
---|
326 | if (fd.mode == fd.LAST_MODE)
|
---|
327 | shell.close();
|
---|
328 | else {
|
---|
329 | synchronized (fd) {
|
---|
330 | if (fd.mode != fd.LAST_MODE)
|
---|
331 | System.out.println (fd.getResults());
|
---|
332 | fd.mode++;
|
---|
333 | if (fd.mode == fd.LAST_MODE)
|
---|
334 | next.setText ("Finish");
|
---|
335 | fd.ready = false;
|
---|
336 | fd.reset = true;
|
---|
337 | fd.notify();
|
---|
338 | }
|
---|
339 | }
|
---|
340 | }
|
---|
341 | });
|
---|
342 |
|
---|
343 | FormData fdata = new FormData();
|
---|
344 | fdata.right = new FormAttachment (100, -10);
|
---|
345 | fdata.bottom = new FormAttachment (100, -10);
|
---|
346 | next.setLayoutData (fdata);
|
---|
347 | FormLayout formLayout = new FormLayout ();
|
---|
348 | shell.setLayout (formLayout);
|
---|
349 |
|
---|
350 | Rectangle dr = display.getBounds ();
|
---|
351 | Rectangle sr = new Rectangle (0, 0, 640, 300);
|
---|
352 | sr.x = (dr.width-sr.width)/2;
|
---|
353 | sr.y = (dr.height-sr.height)/2;
|
---|
354 | shell.setBounds (sr);
|
---|
355 |
|
---|
356 | Thread.currentThread ().setPriority (Thread.MAX_PRIORITY);
|
---|
357 | runner.setPriority (Thread.MAX_PRIORITY);
|
---|
358 | runner.start();
|
---|
359 |
|
---|
360 | return shell;
|
---|
361 | }
|
---|
362 |
|
---|
363 | static void drawGrid (GC gc, int x0, int y0, int width, int height, int step)
|
---|
364 | {
|
---|
365 | int i;
|
---|
366 | for (i = 0; i <= width/step; i++)
|
---|
367 | gc.drawLine (x0+i*step, y0, x0+i*step, y0+height);
|
---|
368 | for (i = 0; i <= height/step; i++)
|
---|
369 | gc.drawLine (x0, y0+i*step, x0+width, y0+i*step);
|
---|
370 | }
|
---|
371 |
|
---|
372 | static String div1000 (long a, long b) {
|
---|
373 | if (b <= 0) return "{infinite}";
|
---|
374 | String rc =
|
---|
375 | "000000" + (a / b) + "." + (((a % b) * 1000) / b) + "000";
|
---|
376 | int h = rc.indexOf ('.') - 6;
|
---|
377 | return rc.substring (h, h + 10);
|
---|
378 | }
|
---|
379 |
|
---|
380 | String title;
|
---|
381 |
|
---|
382 | void updateTitle (String overall, String blit, String time) {
|
---|
383 | if (title == null) {
|
---|
384 | title = shell.getText();
|
---|
385 | }
|
---|
386 | if (overall != null) fd.lastOverall = overall;
|
---|
387 | if (blit != null) fd.lastBlit = blit;
|
---|
388 | if (time != null) fd.lastTime = time;
|
---|
389 | shell.setText (title + " " + fd.getResults());
|
---|
390 | }
|
---|
391 |
|
---|
392 | }
|
---|