From 0832f66cc5b61602f7afa85b351b21a0fa84a5c4 Mon Sep 17 00:00:00 2001 From: Philippe Houdoin Date: Tue, 30 Dec 2008 20:17:18 +0000 Subject: [PATCH] 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 --- src/tests/add-ons/Jamfile | 1 + src/tests/add-ons/opengl/Jamfile | 4 + .../opengl/fake_renderer/FakeRenderer.cpp | 217 ++++++++++++++++++ .../opengl/fake_renderer/FakeRenderer.h | 51 ++++ .../add-ons/opengl/fake_renderer/Jamfile | 22 ++ 5 files changed, 295 insertions(+) create mode 100644 src/tests/add-ons/opengl/Jamfile create mode 100644 src/tests/add-ons/opengl/fake_renderer/FakeRenderer.cpp create mode 100644 src/tests/add-ons/opengl/fake_renderer/FakeRenderer.h create mode 100644 src/tests/add-ons/opengl/fake_renderer/Jamfile diff --git a/src/tests/add-ons/Jamfile b/src/tests/add-ons/Jamfile index 793e1bf1dc..88f4f2e273 100644 --- a/src/tests/add-ons/Jamfile +++ b/src/tests/add-ons/Jamfile @@ -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 ; diff --git a/src/tests/add-ons/opengl/Jamfile b/src/tests/add-ons/opengl/Jamfile new file mode 100644 index 0000000000..13ed873b30 --- /dev/null +++ b/src/tests/add-ons/opengl/Jamfile @@ -0,0 +1,4 @@ +SubDir HAIKU_TOP src tests add-ons opengl ; + +SubInclude HAIKU_TOP src tests add-ons opengl fake_renderer ; + diff --git a/src/tests/add-ons/opengl/fake_renderer/FakeRenderer.cpp b/src/tests/add-ons/opengl/fake_renderer/FakeRenderer.cpp new file mode 100644 index 0000000000..462eebad1d --- /dev/null +++ b/src/tests/add-ons/opengl/fake_renderer/FakeRenderer.cpp @@ -0,0 +1,217 @@ +/* + * Copyright 2006-2008, Haiku. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Philippe Houdoin, philippe.houdoin@free.fr + */ +/* + * Mesa 3-D graphics library + * Version: 6.1 + * + * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + */ + +#include "FakeRenderer.h" + +#include + +#include +#include +#include +#include + + +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; +} + + + diff --git a/src/tests/add-ons/opengl/fake_renderer/FakeRenderer.h b/src/tests/add-ons/opengl/fake_renderer/FakeRenderer.h new file mode 100644 index 0000000000..33a91fbf44 --- /dev/null +++ b/src/tests/add-ons/opengl/fake_renderer/FakeRenderer.h @@ -0,0 +1,51 @@ +/* + * Copyright 2006-2008, Haiku. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Philippe Houdoin, philippe.houdoin@free.fr + */ + +#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 + diff --git a/src/tests/add-ons/opengl/fake_renderer/Jamfile b/src/tests/add-ons/opengl/fake_renderer/Jamfile new file mode 100644 index 0000000000..95082b42ef --- /dev/null +++ b/src/tests/add-ons/opengl/fake_renderer/Jamfile @@ -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 +; +