# enable OpenGL ES support.
SConscript('mapi/glapi/gen/SConscript')
SConscript('mapi/glapi/SConscript')
+
+# Haiku C++ libGL dispatch (renderers depend on libgl)
+if env['platform'] in ['haiku']:
+ SConscript('hgl/SConscript')
+
SConscript('mesa/SConscript')
SConscript('mapi/vgapi/SConscript')
if env['platform'] == 'haiku':
SConscript([
'targets/haiku-softpipe/SConscript',
- 'targets/libgl-haiku/SConscript',
])
if env['dri']:
])
env.Prepend(LIBS = [softpipe])
+env.Prepend(LIBS = [libgl])
+
env.Append(CPPPATH = [
'#/src/mapi',
'#/src/mesa',
+++ /dev/null
-/*
- * 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 <brian.e.paul@gmail.com>
- * Philippe Houdoin <philippe.houdoin@free.fr>
- * Alexander von Gluck IV <kallisti5@unixzen.com>
- */
-
-
-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;
-}
+++ /dev/null
-/*
- * 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 <brian.e.paul@gmail.com>
- * Philippe Houdoin <philippe.houdoin@free.fr>
- */
-#ifndef GLDISPATCHER_H
-#define GLDISPATCHER_H
-
-
-#include <BeBuild.h>
-#include <GL/gl.h>
-#include <SupportDefs.h>
-
-#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
+++ /dev/null
-/*
- * Copyright 2006-2008, Philippe Houdoin. All rights reserved.
- * Distributed under the terms of the MIT License.
- */
-
-
-#include <kernel/image.h>
-
-#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; }
+++ /dev/null
-/*
- * Copyright 2006-2012 Haiku, Inc. All Rights Reserved.
- * Distributed under the terms of the MIT License.
- *
- * Authors:
- * Philippe Houdoin <philippe.houdoin@free.fr>
- * Alexander von Gluck IV <kallisti5@unixzen.com>
- */
-
-
-#include <driver_settings.h>
-#include <image.h>
-
-#include <kernel/image.h>
-#include <system/safemode_defs.h>
-
-#include <Directory.h>
-#include <FindDirectory.h>
-#include <Path.h>
-#include <String.h>
-#include "GLDispatcher.h"
-#include "GLRendererRoster.h"
-
-#include <new>
-#include <string.h>
-
-
-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_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;
-}
+++ /dev/null
-/*
- * Copyright 2006-2012, Haiku, Inc. All Rights Reserved.
- * Distributed under the terms of the MIT License.
- *
- * Authors:
- * Philippe Houdoin <philippe.houdoin@free.fr>
- */
-#ifndef _GLRENDERER_ROSTER_H
-#define _GLRENDERER_ROSTER_H
-
-
-#include <GLRenderer.h>
-
-#include <map>
-
-
-struct renderer_item {
- BGLRenderer* renderer;
- entry_ref ref;
- ino_t node;
- image_id image;
-};
-
-typedef std::map<renderer_id, renderer_item> 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 */
+++ /dev/null
-/*
- * 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 <kernel/image.h>
-
-#include <GLView.h>
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <DirectWindow.h>
-#include <GLRenderer.h>
-
-#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);
-}
-
+++ /dev/null
-#######################################################################
-# SConscript for Haiku OpenGL kit
-
-Import('*')
-
-env = env.Clone()
-
-env.Append(CPPPATH = [
- '#/src/mapi',
- '#/src/mesa',
- '#/src/mesa/main',
- '#/include/HaikuGL',
- '/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)
--- /dev/null
+/*
+ * 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 <brian.e.paul@gmail.com>
+ * Philippe Houdoin <philippe.houdoin@free.fr>
+ * Alexander von Gluck IV <kallisti5@unixzen.com>
+ */
+
+
+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;
+}
--- /dev/null
+/*
+ * 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 <brian.e.paul@gmail.com>
+ * Philippe Houdoin <philippe.houdoin@free.fr>
+ */
+#ifndef GLDISPATCHER_H
+#define GLDISPATCHER_H
+
+
+#include <BeBuild.h>
+#include <GL/gl.h>
+#include <SupportDefs.h>
+
+#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
--- /dev/null
+/*
+ * Copyright 2006-2008, Philippe Houdoin. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include <kernel/image.h>
+
+#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; }
--- /dev/null
+/*
+ * Copyright 2006-2012 Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ * Philippe Houdoin <philippe.houdoin@free.fr>
+ * Alexander von Gluck IV <kallisti5@unixzen.com>
+ */
+
+
+#include <driver_settings.h>
+#include <image.h>
+
+#include <kernel/image.h>
+#include <system/safemode_defs.h>
+
+#include <Directory.h>
+#include <FindDirectory.h>
+#include <Path.h>
+#include <String.h>
+#include "GLDispatcher.h"
+#include "GLRendererRoster.h"
+
+#include <new>
+#include <string.h>
+
+
+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_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;
+}
--- /dev/null
+/*
+ * Copyright 2006-2012, Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ * Philippe Houdoin <philippe.houdoin@free.fr>
+ */
+#ifndef _GLRENDERER_ROSTER_H
+#define _GLRENDERER_ROSTER_H
+
+
+#include <GLRenderer.h>
+
+#include <map>
+
+
+struct renderer_item {
+ BGLRenderer* renderer;
+ entry_ref ref;
+ ino_t node;
+ image_id image;
+};
+
+typedef std::map<renderer_id, renderer_item> 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 */
--- /dev/null
+/*
+ * 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 <kernel/image.h>
+
+#include <GLView.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <DirectWindow.h>
+#include <GLRenderer.h>
+
+#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);
+}
+
--- /dev/null
+#######################################################################
+# SConscript for Haiku OpenGL kit
+
+Import('*')
+
+env = env.Clone()
+
+env.Append(CPPPATH = [
+ '#/src/mapi',
+ '#/src/mesa',
+ '#/src/mesa/main',
+ '#/include/HaikuGL',
+ '/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)
+Export('libgl')
mesa,
])
+env.Prepend(LIBS = [libgl])
+
sources = [
'SoftwareRast.cpp'
]