[Mesa-dev] [PATCH] haiku: Build Haiku's libGL from within Mesa

Alexander von Gluck kallisti5 at unixzen.com
Tue Oct 1 14:15:00 PDT 2013


* 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/Makefile.am        |  52 ++
 src/gallium/targets/libgl-haiku/SConscript         |  34 ++
 9 files changed, 1294 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/Makefile.am
 create mode 100644 src/gallium/targets/libgl-haiku/SConscript

diff --git a/src/gallium/SConscript b/src/gallium/SConscript
index ca75f37..9a25cca 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 0000000..46b91d5
--- /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 <brian.e.paul at gmail.com>
+ *		Philippe Houdoin <philippe.houdoin at free.fr>
+ *		Alexander von Gluck IV <kallisti5 at 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;
+}
diff --git a/src/gallium/targets/libgl-haiku/GLDispatcher.h b/src/gallium/targets/libgl-haiku/GLDispatcher.h
new file mode 100644
index 0000000..44bca8c
--- /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 <brian.e.paul at gmail.com>
+ *		Philippe Houdoin <philippe.houdoin at 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
diff --git a/src/gallium/targets/libgl-haiku/GLRenderer.cpp b/src/gallium/targets/libgl-haiku/GLRenderer.cpp
new file mode 100644
index 0000000..4573a64
--- /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 <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; }
diff --git a/src/gallium/targets/libgl-haiku/GLRendererRoster.cpp b/src/gallium/targets/libgl-haiku/GLRendererRoster.cpp
new file mode 100644
index 0000000..70bc412
--- /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 <philippe.houdoin at free.fr>
+ *		Alexander von Gluck IV <kallisti5 at 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, &parameterLength) == 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, &parameterLength) == 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 0000000..5c8da27
--- /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 <philippe.houdoin at 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 */
diff --git a/src/gallium/targets/libgl-haiku/GLView.cpp b/src/gallium/targets/libgl-haiku/GLView.cpp
new file mode 100644
index 0000000..9ae5b5c
--- /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 at users.berlios.de
+ *		Philippe Houdoin, philippe.houdoin at free.fr
+ *		Stefano Ceccherini, burton666 at 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);
+}
+
diff --git a/src/gallium/targets/libgl-haiku/Makefile.am b/src/gallium/targets/libgl-haiku/Makefile.am
new file mode 100644
index 0000000..c5608a8
--- /dev/null
+++ b/src/gallium/targets/libgl-haiku/Makefile.am
@@ -0,0 +1,52 @@
+# Copyright © 2012 Intel Corporation
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/include \
+	-I$(top_srcdir)/src/mapi \
+	-I$(top_srcdir)/src/mesa \
+	-I$(top_srcdir)/src/mesa/main \
+	-I$(top_srcdir)/src/gallium/include \
+	-I$(top_srcdir)/src/gallium/drivers \
+	-I$(top_srcdir)/src/gallium/auxiliary
+
+lib_LTLIBRARIES = libGL.la
+
+libGL_la_SOURCES = xlib.c
+
+libGL_la_LIBADD = \
+	$(top_builddir)/src/gallium/winsys/sw/xlib/libws_xlib.la \
+	$(top_builddir)/src/gallium/drivers/softpipe/libsoftpipe.la \
+	$(top_builddir)/src/gallium/drivers/trace/libtrace.la \
+	$(top_builddir)/src/gallium/drivers/rbug/librbug.la \
+	$(top_builddir)/src/gallium/drivers/galahad/libgalahad.la \
+	$(top_builddir)/src/mapi/glapi/libglapi.la \
+	$(top_builddir)/src/mesa/libmesagallium.la \
+	$(top_builddir)/src/gallium/auxiliary/libgallium.la \
+	$(GL_LIB_DEPS) \
+	$(CLOCK_LIB)
+
+# Provide compatibility with scripts for the old Mesa build system for
+# a while by putting a link to the driver into /lib of the build tree.
+all-local: libGL.la
+	$(MKDIR_P) $(top_builddir)/$(LIB_DIR)/gallium
+	ln -f .libs/libGL.so* $(top_builddir)/$(LIB_DIR)/gallium/
diff --git a/src/gallium/targets/libgl-haiku/SConscript b/src/gallium/targets/libgl-haiku/SConscript
new file mode 100644
index 0000000..2e6b628
--- /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)
-- 
1.8.3.4






More information about the mesa-dev mailing list