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:
@@ -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 input_server ;
|
||||||
SubInclude HAIKU_TOP src tests add-ons kernel ;
|
SubInclude HAIKU_TOP src tests add-ons kernel ;
|
||||||
SubInclude HAIKU_TOP src tests add-ons media ;
|
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 print ;
|
||||||
SubInclude HAIKU_TOP src tests add-ons translators ;
|
SubInclude HAIKU_TOP src tests add-ons translators ;
|
||||||
|
|||||||
@@ -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
|
||||||
|
;
|
||||||
|
|
||||||
Reference in New Issue
Block a user