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
This commit is contained in:
@@ -122,6 +122,7 @@ if not env['embedded']:
|
||||
if env['platform'] == 'haiku':
|
||||
SConscript([
|
||||
'targets/haiku-softpipe/SConscript',
|
||||
'targets/libgl-haiku/SConscript',
|
||||
])
|
||||
|
||||
if env['dri']:
|
||||
|
||||
@@ -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@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;
|
||||
}
|
||||
@@ -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@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
|
||||
@@ -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; }
|
||||
@@ -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@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_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;
|
||||
}
|
||||
@@ -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@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 */
|
||||
@@ -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 <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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
Reference in New Issue
Block a user