From c9f1217e1f2c309cfd8770940773f1f35582a795 Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Tue, 1 Oct 2013 21:03:48 +0000 Subject: haiku: Build Haiku's libGL from within Mesa * This in essence means that Mesa would be taking control of Haiku's OpenGL kit. * This works by dispatching renderers from the OpenGL add-ons directory --- src/gallium/SConscript | 1 + src/gallium/targets/libgl-haiku/GLDispatcher.cpp | 72 +++ src/gallium/targets/libgl-haiku/GLDispatcher.h | 109 ++++ src/gallium/targets/libgl-haiku/GLRenderer.cpp | 106 ++++ .../targets/libgl-haiku/GLRendererRoster.cpp | 226 ++++++++ src/gallium/targets/libgl-haiku/GLRendererRoster.h | 51 ++ src/gallium/targets/libgl-haiku/GLView.cpp | 643 +++++++++++++++++++++ src/gallium/targets/libgl-haiku/SConscript | 34 ++ 8 files changed, 1242 insertions(+) create mode 100644 src/gallium/targets/libgl-haiku/GLDispatcher.cpp create mode 100644 src/gallium/targets/libgl-haiku/GLDispatcher.h create mode 100644 src/gallium/targets/libgl-haiku/GLRenderer.cpp create mode 100644 src/gallium/targets/libgl-haiku/GLRendererRoster.cpp create mode 100644 src/gallium/targets/libgl-haiku/GLRendererRoster.h create mode 100644 src/gallium/targets/libgl-haiku/GLView.cpp create mode 100644 src/gallium/targets/libgl-haiku/SConscript (limited to 'src/gallium') diff --git a/src/gallium/SConscript b/src/gallium/SConscript index ca75f37f9d9..9a25ccafb10 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -122,6 +122,7 @@ if not env['embedded']: if env['platform'] == 'haiku': SConscript([ 'targets/haiku-softpipe/SConscript', + 'targets/libgl-haiku/SConscript', ]) if env['dri']: diff --git a/src/gallium/targets/libgl-haiku/GLDispatcher.cpp b/src/gallium/targets/libgl-haiku/GLDispatcher.cpp new file mode 100644 index 00000000000..46b91d57c49 --- /dev/null +++ b/src/gallium/targets/libgl-haiku/GLDispatcher.cpp @@ -0,0 +1,72 @@ +/* + * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000-2012 Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Brian Paul + * Philippe Houdoin + * Alexander von Gluck IV + */ + + +extern "C" { +#include "glapi/glapi.h" +#include "glapi/glapi_priv.h" + +/* + * NOTE: this file portion implements C-based dispatch of the OpenGL entrypoints + * (glAccum, glBegin, etc). + * This code IS NOT USED if we're compiling on an x86 system and using + * the glapi_x86.S assembly code. + */ +#if !(defined(USE_X86_ASM) || defined(USE_SPARC_ASM)) + +#define KEYWORD1 PUBLIC +#define KEYWORD2 +#define NAME(func) gl##func + +#define DISPATCH(func, args, msg) \ + const struct _glapi_table* dispatch; \ + dispatch = _glapi_Dispatch ? _glapi_Dispatch : _glapi_get_dispatch();\ + (dispatch->func) args + +#define RETURN_DISPATCH(func, args, msg) \ + const struct _glapi_table* dispatch; \ + dispatch = _glapi_Dispatch ? _glapi_Dispatch : _glapi_get_dispatch();\ + return (dispatch->func) args + +#endif +} + + +/* NOTE: this file portion implement a thin OpenGL entrypoints dispatching + C++ wrapper class + */ + +#include "GLDispatcher.h" + +BGLDispatcher::BGLDispatcher() +{ +} + + +BGLDispatcher::~BGLDispatcher() +{ +} + + +status_t +BGLDispatcher::CheckTable(const struct _glapi_table* table) +{ + _glapi_check_table(table ? table : _glapi_get_dispatch()); + return B_OK; +} + + +status_t +BGLDispatcher::SetTable(struct _glapi_table* table) +{ + _glapi_set_dispatch(table); + return B_OK; +} diff --git a/src/gallium/targets/libgl-haiku/GLDispatcher.h b/src/gallium/targets/libgl-haiku/GLDispatcher.h new file mode 100644 index 00000000000..44bca8ce586 --- /dev/null +++ b/src/gallium/targets/libgl-haiku/GLDispatcher.h @@ -0,0 +1,109 @@ +/* + * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000-2012 Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Brian Paul + * Philippe Houdoin + */ +#ifndef GLDISPATCHER_H +#define GLDISPATCHER_H + + +#include +#include +#include + +#include "glheader.h" + +extern "C" { +#include "glapi/glapi.h" +} + + +class BGLDispatcher +{ + // Private unimplemented copy constructors + BGLDispatcher(const BGLDispatcher &); + BGLDispatcher & operator=(const BGLDispatcher &); + + public: + BGLDispatcher(); + ~BGLDispatcher(); + + void SetCurrentContext(void* context); + void* CurrentContext(); + + struct _glapi_table* Table(); + status_t CheckTable( + const struct _glapi_table* dispatch = NULL); + status_t SetTable(struct _glapi_table* dispatch); + uint32 TableSize(); + + const _glapi_proc operator[](const char* functionName); + const char* operator[](uint32 offset); + + const _glapi_proc AddressOf(const char* functionName); + uint32 OffsetOf(const char* functionName); +}; + + +// Inlines methods +inline void +BGLDispatcher::SetCurrentContext(void* context) +{ + _glapi_set_context(context); +} + + +inline void* +BGLDispatcher::CurrentContext() +{ + return _glapi_get_context(); +} + + +inline struct _glapi_table* +BGLDispatcher::Table() +{ + return _glapi_get_dispatch(); +} + + +inline uint32 +BGLDispatcher::TableSize() +{ + return _glapi_get_dispatch_table_size(); +} + + +inline const _glapi_proc +BGLDispatcher::operator[](const char* functionName) +{ + return _glapi_get_proc_address(functionName); +} + + +inline const char* +BGLDispatcher::operator[](uint32 offset) +{ + return _glapi_get_proc_name((GLuint) offset); +} + + +inline const _glapi_proc +BGLDispatcher::AddressOf(const char* functionName) +{ + return _glapi_get_proc_address(functionName); +} + + +inline uint32 +BGLDispatcher::OffsetOf(const char* functionName) +{ + return (uint32) _glapi_get_proc_offset(functionName); +} + + +#endif // GLDISPATCHER_H diff --git a/src/gallium/targets/libgl-haiku/GLRenderer.cpp b/src/gallium/targets/libgl-haiku/GLRenderer.cpp new file mode 100644 index 00000000000..4573a64a35c --- /dev/null +++ b/src/gallium/targets/libgl-haiku/GLRenderer.cpp @@ -0,0 +1,106 @@ +/* + * Copyright 2006-2008, Philippe Houdoin. All rights reserved. + * Distributed under the terms of the MIT License. + */ + + +#include + +#include "GLRenderer.h" + +#include "GLDispatcher.h" + + +BGLRenderer::BGLRenderer(BGLView* view, ulong glOptions, + BGLDispatcher* dispatcher) + : + fRefCount(1), + fView(view), + fOptions(glOptions), + fDispatcher(dispatcher) +{ +} + + +BGLRenderer::~BGLRenderer() +{ + delete fDispatcher; +} + + +void +BGLRenderer::Acquire() +{ + atomic_add(&fRefCount, 1); +} + + +void +BGLRenderer::Release() +{ + if (atomic_add(&fRefCount, -1) < 1) + delete this; +} + + +void +BGLRenderer::LockGL() +{ +} + + +void +BGLRenderer::UnlockGL() +{ +} + + +void +BGLRenderer::SwapBuffers(bool VSync) +{ +} + + +void +BGLRenderer::Draw(BRect updateRect) +{ +} + + +status_t +BGLRenderer::CopyPixelsOut(BPoint source, BBitmap* dest) +{ + return B_ERROR; +} + + +status_t +BGLRenderer::CopyPixelsIn(BBitmap* source, BPoint dest) +{ + return B_ERROR; +} + + +void +BGLRenderer::FrameResized(float width, float height) +{ +} + + +void +BGLRenderer::DirectConnected(direct_buffer_info* info) +{ +} + + +void +BGLRenderer::EnableDirectMode(bool enabled) +{ +} + + +status_t BGLRenderer::_Reserved_Renderer_0(int32 n, void* p) { return B_ERROR; } +status_t BGLRenderer::_Reserved_Renderer_1(int32 n, void* p) { return B_ERROR; } +status_t BGLRenderer::_Reserved_Renderer_2(int32 n, void* p) { return B_ERROR; } +status_t BGLRenderer::_Reserved_Renderer_3(int32 n, void* p) { return B_ERROR; } +status_t BGLRenderer::_Reserved_Renderer_4(int32 n, void* p) { return B_ERROR; } diff --git a/src/gallium/targets/libgl-haiku/GLRendererRoster.cpp b/src/gallium/targets/libgl-haiku/GLRendererRoster.cpp new file mode 100644 index 00000000000..70bc4129974 --- /dev/null +++ b/src/gallium/targets/libgl-haiku/GLRendererRoster.cpp @@ -0,0 +1,226 @@ +/* + * Copyright 2006-2012 Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Philippe Houdoin + * Alexander von Gluck IV + */ + + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include "GLDispatcher.h" +#include "GLRendererRoster.h" + +#include +#include + + +extern "C" status_t _kern_get_safemode_option(const char* parameter, + char* buffer, size_t* _bufferSize); + + +GLRendererRoster::GLRendererRoster(BGLView* view, ulong options) + : + fNextID(0), + fView(view), + fOptions(options), + fSafeMode(false), + fABISubDirectory(NULL) +{ + char parameter[32]; + size_t parameterLength = sizeof(parameter); + + if (_kern_get_safemode_option(B_SAFEMODE_SAFE_MODE, + parameter, ¶meterLength) == B_OK) { + if (!strcasecmp(parameter, "enabled") || !strcasecmp(parameter, "on") + || !strcasecmp(parameter, "true") || !strcasecmp(parameter, "yes") + || !strcasecmp(parameter, "enable") || !strcmp(parameter, "1")) + fSafeMode = true; + } + + if (_kern_get_safemode_option(B_SAFEMODE_DISABLE_USER_ADD_ONS, + parameter, ¶meterLength) == B_OK) { + if (!strcasecmp(parameter, "enabled") || !strcasecmp(parameter, "on") + || !strcasecmp(parameter, "true") || !strcasecmp(parameter, "yes") + || !strcasecmp(parameter, "enable") || !strcmp(parameter, "1")) + fSafeMode = true; + } + + // We might run in compatibility mode on a system with a different ABI. The + // renderers matching our ABI can usually be found in respective + // subdirectories of the opengl add-ons directories. + system_info info; + if (get_system_info(&info) == B_OK + && (info.abi & B_HAIKU_ABI_MAJOR) + != (B_HAIKU_ABI & B_HAIKU_ABI_MAJOR)) { + switch (B_HAIKU_ABI & B_HAIKU_ABI_MAJOR) { + case B_HAIKU_ABI_GCC_2: + fABISubDirectory = "gcc2"; + break; + case B_HAIKU_ABI_GCC_4: + fABISubDirectory = "gcc4"; + break; + } + } + + AddDefaultPaths(); +} + + +GLRendererRoster::~GLRendererRoster() +{ + +} + + +BGLRenderer* +GLRendererRoster::GetRenderer(int32 id) +{ + RendererMap::const_iterator iterator = fRenderers.find(id); + if (iterator == fRenderers.end()) + return NULL; + + struct renderer_item item = iterator->second; + return item.renderer; +} + + +void +GLRendererRoster::AddDefaultPaths() +{ + // add user directories first, so that they can override system renderers + const directory_which paths[] = { + B_USER_NONPACKAGED_ADDONS_DIRECTORY, + B_USER_ADDONS_DIRECTORY, + B_COMMON_NONPACKAGED_ADDONS_DIRECTORY, + B_COMMON_ADDONS_DIRECTORY, + B_SYSTEM_ADDONS_DIRECTORY, + }; + + for (uint32 i = fSafeMode ? 4 : 0; + i < sizeof(paths) / sizeof(paths[0]); i++) { + BPath path; + status_t status = find_directory(paths[i], &path, true); + if (status == B_OK && path.Append("opengl") == B_OK) + AddPath(path.Path()); + } +} + + +status_t +GLRendererRoster::AddPath(const char* path) +{ + BDirectory directory(path); + status_t status = directory.InitCheck(); + if (status < B_OK) + return status; + + // if a subdirectory for our ABI exists, use that instead + if (fABISubDirectory != NULL) { + BEntry entry(&directory, fABISubDirectory); + if (entry.IsDirectory()) { + status = directory.SetTo(&entry); + if (status != B_OK) + return status; + } + } + + node_ref nodeRef; + status = directory.GetNodeRef(&nodeRef); + if (status < B_OK) + return status; + + int32 count = 0; + int32 files = 0; + + entry_ref ref; + BEntry entry; + while (directory.GetNextRef(&ref) == B_OK) { + entry.SetTo(&ref); + if (entry.InitCheck() == B_OK && !entry.IsFile()) + continue; + + if (CreateRenderer(ref) == B_OK) + count++; + + files++; + } + + if (files != 0 && count == 0) + return B_BAD_VALUE; + + return B_OK; +} + + +status_t +GLRendererRoster::AddRenderer(BGLRenderer* renderer, + image_id image, const entry_ref* ref, ino_t node) +{ + renderer_item item; + item.renderer = renderer; + item.image = image; + item.node = node; + if (ref != NULL) + item.ref = *ref; + + try { + fRenderers[fNextID] = item; + } catch (...) { + return B_NO_MEMORY; + } + + renderer->fOwningRoster = this; + renderer->fID = fNextID++; + return B_OK; +} + + +status_t +GLRendererRoster::CreateRenderer(const entry_ref& ref) +{ + BEntry entry(&ref); + node_ref nodeRef; + status_t status = entry.GetNodeRef(&nodeRef); + if (status < B_OK) + return status; + + BPath path(&ref); + image_id image = load_add_on(path.Path()); + if (image < B_OK) + return image; + + BGLRenderer* (*instantiate_renderer) + (BGLView* view, ulong options, BGLDispatcher* dispatcher); + + status = get_image_symbol(image, "instantiate_gl_renderer", + B_SYMBOL_TYPE_TEXT, (void**)&instantiate_renderer); + if (status == B_OK) { + BGLRenderer* renderer + = instantiate_renderer(fView, fOptions, new BGLDispatcher()); + if (!renderer) { + unload_add_on(image); + return B_UNSUPPORTED; + } + + if (AddRenderer(renderer, image, &ref, nodeRef.node) != B_OK) { + renderer->Release(); + // this will delete the renderer + unload_add_on(image); + } + return B_OK; + } + unload_add_on(image); + + return status; +} diff --git a/src/gallium/targets/libgl-haiku/GLRendererRoster.h b/src/gallium/targets/libgl-haiku/GLRendererRoster.h new file mode 100644 index 00000000000..5c8da271198 --- /dev/null +++ b/src/gallium/targets/libgl-haiku/GLRendererRoster.h @@ -0,0 +1,51 @@ +/* + * Copyright 2006-2012, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Philippe Houdoin + */ +#ifndef _GLRENDERER_ROSTER_H +#define _GLRENDERER_ROSTER_H + + +#include + +#include + + +struct renderer_item { + BGLRenderer* renderer; + entry_ref ref; + ino_t node; + image_id image; +}; + +typedef std::map RendererMap; + + +class GLRendererRoster { + public: + GLRendererRoster(BGLView* view, ulong options); + virtual ~GLRendererRoster(); + + BGLRenderer* GetRenderer(int32 id = 0); + + private: + void AddDefaultPaths(); + status_t AddPath(const char* path); + status_t AddRenderer(BGLRenderer* renderer, + image_id image, const entry_ref* ref, ino_t node); + status_t CreateRenderer(const entry_ref& ref); + + RendererMap fRenderers; + int32 fNextID; + BGLView* fView; + ulong fOptions; + bool fSafeMode; + const char* fABISubDirectory; + +}; + + +#endif /* _GLRENDERER_ROSTER_H */ diff --git a/src/gallium/targets/libgl-haiku/GLView.cpp b/src/gallium/targets/libgl-haiku/GLView.cpp new file mode 100644 index 00000000000..9ae5b5c83ac --- /dev/null +++ b/src/gallium/targets/libgl-haiku/GLView.cpp @@ -0,0 +1,643 @@ +/* + * Copyright 2006-2012, Haiku. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Jérôme Duval, korli@users.berlios.de + * Philippe Houdoin, philippe.houdoin@free.fr + * Stefano Ceccherini, burton666@libero.it + */ + +#include + +#include + +#include +#include +#include +#include + +#include +#include + +#include "interface/DirectWindowPrivate.h" +#include "GLDispatcher.h" +#include "GLRendererRoster.h" + + +struct glview_direct_info { + direct_buffer_info* direct_info; + bool direct_connected; + bool enable_direct_mode; + + glview_direct_info(); + ~glview_direct_info(); +}; + + +BGLView::BGLView(BRect rect, const char* name, ulong resizingMode, ulong mode, + ulong options) + : + BView(rect, name, B_FOLLOW_ALL_SIDES, mode | B_WILL_DRAW | B_FRAME_EVENTS), + // | B_FULL_UPDATE_ON_RESIZE) + fGc(NULL), + fOptions(options), + fDitherCount(0), + fDrawLock("BGLView draw lock"), + fDisplayLock("BGLView display lock"), + fClipInfo(NULL), + fRenderer(NULL), + fRoster(NULL), + fDitherMap(NULL) +{ + fRoster = new GLRendererRoster(this, options); +} + + +BGLView::~BGLView() +{ + delete fClipInfo; + if (fRenderer) + fRenderer->Release(); +} + + +void +BGLView::LockGL() +{ + // TODO: acquire the OpenGL API lock it on this glview + + fDisplayLock.Lock(); + if (fRenderer) + fRenderer->LockGL(); +} + + +void +BGLView::UnlockGL() +{ + if (fRenderer) + fRenderer->UnlockGL(); + fDisplayLock.Unlock(); + + // TODO: release the GL API lock to others glviews +} + + +void +BGLView::SwapBuffers() +{ + SwapBuffers(false); +} + + +void +BGLView::SwapBuffers(bool vSync) +{ + if (fRenderer) { + _LockDraw(); + fRenderer->SwapBuffers(vSync); + _UnlockDraw(); + } +} + + +BView* +BGLView::EmbeddedView() +{ + return NULL; +} + + +void* +BGLView::GetGLProcAddress(const char* procName) +{ + BGLDispatcher* glDispatcher = NULL; + + if (fRenderer) + glDispatcher = fRenderer->GLDispatcher(); + + if (glDispatcher) + return (void*)glDispatcher->AddressOf(procName); + + return NULL; +} + + +status_t +BGLView::CopyPixelsOut(BPoint source, BBitmap* dest) +{ + if (!fRenderer) + return B_ERROR; + + if (!dest || !dest->Bounds().IsValid()) + return B_BAD_VALUE; + + return fRenderer->CopyPixelsOut(source, dest); +} + + +status_t +BGLView::CopyPixelsIn(BBitmap* source, BPoint dest) +{ + if (!fRenderer) + return B_ERROR; + + if (!source || !source->Bounds().IsValid()) + return B_BAD_VALUE; + + return fRenderer->CopyPixelsIn(source, dest); +} + + +/*! Mesa's GLenum is not ulong but uint, so we can't use GLenum + without breaking this method signature. + Instead, we have to use the effective BeOS's SGI OpenGL GLenum type: + unsigned long. + */ +void +BGLView::ErrorCallback(unsigned long errorCode) +{ + char msg[32]; + sprintf(msg, "GL: Error code $%04lx.", errorCode); + // TODO: under BeOS R5, it call debugger(msg); + fprintf(stderr, "%s\n", msg); +} + + +void +BGLView::Draw(BRect updateRect) +{ + if (fRenderer) { + _LockDraw(); + fRenderer->Draw(updateRect); + _UnlockDraw(); + return; + } + // TODO: auto-size and center the string + MovePenTo(8, 32); + DrawString("No OpenGL renderer available!"); +} + + +void +BGLView::AttachedToWindow() +{ + BView::AttachedToWindow(); + + fBounds = Bounds(); + for (BView* view = this; view != NULL; view = view->Parent()) + view->ConvertToParent(&fBounds); + + fRenderer = fRoster->GetRenderer(); + if (fRenderer != NULL) { + // Jackburton: The following code was commented because it doesn't look + // good in "direct" mode: + // when the window is moved, the app_server doesn't paint the view's + // background, and the stuff behind the window itself shows up. + // Setting the view color to black, instead, looks a bit more elegant. +#if 0 + // Don't paint white window background when resized + SetViewColor(B_TRANSPARENT_32_BIT); +#else + SetViewColor(0, 0, 0); +#endif + + // Set default OpenGL viewport: + LockGL(); + glViewport(0, 0, Bounds().IntegerWidth(), Bounds().IntegerHeight()); + UnlockGL(); + fRenderer->FrameResized(Bounds().IntegerWidth(), + Bounds().IntegerHeight()); + + if (fClipInfo) { + fRenderer->DirectConnected(fClipInfo->direct_info); + fRenderer->EnableDirectMode(fClipInfo->enable_direct_mode); + } + + return; + } + + fprintf(stderr, "no renderer found! \n"); + + // No Renderer, no rendering. Setup a minimal "No Renderer" string drawing + // context + SetFont(be_bold_font); + // SetFontSize(16); +} + + +void +BGLView::AllAttached() +{ + BView::AllAttached(); +} + + +void +BGLView::DetachedFromWindow() +{ + if (fRenderer) + fRenderer->Release(); + fRenderer = NULL; + + BView::DetachedFromWindow(); +} + + +void +BGLView::AllDetached() +{ + BView::AllDetached(); +} + + +void +BGLView::FrameResized(float width, float height) +{ + fBounds = Bounds(); + for (BView* v = this; v; v = v->Parent()) + v->ConvertToParent(&fBounds); + + if (fRenderer) { + LockGL(); + _LockDraw(); + _CallDirectConnected(); + fRenderer->FrameResized(width, height); + _UnlockDraw(); + UnlockGL(); + } + + BView::FrameResized(width, height); +} + + +status_t +BGLView::Perform(perform_code d, void* arg) +{ + return BView::Perform(d, arg); +} + + +status_t +BGLView::Archive(BMessage* data, bool deep) const +{ + return BView::Archive(data, deep); +} + + +void +BGLView::MessageReceived(BMessage* msg) +{ + BView::MessageReceived(msg); +} + + +void +BGLView::SetResizingMode(uint32 mode) +{ + BView::SetResizingMode(mode); +} + + +void +BGLView::GetPreferredSize(float* _width, float* _height) +{ + if (_width) + *_width = 0; + if (_height) + *_height = 0; +} + + +void +BGLView::Show() +{ + BView::Show(); +} + + +void +BGLView::Hide() +{ + BView::Hide(); +} + + +BHandler* +BGLView::ResolveSpecifier(BMessage* msg, int32 index, BMessage* specifier, + int32 form, const char* property) +{ + return BView::ResolveSpecifier(msg, index, specifier, form, property); +} + + +status_t +BGLView::GetSupportedSuites(BMessage* data) +{ + return BView::GetSupportedSuites(data); +} + + +void +BGLView::DirectConnected(direct_buffer_info* info) +{ + if (fClipInfo == NULL) { + fClipInfo = new (std::nothrow) glview_direct_info(); + if (fClipInfo == NULL) + return; + } + + direct_buffer_info* localInfo = fClipInfo->direct_info; + + switch (info->buffer_state & B_DIRECT_MODE_MASK) { + case B_DIRECT_START: + fClipInfo->direct_connected = true; + memcpy(localInfo, info, DIRECT_BUFFER_INFO_AREA_SIZE); + _UnlockDraw(); + break; + + case B_DIRECT_MODIFY: + _LockDraw(); + memcpy(localInfo, info, DIRECT_BUFFER_INFO_AREA_SIZE); + _UnlockDraw(); + break; + + case B_DIRECT_STOP: + fClipInfo->direct_connected = false; + _LockDraw(); + break; + } + + if (fRenderer) + _CallDirectConnected(); +} + + +void +BGLView::EnableDirectMode(bool enabled) +{ + if (fRenderer) + fRenderer->EnableDirectMode(enabled); + if (fClipInfo == NULL) { + fClipInfo = new (std::nothrow) glview_direct_info(); + if (fClipInfo == NULL) + return; + } + + fClipInfo->enable_direct_mode = enabled; +} + + +void +BGLView::_LockDraw() +{ + if (!fClipInfo || !fClipInfo->enable_direct_mode) + return; + + fDrawLock.Lock(); +} + + +void +BGLView::_UnlockDraw() +{ + if (!fClipInfo || !fClipInfo->enable_direct_mode) + return; + + fDrawLock.Unlock(); +} + + +void +BGLView::_CallDirectConnected() +{ + if (!fClipInfo) + return; + + direct_buffer_info* localInfo = fClipInfo->direct_info; + direct_buffer_info* info = (direct_buffer_info*)malloc( + DIRECT_BUFFER_INFO_AREA_SIZE); + if (info == NULL) + return; + + memcpy(info, localInfo, DIRECT_BUFFER_INFO_AREA_SIZE); + + // Collect the rects into a BRegion, then clip to the view's bounds + BRegion region; + for (uint32 c = 0; c < localInfo->clip_list_count; c++) + region.Include(localInfo->clip_list[c]); + BRegion boundsRegion = fBounds.OffsetByCopy(localInfo->window_bounds.left, + localInfo->window_bounds.top); + info->window_bounds = boundsRegion.RectAtInt(0); + // window_bounds are now view bounds + region.IntersectWith(&boundsRegion); + + info->clip_list_count = region.CountRects(); + info->clip_bounds = region.FrameInt(); + + for (uint32 c = 0; c < info->clip_list_count; c++) + info->clip_list[c] = region.RectAtInt(c); + fRenderer->DirectConnected(info); + free(info); +} + + +//---- virtual reserved methods ---------- + + +void BGLView::_ReservedGLView1() {} +void BGLView::_ReservedGLView2() {} +void BGLView::_ReservedGLView3() {} +void BGLView::_ReservedGLView4() {} +void BGLView::_ReservedGLView5() {} +void BGLView::_ReservedGLView6() {} +void BGLView::_ReservedGLView7() {} +void BGLView::_ReservedGLView8() {} + + +// #pragma mark - + + +// BeOS compatibility: contrary to others BView's contructors, +// BGLView one wants a non-const name argument. +BGLView::BGLView(BRect rect, char* name, ulong resizingMode, ulong mode, + ulong options) + : + BView(rect, name, B_FOLLOW_ALL_SIDES, mode | B_WILL_DRAW | B_FRAME_EVENTS), + fGc(NULL), + fOptions(options), + fDitherCount(0), + fDrawLock("BGLView draw lock"), + fDisplayLock("BGLView display lock"), + fClipInfo(NULL), + fRenderer(NULL), + fRoster(NULL), + fDitherMap(NULL) +{ + fRoster = new GLRendererRoster(this, options); +} + + +#if 0 +// TODO: implement BGLScreen class... + + +BGLScreen::BGLScreen(char* name, ulong screenMode, ulong options, + status_t* error, bool debug) + : + BWindowScreen(name, screenMode, error, debug) +{ +} + + +BGLScreen::~BGLScreen() +{ +} + + +void +BGLScreen::LockGL() +{ +} + + +void +BGLScreen::UnlockGL() +{ +} + + +void +BGLScreen::SwapBuffers() +{ +} + + +void +BGLScreen::ErrorCallback(unsigned long errorCode) +{ + // Mesa's GLenum is not ulong but uint! + char msg[32]; + sprintf(msg, "GL: Error code $%04lx.", errorCode); + // debugger(msg); + fprintf(stderr, "%s\n", msg); + return; +} + + +void +BGLScreen::ScreenConnected(bool enabled) +{ +} + + +void +BGLScreen::FrameResized(float width, float height) +{ + return BWindowScreen::FrameResized(width, height); +} + + +status_t +BGLScreen::Perform(perform_code d, void* arg) +{ + return BWindowScreen::Perform(d, arg); +} + + +status_t +BGLScreen::Archive(BMessage* data, bool deep) const +{ + return BWindowScreen::Archive(data, deep); +} + + +void +BGLScreen::MessageReceived(BMessage* msg) +{ + BWindowScreen::MessageReceived(msg); +} + + +void +BGLScreen::Show() +{ + BWindowScreen::Show(); +} + + +void +BGLScreen::Hide() +{ + BWindowScreen::Hide(); +} + + +BHandler* +BGLScreen::ResolveSpecifier(BMessage* msg, int32 index, BMessage* specifier, + int32 form, const char* property) +{ + return BWindowScreen::ResolveSpecifier(msg, index, specifier, + form, property); +} + + +status_t +BGLScreen::GetSupportedSuites(BMessage* data) +{ + return BWindowScreen::GetSupportedSuites(data); +} + + +//---- virtual reserved methods ---------- + +void BGLScreen::_ReservedGLScreen1() {} +void BGLScreen::_ReservedGLScreen2() {} +void BGLScreen::_ReservedGLScreen3() {} +void BGLScreen::_ReservedGLScreen4() {} +void BGLScreen::_ReservedGLScreen5() {} +void BGLScreen::_ReservedGLScreen6() {} +void BGLScreen::_ReservedGLScreen7() {} +void BGLScreen::_ReservedGLScreen8() {} +#endif + + +const char* color_space_name(color_space space) +{ +#define C2N(a) case a: return #a + + switch (space) { + C2N(B_RGB24); + C2N(B_RGB32); + C2N(B_RGBA32); + C2N(B_RGB32_BIG); + C2N(B_RGBA32_BIG); + C2N(B_GRAY8); + C2N(B_GRAY1); + C2N(B_RGB16); + C2N(B_RGB15); + C2N(B_RGBA15); + C2N(B_CMAP8); + default: + return "Unknown!"; + }; + +#undef C2N +}; + + +glview_direct_info::glview_direct_info() +{ + // TODO: See direct_window_data() in app_server's ServerWindow.cpp + direct_info = (direct_buffer_info*)calloc(1, DIRECT_BUFFER_INFO_AREA_SIZE); + direct_connected = false; + enable_direct_mode = false; +} + + +glview_direct_info::~glview_direct_info() +{ + free(direct_info); +} + diff --git a/src/gallium/targets/libgl-haiku/SConscript b/src/gallium/targets/libgl-haiku/SConscript new file mode 100644 index 00000000000..2e6b62824a3 --- /dev/null +++ b/src/gallium/targets/libgl-haiku/SConscript @@ -0,0 +1,34 @@ +####################################################################### +# SConscript for Haiku OpenGL kit + +Import('*') + +env = env.Clone() + +env.Append(CPPPATH = [ + '#/src/mapi', + '#/src/mesa', + '#/src/mesa/main', + '/boot/system/develop/headers/private', + Dir('../../../mapi'), # src/mapi build path for python-generated GL API files/headers +]) + +env.Prepend(LIBS = [ + glapi +]) + +sources = [ + 'GLView.cpp', + 'GLRenderer.cpp', + 'GLRendererRoster.cpp', + 'GLDispatcher.cpp', +] + +# libGL.so +libgl = env.SharedLibrary( + target ='GL', + source = sources, + SHLIBSUFFIX = env['SHLIBSUFFIX'], +) + +env.Alias('libgl-haiku', libgl) -- cgit v1.2.3