Added a small faking OpenGL renderer add-on as a testbed for direct

mode threading/drawing issue.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28834 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Philippe Houdoin
2008-12-30 20:17:18 +00:00
parent f9116d8c65
commit 0832f66cc5
5 changed files with 295 additions and 0 deletions
+1
View File
@@ -3,5 +3,6 @@ SubDir HAIKU_TOP src tests add-ons ;
SubInclude HAIKU_TOP src tests add-ons input_server ;
SubInclude HAIKU_TOP src tests add-ons kernel ;
SubInclude HAIKU_TOP src tests add-ons media ;
SubInclude HAIKU_TOP src tests add-ons opengl ;
SubInclude HAIKU_TOP src tests add-ons print ;
SubInclude HAIKU_TOP src tests add-ons translators ;
+4
View File
@@ -0,0 +1,4 @@
SubDir HAIKU_TOP src tests add-ons opengl ;
SubInclude HAIKU_TOP src tests add-ons opengl fake_renderer ;
@@ -0,0 +1,217 @@
/*
* Copyright 2006-2008, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Philippe Houdoin, [email protected]
*/
/*
* Mesa 3-D graphics library
* Version: 6.1
*
* Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
*/
#include "FakeRenderer.h"
#include <stdio.h>
#include <Autolock.h>
#include <DirectWindowPrivate.h>
#include <GraphicsDefs.h>
#include <Screen.h>
extern const char * color_space_name(color_space space);
extern "C" _EXPORT BGLRenderer*
instantiate_gl_renderer(BGLView* view, ulong options,
BGLDispatcher* dispatcher)
{
return new FakeRenderer(view, options, dispatcher);
}
FakeRenderer::FakeRenderer(BGLView* view, ulong options,
BGLDispatcher* dispatcher)
: BGLRenderer(view, options, dispatcher),
fOptions(options),
fDrawLocker("direct draw locker"),
fFrameBuffer(NULL),
fColorSpace(B_NO_COLOR_SPACE),
fRects(NULL),
fConnected(false),
fDisabled(false)
{
fDrawSem = create_sem(0, "FakeRenderer draw");
fDrawThread = spawn_thread(_DirectDrawThread, "FakeRenderer direct draw", B_DISPLAY_PRIORITY, this);
resume_thread(fDrawThread);
}
FakeRenderer::~FakeRenderer()
{
// Wakeup the draw thread by murdering its favorite semaphore
delete_sem(fDrawSem);
status_t exit_value;
wait_for_thread(fDrawThread, &exit_value);
free(fRects);
}
void
FakeRenderer::SwapBuffers(bool VSync)
{
if (VSync && GLView()->Window()) {
// TODO: find a way to check VSync support is actually working...
BScreen screen(GLView()->Window());
screen.WaitForRetrace();
}
// Simulate rendering a new buffer: randomized buffer color ;-)
fDrawColor = make_color(rand() % 0xFF, rand() % 0xFF, rand() % 0xFF);
if (!fConnected || fDisabled) {
GLView()->LockLooper();
// TODO : refresh area
GLView()->UnlockLooper();
return;
}
// Direct mode: wake up drawing thread
release_sem(fDrawSem);
}
void
FakeRenderer::Draw(BRect updateRect)
{
/*
if (fBitmap && (!fDirectModeEnabled || (fInfo == NULL)))
GLView()->DrawBitmap(fBitmap, updateRect, updateRect);
*/
}
void
FakeRenderer::EnableDirectMode(bool enabled)
{
fDisabled = ! enabled;
}
void
FakeRenderer::DirectConnected(direct_buffer_info *info)
{
if (!fConnected && fDisabled)
return;
BAutolock lock(fDrawLocker);
switch (info->buffer_state & B_DIRECT_MODE_MASK) {
case B_DIRECT_START:
fConnected = true;
/* fall through */
case B_DIRECT_MODIFY:
fFrameBuffer = (uint8 *) info->bits;
fBytesPerRow = info->bytes_per_row;
fColorSpace = info->pixel_format;
free(fRects);
fRectsCount = info->clip_list_count;
fRects = (clipping_rect *) malloc(fRectsCount * sizeof(clipping_rect));
memcpy(fRects, info->clip_list, fRectsCount * sizeof(clipping_rect));
fprintf(stderr, "fFrameBuffer = %p\n"
"fBytesPerRow = %d\n"
"fColorSpace = %s\n", fFrameBuffer, fBytesPerRow, color_space_name(fColorSpace));
for (int i = 0; i < fRectsCount; i++) {
fprintf(stderr, "fRects[%d] = %d, %d to %d, %d\n",
i, fRects[i].left, fRects[i].top, fRects[i].right, fRects[i].bottom);
}
break;
case B_DIRECT_STOP:
fConnected = false;
break;
}
fprintf(stderr, "fConnected = %s\n", fConnected ? "true" : "false");
}
// ----
int32
FakeRenderer::_DirectDrawThread(void *data)
{
FakeRenderer *me = (FakeRenderer *) data;
return me->_DirectDrawThread();
}
int32
FakeRenderer::_DirectDrawThread(void)
{
// Let's wait forever/until semaphore death next redraw
while (acquire_sem(fDrawSem) == B_OK) {
BAutolock lock(fDrawLocker);
int i;
int32 x, y;
switch(fColorSpace) {
case B_RGB32:
case B_RGBA32:
for (i = 0; i < fRectsCount; i++) {
for (y = fRects[i].top; y <= fRects[i].bottom; y++) {
uint8 * p = fFrameBuffer + ( y * fBytesPerRow ) + fRects[i].left * 4;
for (x = fRects[i].left; x <= fRects[i].right; x++) {
*p++ = fDrawColor.blue;
*p++ = fDrawColor.green;
*p++ = fDrawColor.red;
*p++ = fDrawColor.alpha;
}
}
}
break;
case B_RGB24:
case B_RGB32_BIG:
case B_RGBA32_BIG:
case B_RGB24_BIG:
/* fill this in with the color-space conversion
* code of your choosing
*/
break;
case B_RGB16:
case B_RGB15:
case B_RGBA15:
case B_RGB16_BIG:
case B_RGB15_BIG:
case B_RGBA15_BIG:
/* same here */
break;
case B_CMAP8:
/* same here */
break;
default:
/* unsupported mode */
break;
}
} // while draw
return 0;
}
@@ -0,0 +1,51 @@
/*
* Copyright 2006-2008, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Philippe Houdoin, [email protected]
*/
#ifndef FAKERENDERER_H
#define FAKERERENDERER_H
#include "GLRenderer.h"
class FakeRenderer : public BGLRenderer {
public:
FakeRenderer(BGLView* view,
ulong bgl_options,
BGLDispatcher* dispatcher);
virtual ~FakeRenderer();
virtual void SwapBuffers(bool VSync = false);
virtual void Draw(BRect updateRect);
virtual void EnableDirectMode(bool enabled);
virtual void DirectConnected(direct_buffer_info* info);
private:
static int32 _DirectDrawThread(void *data);
int32 _DirectDrawThread();
ulong fOptions;
sem_id fDrawSem;
thread_id fDrawThread;
BLocker fDrawLocker;
rgb_color fDrawColor;
uint8 * fFrameBuffer;
int32 fBytesPerRow;
color_space fColorSpace;
clipping_rect fBounds;
clipping_rect * fRects;
int fRectsCount;
bool fConnected;
bool fDisabled;
};
#endif // FAKERENDERER_H
@@ -0,0 +1,22 @@
SubDir HAIKU_TOP src tests add-ons opengl fake_renderer ;
SetSubDirSupportedPlatformsBeOSCompatible ;
if $(TARGET_PLATFORM) != haiku {
UseHeaders [ FDirName $(HAIKU_TOP) headers os opengl ] : true ;
# We need our public GL headers also when not compiling for Haiku.
}
UsePrivateHeaders interface opengl ;
Addon fake_renderer :
FakeRenderer.cpp
: libGL.so be
;
Package haiku-opengl-cvs :
fake_renderer :
boot home config add-ons opengl
;