xref: /haiku/src/tests/servers/app/newerClipping/main.cpp (revision 0a6ef8179ccb4f058fc1b571c1f6bca98ef5d224)
1 
2 #include <Application.h>
3 #include <DirectWindow.h>
4 #include <View.h>
5 
6 #include <stdio.h>
7 #include <stdlib.h>
8 
9 #include "AccelerantHWInterface.h"
10 #include "Desktop.h"
11 #include "DirectWindowBuffer.h"
12 #include "DrawingEngine.h"
13 #include "DrawView.h"
14 #include "ViewLayer.h"
15 #include "WindowLayer.h"
16 
17 class App : public BApplication {
18  public:
19 						App();
20 
21 	virtual void		ReadyToRun();
22 };
23 
24 class Window : public BDirectWindow {
25  public:
26 								Window(const char* title);
27 	virtual						~Window();
28 
29 	virtual	bool				QuitRequested();
30 
31 	virtual void				DirectConnected(direct_buffer_info* info);
32 
33 			void				AddWindow(BRect frame, const char* name);
34 			void				Test();
35  private:
36 		DrawView*				fView;
37 		Desktop*				fDesktop;
38 		bool					fQuit;
39 		DirectWindowBuffer		fBuffer;
40 		AccelerantHWInterface	fInterface;
41 		DrawingEngine			fEngine;
42 
43 };
44 
45 // constructor
App()46 App::App()
47 	: BApplication("application/x-vnd.stippi.ClippingTest")
48 {
49 	srand(real_time_clock_usecs());
50 }
51 
52 // ReadyToRun
53 void
ReadyToRun()54 App::ReadyToRun()
55 {
56 	Window* win = new Window("clipping");
57 	win->Show();
58 
59 //	win->Test();
60 }
61 
62 // constructor
Window(const char * title)63 Window::Window(const char* title)
64 	: BDirectWindow(BRect(50, 50, 800, 650), title,
65 					B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, B_ASYNCHRONOUS_CONTROLS),
66 	  fQuit(false),
67 	  fBuffer(),
68 	  fInterface(),
69 	  fEngine(&fInterface, &fBuffer)
70 {
71 	fInterface.Initialize();
72 	fView = new DrawView(Bounds());
73 	AddChild(fView);
74 	fView->MakeFocus(true);
75 
76 	fDesktop = new Desktop(fView, &fEngine);
77 	fDesktop->Run();
78 }
79 
80 // destructor
~Window()81 Window::~Window()
82 {
83 	fInterface.Shutdown();
84 	fDesktop->Lock();
85 	fDesktop->Quit();
86 }
87 
88 // QuitRequested
89 bool
QuitRequested()90 Window::QuitRequested()
91 {
92 /*	if (!fQuit) {
93 		fDesktop->PostMessage(MSG_QUIT);
94 		fQuit = true;
95 		return false;
96 	}*/
97 be_app->PostMessage(B_QUIT_REQUESTED);
98 	return true;
99 }
100 
101 // #pragma mark -
102 
103 void
fill_line_8(uint8 * buffer,int32 pixels,uint8 r,uint8 g,uint8 b)104 fill_line_8(uint8* buffer, int32 pixels, uint8 r, uint8 g, uint8 b)
105 {
106 	for (int32 i = 0; i < pixels; i++) {
107 		*buffer++ = b;
108 		*buffer++ = g;
109 		*buffer++ = r;
110 		*buffer++ = 255;
111 	}
112 }
113 
114 void
fill_line_32(uint8 * buffer,int32 pixels,uint8 r,uint8 g,uint8 b)115 fill_line_32(uint8* buffer, int32 pixels, uint8 r, uint8 g, uint8 b)
116 {
117 	uint32 pixel;
118 	uint32* handle = (uint32*)buffer;
119 	for (int32 i = 0; i < pixels; i++) {
120 		pixel = 0xff000000 | (r << 16) | (g << 8) | (b);
121 		*handle++ = pixel;
122 	}
123 }
124 
125 void
fill_line_64(uint8 * buffer,int32 pixels,uint8 r,uint8 g,uint8 b)126 fill_line_64(uint8* buffer, int32 pixels, uint8 r, uint8 g, uint8 b)
127 {
128 	uint64 pixel;
129 	uint64* handle = (uint64*)buffer;
130 	pixels /= 2;
131 	for (int32 i = 0; i < pixels; i++) {
132 		pixel = 0xff000000 | (r << 16) | (g << 8) | (b);
133 		pixel = pixel << 32;
134 		pixel |= 0xff000000 | (r << 16) | (g << 8) | (b);
135 		*handle++ = pixel;
136 	}
137 }
138 
139 void
test1(uint8 * buffer,uint32 bpr)140 test1(uint8* buffer, uint32 bpr)
141 {
142 	uint8* handle = buffer;
143 
144 /*	bigtime_t start8 = system_time();
145 	for (int32 x = 0; x < 1000; x++) {
146 		handle = buffer;
147 		for (int32 i = 0; i < 64; i++) {
148 			fill_line_8(handle, 512, 255, 0, 255);
149 			handle += bpr;
150 		}
151 	}
152 
153 	bigtime_t start32 = system_time();
154 	for (int32 x = 0; x < 1000; x++) {
155 		handle = buffer;
156 		for (int32 i = 0; i < 64; i++) {
157 			fill_line_32(handle, 512, 255, 0, 255);
158 			handle += bpr;
159 		}
160 	}
161 
162 	bigtime_t start64 = system_time();
163 	for (int32 x = 0; x < 1000; x++) {*/
164 		handle = buffer;
165 		for (int32 i = 0; i < 640; i++) {
166 			fill_line_64(handle, 512, 0, 255, 255);
167 			handle += bpr;
168 		}
169 /*	}
170 
171 
172 	bigtime_t finish = system_time();
173 	printf("8:  %lld\n", start32 - start8);
174 	printf("32: %lld\n", start64 - start32);
175 	printf("64: %lld\n", finish - start64);*/
176 }
177 
178 // #pragma mark -
179 
180 void
blend_line_8(uint8 * buffer,int32 pixels,uint8 r,uint8 g,uint8 b,uint8 a)181 blend_line_8(uint8* buffer, int32 pixels, uint8 r, uint8 g, uint8 b, uint8 a)
182 {
183 	for (int32 i = 0; i < pixels; i++) {
184 		buffer[0] = ((b - buffer[0]) * a + (buffer[0] << 8)) >> 8;
185 		buffer[1] = ((g - buffer[1]) * a + (buffer[1] << 8)) >> 8;
186 		buffer[2] = ((r - buffer[2]) * a + (buffer[2] << 8)) >> 8;;
187 		buffer[3] = a;
188 		buffer += 4;
189 	}
190 }
191 
192 union pixel {
193 	uint32	data32;
194 	uint8	data8[4];
195 };
196 
197 void
blend_line_32(uint8 * buffer,int32 pixels,uint8 r,uint8 g,uint8 b,uint8 a)198 blend_line_32(uint8* buffer, int32 pixels, uint8 r, uint8 g, uint8 b, uint8 a)
199 {
200 	pixel p;
201 	pixels /= 2;
202 	for (int32 i = 0; i < pixels; i++) {
203 		p.data32 = *(uint32*)buffer;
204 
205 		p.data8[0] = ((b - p.data8[0]) * a + (p.data8[0] << 8)) >> 8;
206 		p.data8[1] = ((g - p.data8[1]) * a + (p.data8[1] << 8)) >> 8;
207 		p.data8[2] = ((r - p.data8[2]) * a + (p.data8[2] << 8)) >> 8;
208 		p.data8[3] = 255;
209 		*((uint32*)buffer) = p.data32;
210 		buffer += 4;
211 
212 		p.data32 = *(uint32*)buffer;
213 
214 		p.data8[0] = ((b - p.data8[0]) * a + (p.data8[0] << 8)) >> 8;
215 		p.data8[1] = ((g - p.data8[1]) * a + (p.data8[1] << 8)) >> 8;
216 		p.data8[2] = ((r - p.data8[2]) * a + (p.data8[2] << 8)) >> 8;
217 		p.data8[3] = 255;
218 		*((uint32*)buffer) = p.data32;
219 		buffer += 4;
220 	}
221 }
222 
223 union pixel2 {
224 	uint64	data64;
225 	uint8	data8[8];
226 };
227 
228 // gfxcpy32
229 // * numBytes is expected to be a multiple of 4
230 inline
231 void
gfxcpy32(uint8 * dst,uint8 * src,int32 numBytes)232 gfxcpy32(uint8* dst, uint8* src, int32 numBytes)
233 {
234 	uint64* d64 = (uint64*)dst;
235 	uint64* s64 = (uint64*)src;
236 	int32 numBytesStart = numBytes;
237 	while (numBytes >= 32) {
238 		*d64++ = *s64++;
239 		*d64++ = *s64++;
240 		*d64++ = *s64++;
241 		*d64++ = *s64++;
242 		numBytes -= 32;
243 	}
244 	if (numBytes >= 16) {
245 		*d64++ = *s64++;
246 		*d64++ = *s64++;
247 		numBytes -= 16;
248 	}
249 	if (numBytes >= 8) {
250 		*d64++ = *s64++;
251 		numBytes -= 8;
252 	}
253 	if (numBytes == 4) {
254 		uint32* d32 = (uint32*)(dst + numBytesStart - numBytes);
255 		uint32* s32 = (uint32*)(src + numBytesStart - numBytes);
256 		*d32 = *s32;
257 	}
258 }
259 
260 void
blend_line_64(uint8 * buffer,int32 pixels,uint8 r,uint8 g,uint8 b,uint8 a)261 blend_line_64(uint8* buffer, int32 pixels, uint8 r, uint8 g, uint8 b, uint8 a)
262 {
263 	pixel2 p;
264 	pixels /= 2;
265 
266 	r = (r * a) >> 8;
267 	g = (g * a) >> 8;
268 	b = (b * a) >> 8;
269 	a = 255 - a;
270 
271 	uint8 tempBuffer[pixels * 8];
272 
273 	uint8* t = tempBuffer;
274 	uint8* s = buffer;
275 
276 	for (int32 i = 0; i < pixels; i++) {
277 		p.data64 = *(uint64*)s;
278 
279 		t[0] = ((p.data8[0] * a) >> 8) + b;
280 		t[1] = ((p.data8[1] * a) >> 8) + g;
281 		t[2] = ((p.data8[2] * a) >> 8) + r;
282 
283 		t[4] = ((p.data8[4] * a) >> 8) + b;
284 		t[5] = ((p.data8[5] * a) >> 8) + g;
285 		t[6] = ((p.data8[6] * a) >> 8) + r;
286 
287 		t += 8;
288 		s += 8;
289 	}
290 
291 	gfxcpy32(buffer, tempBuffer, pixels * 8);
292 }
293 void
test2(uint8 * buffer,uint32 bpr)294 test2(uint8* buffer, uint32 bpr)
295 {
296 	uint8* handle = buffer;
297 
298 /*	bigtime_t start8 = system_time();
299 //	for (int32 x = 0; x < 10; x++) {
300 		handle = buffer;
301 		for (int32 i = 0; i < 64; i++) {
302 			blend_line_8(handle, 512, 255, 0, 0, 20);
303 			handle += bpr;
304 		}
305 //	}
306 
307 	bigtime_t start32 = system_time();
308 //	for (int32 x = 0; x < 10; x++) {
309 		handle = buffer;
310 		for (int32 i = 0; i < 64; i++) {
311 			blend_line_32(handle, 512, 255, 0, 0, 20);
312 			handle += bpr;
313 		}
314 //	}*/
315 
316 	bigtime_t start64 = system_time();
317 //	for (int32 x = 0; x < 10; x++) {
318 		handle = buffer;
319 		for (int32 i = 0; i < 640; i++) {
320 			blend_line_64(handle, 512, 255, 0, 0, 200);
321 			handle += bpr;
322 		}
323 //	}
324 
325 	bigtime_t finish = system_time();
326 //	printf("8:  %lld\n", start32 - start8);
327 //	printf("32: %lld\n", start64 - start32);
328 	printf("blend 64: %lld\n", finish - start64);
329 }
330 
331 // #pragma mark -
332 
333 // DirectConnected
334 void
DirectConnected(direct_buffer_info * info)335 Window::DirectConnected(direct_buffer_info* info)
336 {
337 	// TODO: for some reason, this deadlocks
338 	// on B_DIRECT_STOP... be aware
339 //	fDesktop->LockClipping();
340 
341 //	fEngine.Lock();
342 
343 	switch(info->buffer_state & B_DIRECT_MODE_MASK) {
344 		case B_DIRECT_START:
345 		case B_DIRECT_MODIFY:
346 			fBuffer.SetTo(info);
347 			fDesktop->SetOffset(info->window_bounds.left, info->window_bounds.top);
348 			test2((uint8*)info->bits, info->bytes_per_row);
349 			break;
350 		case B_DIRECT_STOP:
351 			fBuffer.SetTo(NULL);
352 			break;
353 	}
354 
355 //	fDesktop->SetMasterClipping(&fBuffer.WindowClipping());
356 
357 //	fEngine.Unlock();
358 
359 //	fDesktop->UnlockClipping();
360 }
361 
362 // AddWindow
363 void
AddWindow(BRect frame,const char * name)364 Window::AddWindow(BRect frame, const char* name)
365 {
366 	WindowLayer* window = new WindowLayer(frame, name,
367 										  fDesktop->GetDrawingEngine(),
368 										  fDesktop);
369 
370 	// add a coupld children
371 	frame.OffsetTo(B_ORIGIN);
372 	frame.InsetBy(5.0, 5.0);
373 	if (frame.IsValid()) {
374 		ViewLayer* layer1 = new ViewLayer(frame, "View 1",
375 										  B_FOLLOW_ALL,
376 										  B_FULL_UPDATE_ON_RESIZE,
377 										  (rgb_color){ 180, 180, 180, 255 });
378 
379 		frame.OffsetTo(B_ORIGIN);
380 		frame.InsetBy(15.0, 15.0);
381 		if (frame.IsValid()) {
382 
383 			BRect f = frame;
384 			f.bottom = f.top + f.Height() / 3 - 3;
385 			f.right = f.left + f.Width() / 3 - 3;
386 
387 			// top row of views
388 			ViewLayer* layer;
389 			layer = new ViewLayer(f, "View", B_FOLLOW_LEFT | B_FOLLOW_TOP,
390 								  B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
391 			layer1->AddChild(layer);
392 
393 			f.OffsetBy(f.Width() + 6, 0);
394 
395 			layer = new ViewLayer(f, "View", B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP,
396 								  B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
397 			layer1->AddChild(layer);
398 
399 			f.OffsetBy(f.Width() + 6, 0);
400 
401 			layer = new ViewLayer(f, "View", B_FOLLOW_RIGHT | B_FOLLOW_TOP,
402 								  B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
403 			layer1->AddChild(layer);
404 
405 			// middle row of views
406 			f = frame;
407 			f.bottom = f.top + f.Height() / 3 - 3;
408 			f.right = f.left + f.Width() / 3 - 3;
409 			f.OffsetBy(0, f.Height() + 6);
410 
411 			layer = new ViewLayer(f, "View", B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM,
412 								  B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
413 			layer1->AddChild(layer);
414 
415 			f.OffsetBy(f.Width() + 6, 0);
416 
417 			layer = new ViewLayer(f, "View", B_FOLLOW_ALL,
418 								  B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
419 			layer1->AddChild(layer);
420 
421 			f.OffsetBy(f.Width() + 6, 0);
422 
423 			layer = new ViewLayer(f, "View", B_FOLLOW_RIGHT | B_FOLLOW_TOP_BOTTOM,
424 								  B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
425 			layer1->AddChild(layer);
426 
427 			// bottom row of views
428 			f = frame;
429 			f.bottom = f.top + f.Height() / 3 - 3;
430 			f.right = f.left + f.Width() / 3 - 3;
431 			f.OffsetBy(0, 2 * f.Height() + 12);
432 
433 			layer = new ViewLayer(f, "View", B_FOLLOW_LEFT | B_FOLLOW_BOTTOM,
434 								  B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
435 			layer1->AddChild(layer);
436 
437 			f.OffsetBy(f.Width() + 6, 0);
438 
439 //			layer = new ViewLayer(f, "View", B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM,
440 			layer = new ViewLayer(f, "View", B_FOLLOW_LEFT | B_FOLLOW_BOTTOM,
441 								  B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
442 			layer1->AddChild(layer);
443 
444 			f.OffsetBy(f.Width() + 6, 0);
445 
446 //			layer = new ViewLayer(f, "View", B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM,
447 			layer = new ViewLayer(f, "View", B_FOLLOW_LEFT | B_FOLLOW_BOTTOM,
448 								  B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
449 			layer1->AddChild(layer);
450 		}
451 
452 		window->AddChild(layer1);
453 	}
454 
455 	window->Run();
456 
457 	BMessage message(MSG_ADD_WINDOW);
458 	message.AddPointer("window", (void*)window);
459 	fDesktop->PostMessage(&message);
460 }
461 
462 // Test
463 void
Test()464 Window::Test()
465 {
466 	BRect frame(20, 20, 330, 230);
467 //	AddWindow(frame, "Window 1");
468 //	AddWindow(frame, "Window 2");
469 	for (int32 i = 0; i < 20; i++) {
470 		BString name("Window ");
471 		frame.OffsetBy(20, 15);
472 		name << i + 1;
473 		AddWindow(frame, name.String());
474 	}
475 
476 /*	frame.Set(10, 80, 320, 290);
477 	for (int32 i = 20; i < 40; i++) {
478 		BString name("Window ");
479 		frame.OffsetBy(20, 15);
480 		name << i + 1;
481 		AddWindow(frame, name.String());
482 	}
483 
484 	frame.Set(20, 140, 330, 230);
485 	for (int32 i = 40; i < 60; i++) {
486 		BString name("Window ");
487 		frame.OffsetBy(20, 15);
488 		name << i + 1;
489 		AddWindow(frame, name.String());
490 	}
491 
492 	frame.Set(20, 200, 330, 230);
493 	for (int32 i = 60; i < 80; i++) {
494 		BString name("Window ");
495 		frame.OffsetBy(20, 15);
496 		name << i + 1;
497 		AddWindow(frame, name.String());
498 	}
499 
500 	frame.Set(20, 260, 330, 230);
501 // 99 windows are ok, the 100th looper does not run anymore,
502 // I guess I'm hitting a BeOS limit (max loopers per app?)
503 	for (int32 i = 80; i < 99; i++) {
504 		BString name("Window ");
505 		frame.OffsetBy(20, 15);
506 		name << i + 1;
507 		AddWindow(frame, name.String());
508 	}*/
509 }
510 
511 // main
512 int
main(int argc,const char * argv[])513 main(int argc, const char* argv[])
514 {
515 	srand((long int)system_time());
516 
517 	App app;
518 	app.Run();
519 	return 0;
520 }
521