xref: /haiku/src/tests/add-ons/opengl/fake_renderer/FakeRenderer.cpp (revision 99d027cd0238c1d86da86d7c3f4200509ccc61a6)
1 /*
2  * Copyright 2006-2008, Haiku. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Philippe Houdoin, philippe.houdoin@free.fr
7  */
8 /*
9  * Mesa 3-D graphics library
10  * Version:  6.1
11  *
12  * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
13  */
14 
15 #include "FakeRenderer.h"
16 
17 #include <stdio.h>
18 
19 #include <Autolock.h>
20 #include <DirectWindowPrivate.h>
21 #include <GraphicsDefs.h>
22 #include <Screen.h>
23 
24 
25 extern const char * color_space_name(color_space space);
26 
27 
28 extern "C" _EXPORT BGLRenderer*
29 instantiate_gl_renderer(BGLView* view, ulong options,
30 	BGLDispatcher* dispatcher)
31 {
32 	return new FakeRenderer(view, options, dispatcher);
33 }
34 
35 
36 FakeRenderer::FakeRenderer(BGLView* view, ulong options,
37 		BGLDispatcher* dispatcher)
38 	: BGLRenderer(view, options, dispatcher),
39 	fOptions(options),
40 	fDrawLocker("direct draw locker"),
41 	fFrameBuffer(NULL),
42 	fColorSpace(B_NO_COLOR_SPACE),
43 	fRects(NULL),
44 	fConnected(false),
45 	fDisabled(false)
46 {
47 	fDrawSem = create_sem(0, "FakeRenderer draw");
48 	fDrawThread = spawn_thread(_DirectDrawThread, "FakeRenderer direct draw", B_DISPLAY_PRIORITY, this);
49 	resume_thread(fDrawThread);
50 
51 }
52 
53 FakeRenderer::~FakeRenderer()
54 {
55 	// Wakeup the draw thread by murdering its favorite semaphore
56 	delete_sem(fDrawSem);
57 
58 	status_t exit_value;
59 	wait_for_thread(fDrawThread, &exit_value);
60 
61 	free(fRects);
62 }
63 
64 
65 void
66 FakeRenderer::SwapBuffers(bool VSync)
67 {
68 	if (VSync && GLView()->Window()) {
69 		// TODO: find a way to check VSync support is actually working...
70 		BScreen screen(GLView()->Window());
71 		screen.WaitForRetrace();
72 	}
73 
74 	// Simulate rendering a new buffer: randomized buffer color ;-)
75 	fDrawColor = make_color(rand() % 0xFF, rand() % 0xFF, rand() % 0xFF);
76 
77 	if (!fConnected || fDisabled) {
78 		GLView()->LockLooper();
79 		// TODO : refresh area
80 		GLView()->UnlockLooper();
81 		return;
82 	}
83 
84 	// Direct mode: wake up drawing thread
85 	release_sem(fDrawSem);
86 }
87 
88 
89 void
90 FakeRenderer::Draw(BRect updateRect)
91 {
92 /*
93 	if (fBitmap && (!fDirectModeEnabled || (fInfo == NULL)))
94 		GLView()->DrawBitmap(fBitmap, updateRect, updateRect);
95 */
96 }
97 
98 
99 void
100 FakeRenderer::EnableDirectMode(bool enabled)
101 {
102 	fDisabled = ! enabled;
103 }
104 
105 
106 void
107 FakeRenderer::DirectConnected(direct_buffer_info *info)
108 {
109 	if (!fConnected && fDisabled)
110 		return;
111 
112 	BAutolock lock(fDrawLocker);
113 
114 	switch (info->buffer_state & B_DIRECT_MODE_MASK) {
115 	case B_DIRECT_START:
116 		fConnected = true;
117 		/* fall through */
118 	case B_DIRECT_MODIFY:
119 		fFrameBuffer = (uint8 *) info->bits;
120 		fBytesPerRow = info->bytes_per_row;
121 		fColorSpace = info->pixel_format;
122 
123 		free(fRects);
124 		fRectsCount = info->clip_list_count;
125 		fRects = (clipping_rect *) malloc(fRectsCount * sizeof(clipping_rect));
126 		memcpy(fRects, info->clip_list, fRectsCount * sizeof(clipping_rect));
127 
128 		fprintf(stderr, "fFrameBuffer = %p\n"
129 						"fBytesPerRow = %d\n"
130 						"fColorSpace  = %s\n", fFrameBuffer, fBytesPerRow, color_space_name(fColorSpace));
131 		for (int i = 0; i < fRectsCount; i++) {
132 			fprintf(stderr, "fRects[%d] = %d, %d to %d, %d\n",
133 				i, fRects[i].left, fRects[i].top, fRects[i].right, fRects[i].bottom);
134 		}
135 		break;
136 
137 	case B_DIRECT_STOP:
138 		fConnected = false;
139 		break;
140 	}
141 
142 	fprintf(stderr, "fConnected = %s\n", fConnected ? "true" : "false");
143 }
144 
145 
146 // ----
147 
148 
149 int32
150 FakeRenderer::_DirectDrawThread(void *data)
151 {
152 	FakeRenderer *me = (FakeRenderer *) data;
153 	return me->_DirectDrawThread();
154 }
155 
156 
157 int32
158 FakeRenderer::_DirectDrawThread(void)
159 {
160 	// Let's wait forever/until semaphore death next redraw
161 	while (acquire_sem(fDrawSem) == B_OK) {
162 
163 		BAutolock lock(fDrawLocker);
164 
165 		int i;
166 		int32 x, y;
167 
168 		switch(fColorSpace) {
169 		case B_RGB32:
170 		case B_RGBA32:
171 			for (i = 0; i < fRectsCount; i++) {
172 				for (y = fRects[i].top; y <= fRects[i].bottom; y++) {
173 					uint8 * p = fFrameBuffer + ( y * fBytesPerRow ) + fRects[i].left * 4;
174 					for (x = fRects[i].left; x <= fRects[i].right; x++) {
175 						*p++ = fDrawColor.blue;
176 						*p++ = fDrawColor.green;
177 						*p++ = fDrawColor.red;
178 						*p++ = fDrawColor.alpha;
179 					}
180 				}
181 			}
182 			break;
183 
184 		case B_RGB24:
185 		case B_RGB32_BIG:
186 		case B_RGBA32_BIG:
187 		case B_RGB24_BIG:
188 			/* fill this in with the color-space conversion
189 			 * code of your choosing
190 			 */
191 			break;
192 
193 		case B_RGB16:
194 		case B_RGB15:
195 		case B_RGBA15:
196 		case B_RGB16_BIG:
197 		case B_RGB15_BIG:
198 		case B_RGBA15_BIG:
199 			/* same here */
200 			break;
201 
202 		case B_CMAP8:
203 			/* same here */
204 			break;
205 
206 		default:
207 			/* unsupported mode */
208 			break;
209 		}
210 
211 	} // while draw
212 
213 	return 0;
214 }
215 
216 
217 
218