10832f66cSPhilippe Houdoin/*
20832f66cSPhilippe Houdoin * Copyright 2006-2008, Haiku. All rights reserved.
30832f66cSPhilippe Houdoin * Distributed under the terms of the MIT License.
40832f66cSPhilippe Houdoin *
50832f66cSPhilippe Houdoin * Authors:
60832f66cSPhilippe Houdoin *		Philippe Houdoin, philippe.houdoin@free.fr
70832f66cSPhilippe Houdoin */
80832f66cSPhilippe Houdoin/*
90832f66cSPhilippe Houdoin * Mesa 3-D graphics library
100832f66cSPhilippe Houdoin * Version:  6.1
110832f66cSPhilippe Houdoin *
120832f66cSPhilippe Houdoin * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
130832f66cSPhilippe Houdoin */
140832f66cSPhilippe Houdoin
150832f66cSPhilippe Houdoin#include "FakeRenderer.h"
160832f66cSPhilippe Houdoin
170832f66cSPhilippe Houdoin#include <stdio.h>
180832f66cSPhilippe Houdoin
190832f66cSPhilippe Houdoin#include <Autolock.h>
200832f66cSPhilippe Houdoin#include <DirectWindowPrivate.h>
210832f66cSPhilippe Houdoin#include <GraphicsDefs.h>
220832f66cSPhilippe Houdoin#include <Screen.h>
230832f66cSPhilippe Houdoin
240832f66cSPhilippe Houdoin
250832f66cSPhilippe Houdoinextern const char * color_space_name(color_space space);
260832f66cSPhilippe Houdoin
270832f66cSPhilippe Houdoin
280832f66cSPhilippe Houdoinextern "C" _EXPORT BGLRenderer*
290832f66cSPhilippe Houdoininstantiate_gl_renderer(BGLView* view, ulong options,
300832f66cSPhilippe Houdoin	BGLDispatcher* dispatcher)
310832f66cSPhilippe Houdoin{
320832f66cSPhilippe Houdoin	return new FakeRenderer(view, options, dispatcher);
330832f66cSPhilippe Houdoin}
340832f66cSPhilippe Houdoin
350832f66cSPhilippe Houdoin
360832f66cSPhilippe HoudoinFakeRenderer::FakeRenderer(BGLView* view, ulong options,
370832f66cSPhilippe Houdoin		BGLDispatcher* dispatcher)
380832f66cSPhilippe Houdoin	: BGLRenderer(view, options, dispatcher),
390832f66cSPhilippe Houdoin	fOptions(options),
400832f66cSPhilippe Houdoin	fDrawLocker("direct draw locker"),
410832f66cSPhilippe Houdoin	fFrameBuffer(NULL),
420832f66cSPhilippe Houdoin	fColorSpace(B_NO_COLOR_SPACE),
430832f66cSPhilippe Houdoin	fRects(NULL),
440832f66cSPhilippe Houdoin	fConnected(false),
450832f66cSPhilippe Houdoin	fDisabled(false)
460832f66cSPhilippe Houdoin{
470832f66cSPhilippe Houdoin	fDrawSem = create_sem(0, "FakeRenderer draw");
480832f66cSPhilippe Houdoin	fDrawThread = spawn_thread(_DirectDrawThread, "FakeRenderer direct draw", B_DISPLAY_PRIORITY, this);
490832f66cSPhilippe Houdoin	resume_thread(fDrawThread);
500832f66cSPhilippe Houdoin
510832f66cSPhilippe Houdoin}
520832f66cSPhilippe Houdoin
530832f66cSPhilippe HoudoinFakeRenderer::~FakeRenderer()
540832f66cSPhilippe Houdoin{
550832f66cSPhilippe Houdoin	// Wakeup the draw thread by murdering its favorite semaphore
560832f66cSPhilippe Houdoin	delete_sem(fDrawSem);
570832f66cSPhilippe Houdoin
580832f66cSPhilippe Houdoin	status_t exit_value;
590832f66cSPhilippe Houdoin	wait_for_thread(fDrawThread, &exit_value);
600832f66cSPhilippe Houdoin
610832f66cSPhilippe Houdoin	free(fRects);
620832f66cSPhilippe Houdoin}
630832f66cSPhilippe Houdoin
640832f66cSPhilippe Houdoin
650832f66cSPhilippe Houdoinvoid
660832f66cSPhilippe HoudoinFakeRenderer::SwapBuffers(bool VSync)
670832f66cSPhilippe Houdoin{
680832f66cSPhilippe Houdoin	if (VSync && GLView()->Window()) {
690832f66cSPhilippe Houdoin		// TODO: find a way to check VSync support is actually working...
700832f66cSPhilippe Houdoin		BScreen screen(GLView()->Window());
710832f66cSPhilippe Houdoin		screen.WaitForRetrace();
720832f66cSPhilippe Houdoin	}
730832f66cSPhilippe Houdoin
740832f66cSPhilippe Houdoin	// Simulate rendering a new buffer: randomized buffer color ;-)
750832f66cSPhilippe Houdoin	fDrawColor = make_color(rand() % 0xFF, rand() % 0xFF, rand() % 0xFF);
760832f66cSPhilippe Houdoin
770832f66cSPhilippe Houdoin	if (!fConnected || fDisabled) {
780832f66cSPhilippe Houdoin		GLView()->LockLooper();
790832f66cSPhilippe Houdoin		// TODO : refresh area
800832f66cSPhilippe Houdoin		GLView()->UnlockLooper();
810832f66cSPhilippe Houdoin		return;
820832f66cSPhilippe Houdoin	}
830832f66cSPhilippe Houdoin
840832f66cSPhilippe Houdoin	// Direct mode: wake up drawing thread
850832f66cSPhilippe Houdoin	release_sem(fDrawSem);
860832f66cSPhilippe Houdoin}
870832f66cSPhilippe Houdoin
880832f66cSPhilippe Houdoin
890832f66cSPhilippe Houdoinvoid
900832f66cSPhilippe HoudoinFakeRenderer::Draw(BRect updateRect)
910832f66cSPhilippe Houdoin{
920832f66cSPhilippe Houdoin/*
930832f66cSPhilippe Houdoin	if (fBitmap && (!fDirectModeEnabled || (fInfo == NULL)))
940832f66cSPhilippe Houdoin		GLView()->DrawBitmap(fBitmap, updateRect, updateRect);
950832f66cSPhilippe Houdoin*/
960832f66cSPhilippe Houdoin}
970832f66cSPhilippe Houdoin
980832f66cSPhilippe Houdoin
990832f66cSPhilippe Houdoinvoid
1000832f66cSPhilippe HoudoinFakeRenderer::EnableDirectMode(bool enabled)
1010832f66cSPhilippe Houdoin{
1020832f66cSPhilippe Houdoin	fDisabled = ! enabled;
1030832f66cSPhilippe Houdoin}
1040832f66cSPhilippe Houdoin
1050832f66cSPhilippe Houdoin
1060832f66cSPhilippe Houdoinvoid
1070832f66cSPhilippe HoudoinFakeRenderer::DirectConnected(direct_buffer_info *info)
1080832f66cSPhilippe Houdoin{
1090832f66cSPhilippe Houdoin	if (!fConnected && fDisabled)
1100832f66cSPhilippe Houdoin		return;
1110832f66cSPhilippe Houdoin
1120832f66cSPhilippe Houdoin	BAutolock lock(fDrawLocker);
1130832f66cSPhilippe Houdoin
1140832f66cSPhilippe Houdoin	switch (info->buffer_state & B_DIRECT_MODE_MASK) {
1150832f66cSPhilippe Houdoin	case B_DIRECT_START:
1160832f66cSPhilippe Houdoin		fConnected = true;
1170832f66cSPhilippe Houdoin		/* fall through */
1180832f66cSPhilippe Houdoin	case B_DIRECT_MODIFY:
1190832f66cSPhilippe Houdoin		fFrameBuffer = (uint8 *) info->bits;
1200832f66cSPhilippe Houdoin		fBytesPerRow = info->bytes_per_row;
1210832f66cSPhilippe Houdoin		fColorSpace = info->pixel_format;
1220832f66cSPhilippe Houdoin
1230832f66cSPhilippe Houdoin		free(fRects);
1240832f66cSPhilippe Houdoin		fRectsCount = info->clip_list_count;
1250832f66cSPhilippe Houdoin		fRects = (clipping_rect *) malloc(fRectsCount * sizeof(clipping_rect));
1260832f66cSPhilippe Houdoin		memcpy(fRects, info->clip_list, fRectsCount * sizeof(clipping_rect));
1270832f66cSPhilippe Houdoin
1280832f66cSPhilippe Houdoin		fprintf(stderr, "fFrameBuffer = %p\n"
1290832f66cSPhilippe Houdoin						"fBytesPerRow = %d\n"
1300832f66cSPhilippe Houdoin						"fColorSpace  = %s\n", fFrameBuffer, fBytesPerRow, color_space_name(fColorSpace));
1310832f66cSPhilippe Houdoin		for (int i = 0; i < fRectsCount; i++) {
1320832f66cSPhilippe Houdoin			fprintf(stderr, "fRects[%d] = %d, %d to %d, %d\n",
1330832f66cSPhilippe Houdoin				i, fRects[i].left, fRects[i].top, fRects[i].right, fRects[i].bottom);
1340832f66cSPhilippe Houdoin		}
1350832f66cSPhilippe Houdoin		break;
1360832f66cSPhilippe Houdoin
1370832f66cSPhilippe Houdoin	case B_DIRECT_STOP:
1380832f66cSPhilippe Houdoin		fConnected = false;
1390832f66cSPhilippe Houdoin		break;
1400832f66cSPhilippe Houdoin	}
1410832f66cSPhilippe Houdoin
1420832f66cSPhilippe Houdoin	fprintf(stderr, "fConnected = %s\n", fConnected ? "true" : "false");
1430832f66cSPhilippe Houdoin}
1440832f66cSPhilippe Houdoin
1450832f66cSPhilippe Houdoin
1460832f66cSPhilippe Houdoin// ----
1470832f66cSPhilippe Houdoin
1480832f66cSPhilippe Houdoin
1490832f66cSPhilippe Houdoinint32
1500832f66cSPhilippe HoudoinFakeRenderer::_DirectDrawThread(void *data)
1510832f66cSPhilippe Houdoin{
1520832f66cSPhilippe Houdoin	FakeRenderer *me = (FakeRenderer *) data;
1530832f66cSPhilippe Houdoin	return me->_DirectDrawThread();
1540832f66cSPhilippe Houdoin}
1550832f66cSPhilippe Houdoin
1560832f66cSPhilippe Houdoin
1570832f66cSPhilippe Houdoinint32
1580832f66cSPhilippe HoudoinFakeRenderer::_DirectDrawThread(void)
1590832f66cSPhilippe Houdoin{
1600832f66cSPhilippe Houdoin	// Let's wait forever/until semaphore death next redraw
1610832f66cSPhilippe Houdoin	while (acquire_sem(fDrawSem) == B_OK) {
1620832f66cSPhilippe Houdoin
1630832f66cSPhilippe Houdoin		BAutolock lock(fDrawLocker);
1640832f66cSPhilippe Houdoin
1650832f66cSPhilippe Houdoin		int i;
1660832f66cSPhilippe Houdoin		int32 x, y;
1670832f66cSPhilippe Houdoin
1680832f66cSPhilippe Houdoin		switch(fColorSpace) {
1690832f66cSPhilippe Houdoin		case B_RGB32:
1700832f66cSPhilippe Houdoin		case B_RGBA32:
1710832f66cSPhilippe Houdoin			for (i = 0; i < fRectsCount; i++) {
1720832f66cSPhilippe Houdoin				for (y = fRects[i].top; y <= fRects[i].bottom; y++) {
1730832f66cSPhilippe Houdoin					uint8 * p = fFrameBuffer + ( y * fBytesPerRow ) + fRects[i].left * 4;
1740832f66cSPhilippe Houdoin					for (x = fRects[i].left; x <= fRects[i].right; x++) {
1750832f66cSPhilippe Houdoin						*p++ = fDrawColor.blue;
1760832f66cSPhilippe Houdoin						*p++ = fDrawColor.green;
1770832f66cSPhilippe Houdoin						*p++ = fDrawColor.red;
1780832f66cSPhilippe Houdoin						*p++ = fDrawColor.alpha;
1790832f66cSPhilippe Houdoin					}
1800832f66cSPhilippe Houdoin				}
1810832f66cSPhilippe Houdoin			}
1820832f66cSPhilippe Houdoin			break;
1830832f66cSPhilippe Houdoin
1840832f66cSPhilippe Houdoin		case B_RGB24:
1850832f66cSPhilippe Houdoin		case B_RGB32_BIG:
1860832f66cSPhilippe Houdoin		case B_RGBA32_BIG:
1870832f66cSPhilippe Houdoin		case B_RGB24_BIG:
1880832f66cSPhilippe Houdoin			/* fill this in with the color-space conversion
1890832f66cSPhilippe Houdoin			 * code of your choosing
1900832f66cSPhilippe Houdoin			 */
1910832f66cSPhilippe Houdoin			break;
1920832f66cSPhilippe Houdoin
1930832f66cSPhilippe Houdoin		case B_RGB16:
1940832f66cSPhilippe Houdoin		case B_RGB15:
1950832f66cSPhilippe Houdoin		case B_RGBA15:
1960832f66cSPhilippe Houdoin		case B_RGB16_BIG:
1970832f66cSPhilippe Houdoin		case B_RGB15_BIG:
1980832f66cSPhilippe Houdoin		case B_RGBA15_BIG:
1990832f66cSPhilippe Houdoin			/* same here */
2000832f66cSPhilippe Houdoin			break;
2010832f66cSPhilippe Houdoin
2020832f66cSPhilippe Houdoin		case B_CMAP8:
2030832f66cSPhilippe Houdoin			/* same here */
2040832f66cSPhilippe Houdoin			break;
2050832f66cSPhilippe Houdoin
2060832f66cSPhilippe Houdoin		default:
2070832f66cSPhilippe Houdoin			/* unsupported mode */
2080832f66cSPhilippe Houdoin			break;
2090832f66cSPhilippe Houdoin		}
2100832f66cSPhilippe Houdoin
2110832f66cSPhilippe Houdoin	} // while draw
2120832f66cSPhilippe Houdoin
2130832f66cSPhilippe Houdoin	return 0;
2140832f66cSPhilippe Houdoin}
2150832f66cSPhilippe Houdoin
2160832f66cSPhilippe Houdoin
2170832f66cSPhilippe Houdoin
218