mirror of
https://gitee.com/openharmony/third_party_mesa3d
synced 2025-02-17 00:18:24 +00:00
hgl: Major refactor and cleanup
* Drop old-timey GLDisplatcher * Refactor haiku-softpipe fixing some hacks * Bubble BBitmap up to winsys Reviewed-by: Alexander von Gluck IV <kallisti5@unixzen.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8323>
This commit is contained in:
parent
bd6ea80d96
commit
065cf4f914
@ -27,8 +27,7 @@ class _EXPORT BGLRenderer
|
||||
BGLRenderer & operator=(const BGLRenderer &);
|
||||
|
||||
public:
|
||||
BGLRenderer(BGLView *view, ulong bgl_options,
|
||||
BGLDispatcher *dispatcher);
|
||||
BGLRenderer(BGLView *view, ulong bgl_options);
|
||||
virtual ~BGLRenderer();
|
||||
|
||||
void Acquire();
|
||||
@ -50,7 +49,6 @@ public:
|
||||
inline int32 ReferenceCount() const { return fRefCount; };
|
||||
inline ulong Options() const { return fOptions; };
|
||||
inline BGLView* GLView() { return fView; };
|
||||
inline BGLDispatcher* GLDispatcher() { return fDispatcher; };
|
||||
|
||||
private:
|
||||
friend class GLRendererRoster;
|
||||
@ -64,13 +62,12 @@ private:
|
||||
int32 fRefCount; // How much we're still useful
|
||||
BGLView* fView; // Never forget who is the boss!
|
||||
ulong fOptions; // Keep that tune in memory
|
||||
BGLDispatcher* fDispatcher;// Our personal GL API call dispatcher
|
||||
|
||||
GLRendererRoster* fOwningRoster;
|
||||
renderer_id fID;
|
||||
};
|
||||
|
||||
extern "C" _EXPORT BGLRenderer* instantiate_gl_renderer(BGLView *view, ulong options, BGLDispatcher *dispatcher);
|
||||
extern "C" _EXPORT BGLRenderer* instantiate_gl_renderer(BGLView *view, ulong options);
|
||||
|
||||
|
||||
#endif // GLRENDERER_H
|
||||
|
@ -12,18 +12,19 @@
|
||||
|
||||
#include <GL/gl.h>
|
||||
|
||||
#define BGL_RGB 0
|
||||
#define BGL_INDEX 1
|
||||
#define BGL_SINGLE 0
|
||||
#define BGL_DOUBLE 2
|
||||
#define BGL_DIRECT 0
|
||||
#define BGL_INDIRECT 4
|
||||
#define BGL_ACCUM 8
|
||||
#define BGL_ALPHA 16
|
||||
#define BGL_DEPTH 32
|
||||
#define BGL_OVERLAY 64
|
||||
#define BGL_UNDERLAY 128
|
||||
#define BGL_STENCIL 512
|
||||
#define BGL_RGB 0
|
||||
#define BGL_INDEX 1
|
||||
#define BGL_SINGLE 0
|
||||
#define BGL_DOUBLE 2
|
||||
#define BGL_DIRECT 0
|
||||
#define BGL_INDIRECT 4
|
||||
#define BGL_ACCUM 8
|
||||
#define BGL_ALPHA 16
|
||||
#define BGL_DEPTH 32
|
||||
#define BGL_OVERLAY 64
|
||||
#define BGL_UNDERLAY 128
|
||||
#define BGL_STENCIL 512
|
||||
#define BGL_SHARE_CONTEXT 1024
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
|
@ -57,24 +57,20 @@ hgl_st_framebuffer(struct st_framebuffer_iface *stfbi)
|
||||
|
||||
|
||||
static bool
|
||||
hgl_st_framebuffer_flush_front(struct st_context_iface *stctxi,
|
||||
hgl_st_framebuffer_flush_front(struct st_context_iface* stctxi,
|
||||
struct st_framebuffer_iface* stfbi, enum st_attachment_type statt)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
//struct hgl_context* context = hgl_st_context(stctxi);
|
||||
// struct hgl_buffer* buffer = hgl_st_context(stfbi);
|
||||
struct hgl_buffer* buffer = hgl_st_framebuffer(stfbi);
|
||||
//buffer->surface
|
||||
struct pipe_resource* ptex = buffer->textures[statt];
|
||||
|
||||
#if 0
|
||||
struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
|
||||
mtx_lock(&stwfb->fb->mutex);
|
||||
if (!ptex)
|
||||
return true;
|
||||
|
||||
struct pipe_resource* resource = textures[statt];
|
||||
if (resource)
|
||||
stw_framebuffer_present_locked(...);
|
||||
#endif
|
||||
// TODO: pipe_context here??? Might be needed for hw renderers
|
||||
buffer->screen->flush_frontbuffer(buffer->screen, NULL, ptex, 0, 0,
|
||||
buffer->winsysContext, NULL);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -93,6 +89,8 @@ hgl_st_framebuffer_validate_textures(struct st_framebuffer_iface *stfbi,
|
||||
buffer = hgl_st_framebuffer(stfbi);
|
||||
|
||||
if (buffer->width != width || buffer->height != height) {
|
||||
TRACE("validate_textures: size changed: %d, %d -> %d, %d\n",
|
||||
buffer->width, buffer->height, width, height);
|
||||
for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
|
||||
pipe_resource_reference(&buffer->textures[i], NULL);
|
||||
}
|
||||
@ -109,31 +107,34 @@ hgl_st_framebuffer_validate_textures(struct st_framebuffer_iface *stfbi,
|
||||
enum pipe_format format;
|
||||
unsigned bind;
|
||||
|
||||
switch (i) {
|
||||
case ST_ATTACHMENT_FRONT_LEFT:
|
||||
case ST_ATTACHMENT_BACK_LEFT:
|
||||
case ST_ATTACHMENT_FRONT_RIGHT:
|
||||
case ST_ATTACHMENT_BACK_RIGHT:
|
||||
format = buffer->visual->color_format;
|
||||
bind = PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_RENDER_TARGET;
|
||||
break;
|
||||
case ST_ATTACHMENT_DEPTH_STENCIL:
|
||||
format = buffer->visual->depth_stencil_format;
|
||||
bind = PIPE_BIND_DEPTH_STENCIL;
|
||||
break;
|
||||
default:
|
||||
format = PIPE_FORMAT_NONE;
|
||||
bind = 0;
|
||||
break;
|
||||
}
|
||||
if (((1 << i) & buffer->visual->buffer_mask) && buffer->textures[i] == NULL) {
|
||||
switch (i) {
|
||||
case ST_ATTACHMENT_FRONT_LEFT:
|
||||
case ST_ATTACHMENT_BACK_LEFT:
|
||||
case ST_ATTACHMENT_FRONT_RIGHT:
|
||||
case ST_ATTACHMENT_BACK_RIGHT:
|
||||
format = buffer->visual->color_format;
|
||||
bind = PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_RENDER_TARGET;
|
||||
break;
|
||||
case ST_ATTACHMENT_DEPTH_STENCIL:
|
||||
format = buffer->visual->depth_stencil_format;
|
||||
bind = PIPE_BIND_DEPTH_STENCIL;
|
||||
break;
|
||||
default:
|
||||
format = PIPE_FORMAT_NONE;
|
||||
bind = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (format != PIPE_FORMAT_NONE) {
|
||||
templat.format = format;
|
||||
templat.bind = bind;
|
||||
buffer->textures[i] = buffer->screen->resource_create(buffer->screen,
|
||||
&templat);
|
||||
if (!buffer->textures[i])
|
||||
return FALSE;
|
||||
if (format != PIPE_FORMAT_NONE) {
|
||||
templat.format = format;
|
||||
templat.bind = bind;
|
||||
TRACE("resource_create(%d, %d, %d)\n", i, format, bind);
|
||||
buffer->textures[i] = buffer->screen->resource_create(buffer->screen,
|
||||
&templat);
|
||||
if (!buffer->textures[i])
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,10 +166,6 @@ hgl_st_framebuffer_validate(struct st_context_iface *stctxi,
|
||||
context = hgl_st_context(stctxi);
|
||||
buffer = hgl_st_framebuffer(stfbi);
|
||||
|
||||
//int32 width = 0;
|
||||
//int32 height = 0;
|
||||
//get_bitmap_size(context->bitmap, &width, &height);
|
||||
|
||||
// Build mask of current attachments
|
||||
stAttachmentMask = 0;
|
||||
for (i = 0; i < count; i++)
|
||||
@ -186,14 +183,9 @@ hgl_st_framebuffer_validate(struct st_context_iface *stctxi,
|
||||
|
||||
ret = hgl_st_framebuffer_validate_textures(stfbi,
|
||||
context->width, context->height, stAttachmentMask);
|
||||
|
||||
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
// TODO: Simply update attachments
|
||||
//if (!resized) {
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
@ -223,14 +215,14 @@ static uint32_t hgl_fb_ID = 0;
|
||||
* Create new framebuffer
|
||||
*/
|
||||
struct hgl_buffer *
|
||||
hgl_create_st_framebuffer(struct hgl_context* context)
|
||||
hgl_create_st_framebuffer(struct hgl_context* context, void *winsysContext)
|
||||
{
|
||||
struct hgl_buffer *buffer;
|
||||
CALLED();
|
||||
|
||||
// Our requires before creating a framebuffer
|
||||
assert(context);
|
||||
assert(context->screen);
|
||||
assert(context->display);
|
||||
assert(context->stVisual);
|
||||
|
||||
buffer = CALLOC_STRUCT(hgl_buffer);
|
||||
@ -242,9 +234,10 @@ hgl_create_st_framebuffer(struct hgl_context* context)
|
||||
|
||||
// Prepare our buffer
|
||||
buffer->visual = context->stVisual;
|
||||
buffer->screen = context->screen;
|
||||
buffer->screen = context->display->manager->screen;
|
||||
buffer->winsysContext = winsysContext;
|
||||
|
||||
if (context->screen->get_param(buffer->screen, PIPE_CAP_NPOT_TEXTURES))
|
||||
if (buffer->screen->get_param(buffer->screen, PIPE_CAP_NPOT_TEXTURES))
|
||||
buffer->target = PIPE_TEXTURE_2D;
|
||||
else
|
||||
buffer->target = PIPE_TEXTURE_RECT;
|
||||
@ -257,12 +250,26 @@ hgl_create_st_framebuffer(struct hgl_context* context)
|
||||
p_atomic_set(&buffer->stfbi->stamp, 1);
|
||||
buffer->stfbi->st_manager_private = (void*)buffer;
|
||||
buffer->stfbi->ID = p_atomic_inc_return(&hgl_fb_ID);
|
||||
buffer->stfbi->state_manager = context->manager;
|
||||
buffer->stfbi->state_manager = context->display->manager;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hgl_destroy_st_framebuffer(struct hgl_buffer *buffer)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
int i;
|
||||
for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
|
||||
pipe_resource_reference(&buffer->textures[i], NULL);
|
||||
|
||||
FREE(buffer->stfbi);
|
||||
FREE(buffer);
|
||||
}
|
||||
|
||||
|
||||
struct st_api*
|
||||
hgl_create_st_api()
|
||||
{
|
||||
@ -271,38 +278,6 @@ hgl_create_st_api()
|
||||
}
|
||||
|
||||
|
||||
struct st_manager *
|
||||
hgl_create_st_manager(struct hgl_context* context)
|
||||
{
|
||||
struct st_manager* manager;
|
||||
|
||||
CALLED();
|
||||
|
||||
// Required things
|
||||
assert(context);
|
||||
assert(context->screen);
|
||||
|
||||
manager = CALLOC_STRUCT(st_manager);
|
||||
assert(manager);
|
||||
|
||||
//manager->display = dpy;
|
||||
manager->screen = context->screen;
|
||||
manager->get_param = hgl_st_manager_get_param;
|
||||
manager->st_manager_private = (void *)context;
|
||||
|
||||
return manager;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hgl_destroy_st_manager(struct st_manager *manager)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
FREE(manager);
|
||||
}
|
||||
|
||||
|
||||
struct st_visual*
|
||||
hgl_create_st_visual(ulong options)
|
||||
{
|
||||
@ -335,6 +310,7 @@ hgl_create_st_visual(ulong options)
|
||||
visual->render_buffer = ST_ATTACHMENT_FRONT_LEFT;
|
||||
|
||||
if ((options & BGL_DOUBLE) != 0) {
|
||||
TRACE("double buffer enabled\n");
|
||||
visual->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
|
||||
visual->render_buffer = ST_ATTACHMENT_BACK_LEFT;
|
||||
}
|
||||
@ -364,3 +340,33 @@ hgl_destroy_st_visual(struct st_visual* visual)
|
||||
|
||||
FREE(visual);
|
||||
}
|
||||
|
||||
|
||||
struct hgl_display*
|
||||
hgl_create_display(struct pipe_screen* screen)
|
||||
{
|
||||
struct hgl_display* display;
|
||||
|
||||
display = CALLOC_STRUCT(hgl_display);
|
||||
assert(display);
|
||||
display->api = st_gl_api_create();
|
||||
display->manager = CALLOC_STRUCT(st_manager);
|
||||
assert(display->manager);
|
||||
display->manager->screen = screen;
|
||||
display->manager->get_param = hgl_st_manager_get_param;
|
||||
// display->manager->st_manager_private is used by llvmpipe
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hgl_destroy_display(struct hgl_display *display)
|
||||
{
|
||||
if (display->manager->destroy)
|
||||
display->manager->destroy(display->manager);
|
||||
FREE(display->manager);
|
||||
if (display->api->destroy)
|
||||
display->api->destroy(display->api);
|
||||
FREE(display);
|
||||
}
|
||||
|
@ -8,15 +8,13 @@
|
||||
#ifndef HGL_CONTEXT_H
|
||||
#define HGL_CONTEXT_H
|
||||
|
||||
|
||||
#include "os/os_thread.h"
|
||||
#include "pipe/p_format.h"
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "pipe/p_screen.h"
|
||||
#include "postprocess/filters.h"
|
||||
|
||||
#include "frontend/api.h"
|
||||
#include "frontend/st_manager.h"
|
||||
#include "os/os_thread.h"
|
||||
|
||||
#include "bitmap_wrapper.h"
|
||||
|
||||
@ -41,31 +39,29 @@ struct hgl_buffer
|
||||
unsigned mask;
|
||||
|
||||
struct pipe_screen* screen;
|
||||
struct pipe_surface* surface;
|
||||
void* winsysContext;
|
||||
|
||||
enum pipe_texture_target target;
|
||||
struct pipe_resource* textures[ST_ATTACHMENT_COUNT];
|
||||
|
||||
void *map;
|
||||
};
|
||||
|
||||
//struct hgl_buffer *next; /**< next in linked list */
|
||||
|
||||
struct hgl_display
|
||||
{
|
||||
mtx_t mutex;
|
||||
|
||||
struct st_api* api;
|
||||
struct st_manager* manager;
|
||||
};
|
||||
|
||||
|
||||
struct hgl_context
|
||||
{
|
||||
struct st_api* api;
|
||||
// API
|
||||
struct st_manager* manager;
|
||||
// Manager
|
||||
struct hgl_display* display;
|
||||
struct st_context_iface* st;
|
||||
// Interface Object
|
||||
struct st_visual* stVisual;
|
||||
// Visual
|
||||
|
||||
struct pipe_screen* screen;
|
||||
|
||||
//struct pipe_resource* textures[ST_ATTACHMENT_COUNT];
|
||||
|
||||
// Post processing
|
||||
struct pp_queue_t* postProcess;
|
||||
@ -75,13 +71,9 @@ struct hgl_context
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
|
||||
Bitmap* bitmap;
|
||||
color_space colorSpace;
|
||||
|
||||
mtx_t fbMutex;
|
||||
|
||||
struct hgl_buffer* draw;
|
||||
struct hgl_buffer* read;
|
||||
struct hgl_buffer* buffer;
|
||||
};
|
||||
|
||||
// hgl_buffer from statetracker interface
|
||||
@ -91,7 +83,8 @@ struct hgl_buffer* hgl_st_framebuffer(struct st_framebuffer_iface *stfbi);
|
||||
struct st_api* hgl_create_st_api(void);
|
||||
|
||||
// hgl framebuffer
|
||||
struct hgl_buffer* hgl_create_st_framebuffer(struct hgl_context* context);
|
||||
struct hgl_buffer* hgl_create_st_framebuffer(struct hgl_context* context, void *winsysContext);
|
||||
void hgl_destroy_st_framebuffer(struct hgl_buffer *buffer);
|
||||
|
||||
// hgl manager
|
||||
struct st_manager* hgl_create_st_manager(struct hgl_context* screen);
|
||||
@ -101,6 +94,10 @@ void hgl_destroy_st_manager(struct st_manager *manager);
|
||||
struct st_visual* hgl_create_st_visual(ulong options);
|
||||
void hgl_destroy_st_visual(struct st_visual* visual);
|
||||
|
||||
// hgl display
|
||||
struct hgl_display* hgl_create_display(struct pipe_screen* screen);
|
||||
void hgl_destroy_display(struct hgl_display *display);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "GalliumContext.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "GLView.h"
|
||||
|
||||
@ -41,11 +42,12 @@
|
||||
#endif
|
||||
#define ERROR(x...) printf("GalliumContext: " x)
|
||||
|
||||
int32 GalliumContext::fDisplayRefCount = 0;
|
||||
hgl_display* GalliumContext::fDisplay = NULL;
|
||||
|
||||
GalliumContext::GalliumContext(ulong options)
|
||||
:
|
||||
fOptions(options),
|
||||
fScreen(NULL),
|
||||
fCurrentContext(0)
|
||||
{
|
||||
CALLED();
|
||||
@ -54,7 +56,7 @@ GalliumContext::GalliumContext(ulong options)
|
||||
for (context_id i = 0; i < CONTEXT_MAX; i++)
|
||||
fContext[i] = NULL;
|
||||
|
||||
CreateScreen();
|
||||
CreateDisplay();
|
||||
|
||||
(void) mtx_init(&fMutex, mtx_plain);
|
||||
}
|
||||
@ -70,17 +72,20 @@ GalliumContext::~GalliumContext()
|
||||
DestroyContext(i);
|
||||
Unlock();
|
||||
|
||||
mtx_destroy(&fMutex);
|
||||
DestroyDisplay();
|
||||
|
||||
// TODO: Destroy fScreen
|
||||
mtx_destroy(&fMutex);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
GalliumContext::CreateScreen()
|
||||
GalliumContext::CreateDisplay()
|
||||
{
|
||||
CALLED();
|
||||
|
||||
if (atomic_add(&fDisplayRefCount, 1) > 0)
|
||||
return B_OK;
|
||||
|
||||
// Allocate winsys and attach callback hooks
|
||||
struct sw_winsys* winsys = hgl_create_sw_winsys();
|
||||
|
||||
@ -89,25 +94,47 @@ GalliumContext::CreateScreen()
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
fScreen = sw_screen_create(winsys);
|
||||
struct pipe_screen* screen = sw_screen_create(winsys);
|
||||
|
||||
if (fScreen == NULL) {
|
||||
if (screen == NULL) {
|
||||
ERROR("%s: Couldn't create screen!\n", __FUNCTION__);
|
||||
FREE(winsys);
|
||||
winsys->destroy(winsys);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
debug_screen_wrap(fScreen);
|
||||
debug_screen_wrap(screen);
|
||||
|
||||
const char* driverName = fScreen->get_name(fScreen);
|
||||
const char* driverName = screen->get_name(screen);
|
||||
ERROR("%s: Using %s driver.\n", __func__, driverName);
|
||||
|
||||
fDisplay = hgl_create_display(screen);
|
||||
|
||||
if (fDisplay == NULL) {
|
||||
ERROR("%s: Couldn't create display!\n", __FUNCTION__);
|
||||
screen->destroy(screen); // will also destroy winsys
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GalliumContext::DestroyDisplay()
|
||||
{
|
||||
if (atomic_add(&fDisplayRefCount, -1) > 1)
|
||||
return;
|
||||
|
||||
if (fDisplay != NULL) {
|
||||
struct pipe_screen* screen = fDisplay->manager->screen;
|
||||
hgl_destroy_display(fDisplay); fDisplay = NULL;
|
||||
screen->destroy(screen); // destroy will deallocate object
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
context_id
|
||||
GalliumContext::CreateContext(Bitmap *bitmap)
|
||||
GalliumContext::CreateContext(HGLWinsysContext *wsContext)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
@ -119,31 +146,15 @@ GalliumContext::CreateContext(Bitmap *bitmap)
|
||||
}
|
||||
|
||||
// Set up the initial things our context needs
|
||||
context->bitmap = bitmap;
|
||||
context->colorSpace = get_bitmap_color_space(bitmap);
|
||||
context->screen = fScreen;
|
||||
context->draw = NULL;
|
||||
context->read = NULL;
|
||||
context->st = NULL;
|
||||
|
||||
// Create st_gl_api
|
||||
context->api = hgl_create_st_api();
|
||||
if (!context->api) {
|
||||
ERROR("%s: Couldn't obtain Mesa state tracker API!\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create state_tracker manager
|
||||
context->manager = hgl_create_st_manager(context);
|
||||
context->display = fDisplay;
|
||||
|
||||
// Create state tracker visual
|
||||
context->stVisual = hgl_create_st_visual(fOptions);
|
||||
|
||||
// Create state tracker framebuffers
|
||||
context->draw = hgl_create_st_framebuffer(context);
|
||||
context->read = hgl_create_st_framebuffer(context);
|
||||
context->buffer = hgl_create_st_framebuffer(context, wsContext);
|
||||
|
||||
if (!context->draw || !context->read) {
|
||||
if (!context->buffer) {
|
||||
ERROR("%s: Problem allocating framebuffer!\n", __func__);
|
||||
FREE(context->stVisual);
|
||||
return -1;
|
||||
@ -159,10 +170,17 @@ GalliumContext::CreateContext(Bitmap *bitmap)
|
||||
attribs.minor = 0;
|
||||
//attribs.flags |= ST_CONTEXT_FLAG_DEBUG;
|
||||
|
||||
struct st_context_iface* shared = NULL;
|
||||
|
||||
if (fOptions & BGL_SHARE_CONTEXT) {
|
||||
shared = fDisplay->api->get_current(fDisplay->api);
|
||||
TRACE("shared context: %p\n", shared);
|
||||
}
|
||||
|
||||
// Create context using state tracker api call
|
||||
enum st_context_error result;
|
||||
context->st = context->api->create_context(context->api, context->manager,
|
||||
&attribs, &result, context->st);
|
||||
context->st = fDisplay->api->create_context(fDisplay->api, fDisplay->manager,
|
||||
&attribs, &result, shared);
|
||||
|
||||
if (!context->st) {
|
||||
ERROR("%s: Couldn't create mesa state tracker context!\n",
|
||||
@ -200,7 +218,7 @@ GalliumContext::CreateContext(Bitmap *bitmap)
|
||||
context->st->st_manager_private = (void*)context;
|
||||
|
||||
struct st_context *stContext = (struct st_context*)context->st;
|
||||
|
||||
|
||||
// Init Gallium3D Post Processing
|
||||
// TODO: no pp filters are enabled yet through postProcessEnable
|
||||
context->postProcess = pp_init(stContext->pipe, context->postProcessEnable,
|
||||
@ -243,7 +261,7 @@ GalliumContext::DestroyContext(context_id contextID)
|
||||
return;
|
||||
|
||||
if (fContext[contextID]->st) {
|
||||
fContext[contextID]->st->flush(fContext[contextID]->st, 0, NULL);
|
||||
fContext[contextID]->st->flush(fContext[contextID]->st, 0, NULL, NULL, NULL);
|
||||
fContext[contextID]->st->destroy(fContext[contextID]->st);
|
||||
}
|
||||
|
||||
@ -251,23 +269,18 @@ GalliumContext::DestroyContext(context_id contextID)
|
||||
pp_free(fContext[contextID]->postProcess);
|
||||
|
||||
// Delete state tracker framebuffer objects
|
||||
if (fContext[contextID]->read)
|
||||
delete fContext[contextID]->read;
|
||||
if (fContext[contextID]->draw)
|
||||
delete fContext[contextID]->draw;
|
||||
if (fContext[contextID]->buffer)
|
||||
hgl_destroy_st_framebuffer(fContext[contextID]->buffer);
|
||||
|
||||
if (fContext[contextID]->stVisual)
|
||||
hgl_destroy_st_visual(fContext[contextID]->stVisual);
|
||||
|
||||
if (fContext[contextID]->manager)
|
||||
hgl_destroy_st_manager(fContext[contextID]->manager);
|
||||
|
||||
FREE(fContext[contextID]);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
GalliumContext::SetCurrentContext(Bitmap *bitmap, context_id contextID)
|
||||
GalliumContext::SetCurrentContext(bool set, context_id contextID)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
@ -279,16 +292,17 @@ GalliumContext::SetCurrentContext(Bitmap *bitmap, context_id contextID)
|
||||
Lock();
|
||||
context_id oldContextID = fCurrentContext;
|
||||
struct hgl_context* context = fContext[contextID];
|
||||
Unlock();
|
||||
|
||||
if (!context) {
|
||||
ERROR("%s: Invalid context provided (#%" B_PRIu64 ")!\n",
|
||||
__func__, contextID);
|
||||
Unlock();
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if (!bitmap) {
|
||||
context->api->make_current(context->api, NULL, NULL, NULL);
|
||||
if (!set) {
|
||||
fDisplay->api->make_current(fDisplay->api, NULL, NULL, NULL);
|
||||
Unlock();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -297,24 +311,13 @@ GalliumContext::SetCurrentContext(Bitmap *bitmap, context_id contextID)
|
||||
|
||||
if (oldContextID > 0 && oldContextID != contextID) {
|
||||
fContext[oldContextID]->st->flush(fContext[oldContextID]->st,
|
||||
ST_FLUSH_FRONT, NULL);
|
||||
ST_FLUSH_FRONT, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
// We need to lock and unlock framebuffers before accessing them
|
||||
context->api->make_current(context->api, context->st, context->draw->stfbi,
|
||||
context->read->stfbi);
|
||||
|
||||
//if (context->textures[ST_ATTACHMENT_BACK_LEFT]
|
||||
// && context->textures[ST_ATTACHMENT_DEPTH_STENCIL]
|
||||
// && context->postProcess) {
|
||||
// TRACE("Postprocessing textures...\n");
|
||||
// pp_init_fbos(context->postProcess,
|
||||
// context->textures[ST_ATTACHMENT_BACK_LEFT]->width0,
|
||||
// context->textures[ST_ATTACHMENT_BACK_LEFT]->height0);
|
||||
//}
|
||||
|
||||
context->bitmap = bitmap;
|
||||
//context->st->pipe->priv = context;
|
||||
fDisplay->api->make_current(fDisplay->api, context->st, context->buffer->stfbi,
|
||||
context->buffer->stfbi);
|
||||
Unlock();
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
@ -326,40 +329,62 @@ GalliumContext::SwapBuffers(context_id contextID)
|
||||
CALLED();
|
||||
|
||||
Lock();
|
||||
struct hgl_context *context = fContext[contextID];
|
||||
Unlock();
|
||||
struct hgl_context* context = fContext[contextID];
|
||||
|
||||
if (!context) {
|
||||
ERROR("%s: context not found\n", __func__);
|
||||
return B_ERROR;
|
||||
}
|
||||
context->st->flush(context->st, ST_FLUSH_FRONT, NULL);
|
||||
|
||||
struct hgl_buffer* buffer = hgl_st_framebuffer(context->draw->stfbi);
|
||||
pipe_surface* surface = buffer->surface;
|
||||
if (!surface) {
|
||||
ERROR("%s: Invalid drawable surface!\n", __func__);
|
||||
Unlock();
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
fScreen->flush_frontbuffer(fScreen, context->st->pipe, surface->texture, 0, 0,
|
||||
context->bitmap, NULL);
|
||||
// will flush front buffer if no double buffering is used
|
||||
context->st->flush(context->st, ST_FLUSH_FRONT, NULL, NULL, NULL);
|
||||
|
||||
struct hgl_buffer* buffer = context->buffer;
|
||||
|
||||
// flush back buffer and swap buffers if double buffering is used
|
||||
if (buffer->textures[ST_ATTACHMENT_BACK_LEFT] != NULL) {
|
||||
buffer->screen->flush_frontbuffer(buffer->screen, NULL, buffer->textures[ST_ATTACHMENT_BACK_LEFT],
|
||||
0, 0, buffer->winsysContext, NULL);
|
||||
std::swap(buffer->textures[ST_ATTACHMENT_FRONT_LEFT], buffer->textures[ST_ATTACHMENT_BACK_LEFT]);
|
||||
p_atomic_inc(&buffer->stfbi->stamp);
|
||||
}
|
||||
|
||||
Unlock();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GalliumContext::Draw(context_id contextID, BRect updateRect)
|
||||
{
|
||||
struct hgl_context *context = fContext[contextID];
|
||||
|
||||
if (!context) {
|
||||
ERROR("%s: context not found\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
struct hgl_buffer* buffer = context->buffer;
|
||||
|
||||
if (buffer->textures[ST_ATTACHMENT_FRONT_LEFT] == NULL)
|
||||
return;
|
||||
|
||||
buffer->screen->flush_frontbuffer(buffer->screen, NULL, buffer->textures[ST_ATTACHMENT_FRONT_LEFT],
|
||||
0, 0, buffer->winsysContext, NULL);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
GalliumContext::Validate(uint32 width, uint32 height)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
if (!fContext[fCurrentContext]) {
|
||||
if (!fContext[fCurrentContext])
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fContext[fCurrentContext]->width != width
|
||||
|| fContext[fCurrentContext]->height != height) {
|
||||
if (fContext[fCurrentContext]->width != width + 1
|
||||
|| fContext[fCurrentContext]->height != height + 1) {
|
||||
Invalidate(width, height);
|
||||
return false;
|
||||
}
|
||||
@ -375,12 +400,11 @@ GalliumContext::Invalidate(uint32 width, uint32 height)
|
||||
assert(fContext[fCurrentContext]);
|
||||
|
||||
// Update st_context dimensions
|
||||
fContext[fCurrentContext]->width = width;
|
||||
fContext[fCurrentContext]->height = height;
|
||||
fContext[fCurrentContext]->width = width + 1;
|
||||
fContext[fCurrentContext]->height = height + 1;
|
||||
|
||||
// Is this the best way to invalidate?
|
||||
p_atomic_inc(&fContext[fCurrentContext]->read->stfbi->stamp);
|
||||
p_atomic_inc(&fContext[fCurrentContext]->draw->stfbi->stamp);
|
||||
p_atomic_inc(&fContext[fCurrentContext]->buffer->stfbi->stamp);
|
||||
}
|
||||
|
||||
|
||||
|
@ -16,10 +16,10 @@
|
||||
#include "pipe/p_screen.h"
|
||||
#include "postprocess/filters.h"
|
||||
#include "hgl_context.h"
|
||||
|
||||
#include "bitmap_wrapper.h"
|
||||
#include "sw/hgl/hgl_sw_winsys.h"
|
||||
|
||||
|
||||
class BBitmap;
|
||||
|
||||
class GalliumContext {
|
||||
public:
|
||||
@ -29,28 +29,30 @@ public:
|
||||
void Lock();
|
||||
void Unlock();
|
||||
|
||||
context_id CreateContext(Bitmap* bitmap);
|
||||
context_id CreateContext(HGLWinsysContext *wsContext);
|
||||
void DestroyContext(context_id contextID);
|
||||
context_id GetCurrentContext() { return fCurrentContext; };
|
||||
status_t SetCurrentContext(Bitmap *bitmap,
|
||||
context_id contextID);
|
||||
status_t SetCurrentContext(bool set, context_id contextID);
|
||||
|
||||
status_t SwapBuffers(context_id contextID);
|
||||
void Draw(context_id contextID, BRect updateRect);
|
||||
|
||||
bool Validate(uint32 width, uint32 height);
|
||||
void Invalidate(uint32 width, uint32 height);
|
||||
|
||||
private:
|
||||
status_t CreateScreen();
|
||||
status_t CreateDisplay();
|
||||
void DestroyDisplay();
|
||||
void Flush();
|
||||
|
||||
ulong fOptions;
|
||||
struct pipe_screen* fScreen;
|
||||
static int32 fDisplayRefCount;
|
||||
static hgl_display* fDisplay;
|
||||
|
||||
// Context Management
|
||||
struct hgl_context* fContext[CONTEXT_MAX];
|
||||
context_id fCurrentContext;
|
||||
mtx_t fMutex;
|
||||
mtx_t fMutex;
|
||||
};
|
||||
|
||||
|
||||
|
@ -35,16 +35,99 @@ extern const char* color_space_name(color_space space);
|
||||
|
||||
|
||||
extern "C" _EXPORT BGLRenderer*
|
||||
instantiate_gl_renderer(BGLView *view, ulong opts, BGLDispatcher *dispatcher)
|
||||
instantiate_gl_renderer(BGLView *view, ulong opts)
|
||||
{
|
||||
return new SoftwareRenderer(view, opts, dispatcher);
|
||||
return new SoftwareRenderer(view, opts);
|
||||
}
|
||||
|
||||
SoftwareRenderer::SoftwareRenderer(BGLView *view, ulong options,
|
||||
BGLDispatcher* dispatcher)
|
||||
struct RasBuf32
|
||||
{
|
||||
int32 width, height, stride;
|
||||
int32 orgX, orgY;
|
||||
int32 *colors;
|
||||
|
||||
RasBuf32(int32 width, int32 height, int32 stride, int32 orgX, int32 orgY, int32 *colors):
|
||||
width(width), height(height), stride(stride), orgX(orgX), orgY(orgY), colors(colors)
|
||||
{}
|
||||
|
||||
RasBuf32(BBitmap *bmp)
|
||||
{
|
||||
width = bmp->Bounds().IntegerWidth() + 1;
|
||||
height = bmp->Bounds().IntegerHeight() + 1;
|
||||
stride = bmp->BytesPerRow()/4;
|
||||
orgX = 0;
|
||||
orgY = 0;
|
||||
colors = (int32*)bmp->Bits();
|
||||
}
|
||||
|
||||
RasBuf32(direct_buffer_info *info)
|
||||
{
|
||||
width = 0x7fffffff;
|
||||
height = 0x7fffffff;
|
||||
stride = info->bytes_per_row/4;
|
||||
orgX = 0;
|
||||
orgY = 0;
|
||||
colors = (int32*)info->bits;
|
||||
}
|
||||
|
||||
void ClipSize(int32 x, int32 y, int32 w, int32 h)
|
||||
{
|
||||
if (x < 0) {w += x; x = 0;}
|
||||
if (y < 0) {h += y; y = 0;}
|
||||
if (x + w > width) {w = width - x;}
|
||||
if (y + h > height) {h = height - y;}
|
||||
if ((w > 0) && (h > 0)) {
|
||||
colors += y*stride + x;
|
||||
width = w;
|
||||
height = h;
|
||||
} else {
|
||||
width = 0; height = 0; colors = NULL;
|
||||
}
|
||||
if (x + orgX > 0) {orgX += x;} else {orgX = 0;}
|
||||
if (y + orgY > 0) {orgY += y;} else {orgY = 0;}
|
||||
}
|
||||
|
||||
void ClipRect(int32 l, int32 t, int32 r, int32 b)
|
||||
{
|
||||
ClipSize(l, t, r - l, b - t);
|
||||
}
|
||||
|
||||
void Shift(int32 dx, int32 dy)
|
||||
{
|
||||
orgX += dx;
|
||||
orgY += dy;
|
||||
}
|
||||
|
||||
void Clear(int32 color)
|
||||
{
|
||||
RasBuf32 dst = *this;
|
||||
dst.stride -= dst.width;
|
||||
for (; dst.height > 0; dst.height--) {
|
||||
for (int32 i = dst.width; i > 0; i--)
|
||||
*dst.colors++ = color;
|
||||
dst.colors += dst.stride;
|
||||
}
|
||||
}
|
||||
|
||||
void Blit(RasBuf32 src)
|
||||
{
|
||||
RasBuf32 dst = *this;
|
||||
int32 x, y;
|
||||
x = src.orgX - orgX;
|
||||
y = src.orgY - orgY;
|
||||
dst.ClipSize(x, y, src.width, src.height);
|
||||
src.ClipSize(-x, -y, width, height);
|
||||
for (; dst.height > 0; dst.height--) {
|
||||
memcpy(dst.colors, src.colors, 4*dst.width);
|
||||
dst.colors += dst.stride;
|
||||
src.colors += src.stride;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
SoftwareRenderer::SoftwareRenderer(BGLView *view, ulong options)
|
||||
:
|
||||
BGLRenderer(view, options, dispatcher),
|
||||
fBitmap(NULL),
|
||||
BGLRenderer(view, options),
|
||||
fDirectModeEnabled(false),
|
||||
fInfo(NULL),
|
||||
fInfoLocker("info locker"),
|
||||
@ -53,9 +136,6 @@ SoftwareRenderer::SoftwareRenderer(BGLView *view, ulong options,
|
||||
{
|
||||
CALLED();
|
||||
|
||||
// Disable double buffer for the moment.
|
||||
//options &= ~BGL_DOUBLE;
|
||||
|
||||
// Initialize the "Haiku Software GL Pipe"
|
||||
time_t beg;
|
||||
time_t end;
|
||||
@ -65,7 +145,6 @@ SoftwareRenderer::SoftwareRenderer(BGLView *view, ulong options,
|
||||
TRACE("Haiku Software GL Pipe initialization time: %f.\n",
|
||||
difftime(end, beg));
|
||||
|
||||
// Allocate a bitmap
|
||||
BRect b = view->Bounds();
|
||||
fColorSpace = BScreen(view->Window()).ColorSpace();
|
||||
TRACE("%s: Colorspace:\t%s\n", __func__, color_space_name(fColorSpace));
|
||||
@ -73,11 +152,9 @@ SoftwareRenderer::SoftwareRenderer(BGLView *view, ulong options,
|
||||
fWidth = (GLint)b.IntegerWidth();
|
||||
fHeight = (GLint)b.IntegerHeight();
|
||||
|
||||
_AllocateBitmap();
|
||||
|
||||
// Initialize the first "Haiku Software GL Pipe" context
|
||||
beg = time(NULL);
|
||||
fContextID = fContextObj->CreateContext(fBitmap);
|
||||
fContextID = fContextObj->CreateContext(this);
|
||||
end = time(NULL);
|
||||
|
||||
if (fContextID < 0)
|
||||
@ -98,8 +175,6 @@ SoftwareRenderer::~SoftwareRenderer()
|
||||
|
||||
if (fContextObj)
|
||||
delete fContextObj;
|
||||
if (fBitmap)
|
||||
delete fBitmap;
|
||||
}
|
||||
|
||||
|
||||
@ -111,21 +186,19 @@ SoftwareRenderer::LockGL()
|
||||
|
||||
color_space cs = BScreen(GLView()->Window()).ColorSpace();
|
||||
|
||||
BAutolock lock(fInfoLocker);
|
||||
if (fDirectModeEnabled && fInfo != NULL) {
|
||||
fWidth = fInfo->window_bounds.right - fInfo->window_bounds.left;
|
||||
fHeight = fInfo->window_bounds.bottom - fInfo->window_bounds.top;
|
||||
{
|
||||
BAutolock lock(fInfoLocker);
|
||||
if (fDirectModeEnabled && fInfo != NULL) {
|
||||
fWidth = fInfo->window_bounds.right - fInfo->window_bounds.left;
|
||||
fHeight = fInfo->window_bounds.bottom - fInfo->window_bounds.top;
|
||||
}
|
||||
|
||||
fContextObj->Validate(fWidth, fHeight);
|
||||
fColorSpace = cs;
|
||||
}
|
||||
|
||||
if (fBitmap && cs == fColorSpace && fContextObj->Validate(fWidth, fHeight)) {
|
||||
fContextObj->SetCurrentContext(fBitmap, fContextID);
|
||||
return;
|
||||
}
|
||||
|
||||
fColorSpace = cs;
|
||||
|
||||
_AllocateBitmap();
|
||||
fContextObj->SetCurrentContext(fBitmap, fContextID);
|
||||
// do not hold fInfoLocker here to avoid deadlock
|
||||
fContextObj->SetCurrentContext(true, fContextID);
|
||||
}
|
||||
|
||||
|
||||
@ -136,76 +209,54 @@ SoftwareRenderer::UnlockGL()
|
||||
if ((fOptions & BGL_DOUBLE) == 0) {
|
||||
SwapBuffers();
|
||||
}
|
||||
fContextObj->SetCurrentContext(NULL, fContextID);
|
||||
fContextObj->SetCurrentContext(false, fContextID);
|
||||
BGLRenderer::UnlockGL();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SoftwareRenderer::Display(BBitmap *bitmap, BRect *updateRect)
|
||||
{
|
||||
// CALLED();
|
||||
|
||||
if (!fDirectModeEnabled) {
|
||||
// TODO: avoid timeout
|
||||
if (GLView()->LockLooperWithTimeout(1000) == B_OK) {
|
||||
GLView()->DrawBitmap(bitmap, B_ORIGIN);
|
||||
GLView()->UnlockLooper();
|
||||
}
|
||||
} else {
|
||||
BAutolock lock(fInfoLocker);
|
||||
if (fInfo != NULL) {
|
||||
RasBuf32 srcBuf(bitmap);
|
||||
RasBuf32 dstBuf(fInfo);
|
||||
for (uint32 i = 0; i < fInfo->clip_list_count; i++) {
|
||||
clipping_rect *clip = &fInfo->clip_list[i];
|
||||
RasBuf32 dstClip = dstBuf;
|
||||
dstClip.ClipRect(clip->left, clip->top, clip->right + 1, clip->bottom + 1);
|
||||
dstClip.Shift(-fInfo->window_bounds.left, -fInfo->window_bounds.top);
|
||||
dstClip.Blit(srcBuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SoftwareRenderer::SwapBuffers(bool vsync)
|
||||
{
|
||||
// CALLED();
|
||||
if (!fBitmap)
|
||||
return;
|
||||
|
||||
BScreen screen(GLView()->Window());
|
||||
|
||||
fContextObj->SwapBuffers(fContextID);
|
||||
|
||||
BAutolock lock(fInfoLocker);
|
||||
|
||||
if (!fDirectModeEnabled || fInfo == NULL) {
|
||||
if (GLView()->LockLooperWithTimeout(1000) == B_OK) {
|
||||
GLView()->DrawBitmap(fBitmap, B_ORIGIN);
|
||||
GLView()->UnlockLooper();
|
||||
if (vsync)
|
||||
screen.WaitForRetrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// check the bitmap size still matches the size
|
||||
if (fInfo->window_bounds.bottom - fInfo->window_bounds.top
|
||||
!= fBitmap->Bounds().IntegerHeight()
|
||||
|| fInfo->window_bounds.right - fInfo->window_bounds.left
|
||||
!= fBitmap->Bounds().IntegerWidth()) {
|
||||
ERROR("%s: Bitmap size doesn't match size!\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 bytesPerRow = fBitmap->BytesPerRow();
|
||||
uint8 bytesPerPixel = bytesPerRow / fBitmap->Bounds().IntegerWidth();
|
||||
|
||||
for (uint32 i = 0; i < fInfo->clip_list_count; i++) {
|
||||
clipping_rect *clip = &fInfo->clip_list[i];
|
||||
int32 height = clip->bottom - clip->top + 1;
|
||||
int32 bytesWidth
|
||||
= (clip->right - clip->left + 1) * bytesPerPixel;
|
||||
bytesWidth -= bytesPerPixel;
|
||||
uint8 *p = (uint8 *)fInfo->bits + clip->top
|
||||
* fInfo->bytes_per_row + clip->left * bytesPerPixel;
|
||||
uint8 *b = (uint8 *)fBitmap->Bits()
|
||||
+ (clip->top - fInfo->window_bounds.top) * bytesPerRow
|
||||
+ (clip->left - fInfo->window_bounds.left) * bytesPerPixel;
|
||||
|
||||
for (int y = 0; y < height - 1; y++) {
|
||||
memcpy(p, b, bytesWidth);
|
||||
p += fInfo->bytes_per_row;
|
||||
b += bytesPerRow;
|
||||
}
|
||||
}
|
||||
|
||||
fContextObj->Validate(fWidth, fHeight);
|
||||
if (vsync)
|
||||
screen.WaitForRetrace();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SoftwareRenderer::Draw(BRect updateRect)
|
||||
{
|
||||
// CALLED();
|
||||
if ((!fDirectModeEnabled || fInfo == NULL) && fBitmap)
|
||||
GLView()->DrawBitmap(fBitmap, updateRect, updateRect);
|
||||
fContextObj->Draw(fContextID, updateRect);
|
||||
}
|
||||
|
||||
|
||||
@ -213,41 +264,9 @@ status_t
|
||||
SoftwareRenderer::CopyPixelsOut(BPoint location, BBitmap *bitmap)
|
||||
{
|
||||
CALLED();
|
||||
color_space scs = fBitmap->ColorSpace();
|
||||
color_space dcs = bitmap->ColorSpace();
|
||||
|
||||
if (scs != dcs && (scs != B_RGBA32 || dcs != B_RGB32)) {
|
||||
ERROR("%s::CopyPixelsOut(): incompatible color space: %s != %s\n",
|
||||
__PRETTY_FUNCTION__, color_space_name(scs), color_space_name(dcs));
|
||||
return B_BAD_TYPE;
|
||||
}
|
||||
|
||||
BRect sr = fBitmap->Bounds();
|
||||
BRect dr = bitmap->Bounds();
|
||||
|
||||
// int32 w1 = sr.IntegerWidth();
|
||||
// int32 h1 = sr.IntegerHeight();
|
||||
// int32 w2 = dr.IntegerWidth();
|
||||
// int32 h2 = dr.IntegerHeight();
|
||||
|
||||
sr = sr & dr.OffsetBySelf(location);
|
||||
dr = sr.OffsetByCopy(-location.x, -location.y);
|
||||
|
||||
uint8 *ps = (uint8 *) fBitmap->Bits();
|
||||
uint8 *pd = (uint8 *) bitmap->Bits();
|
||||
uint32 *s, *d;
|
||||
uint32 y;
|
||||
for (y = (uint32) sr.top; y <= (uint32) sr.bottom; y++) {
|
||||
s = (uint32 *)(ps + y * fBitmap->BytesPerRow());
|
||||
s += (uint32) sr.left;
|
||||
|
||||
d = (uint32 *)(pd + (y + (uint32)(dr.top - sr.top))
|
||||
* bitmap->BytesPerRow());
|
||||
d += (uint32) dr.left;
|
||||
memcpy(d, s, dr.IntegerWidth() * 4);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
// TODO: implement
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@ -256,40 +275,8 @@ SoftwareRenderer::CopyPixelsIn(BBitmap *bitmap, BPoint location)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
color_space sourceCS = bitmap->ColorSpace();
|
||||
color_space destinationCS = fBitmap->ColorSpace();
|
||||
|
||||
if (sourceCS != destinationCS
|
||||
&& (sourceCS != B_RGB32 || destinationCS != B_RGBA32)) {
|
||||
ERROR("%s::CopyPixelsIn(): incompatible color space: %s != %s\n",
|
||||
__PRETTY_FUNCTION__, color_space_name(sourceCS),
|
||||
color_space_name(destinationCS));
|
||||
return B_BAD_TYPE;
|
||||
}
|
||||
|
||||
BRect sr = bitmap->Bounds();
|
||||
BRect dr = fBitmap->Bounds();
|
||||
|
||||
sr = sr & dr.OffsetBySelf(location);
|
||||
dr = sr.OffsetByCopy(-location.x, -location.y);
|
||||
|
||||
uint8 *ps = (uint8 *) bitmap->Bits();
|
||||
uint8 *pd = (uint8 *) fBitmap->Bits();
|
||||
uint32 *s, *d;
|
||||
uint32 y;
|
||||
|
||||
for (y = (uint32) sr.top; y <= (uint32) sr.bottom; y++) {
|
||||
s = (uint32 *)(ps + y * bitmap->BytesPerRow());
|
||||
s += (uint32) sr.left;
|
||||
|
||||
d = (uint32 *)(pd + (y + (uint32)(dr.top - sr.top))
|
||||
* fBitmap->BytesPerRow());
|
||||
d += (uint32) dr.left;
|
||||
|
||||
memcpy(d, s, dr.IntegerWidth() * 4);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
// TODO: implement
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@ -327,36 +314,3 @@ SoftwareRenderer::FrameResized(float width, float height)
|
||||
fWidth = (GLuint)width;
|
||||
fHeight = (GLuint)height;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SoftwareRenderer::_AllocateBitmap()
|
||||
{
|
||||
// CALLED();
|
||||
|
||||
// allocate new size of back buffer bitmap
|
||||
BAutolock lock(fInfoLocker);
|
||||
if (fBitmap)
|
||||
delete fBitmap;
|
||||
|
||||
if (fWidth < 1 || fHeight < 1) {
|
||||
TRACE("%s: Can't allocate bitmap of %dx%d\n", __func__,
|
||||
fWidth, fHeight);
|
||||
return;
|
||||
}
|
||||
BRect rect(0.0, 0.0, fWidth, fHeight);
|
||||
fBitmap = new (std::nothrow) BBitmap(rect, fColorSpace);
|
||||
if (fBitmap == NULL) {
|
||||
TRACE("%s: Can't create bitmap!\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
TRACE("%s: New bitmap size: %" B_PRId32 " x %" B_PRId32 "\n", __func__,
|
||||
fBitmap->Bounds().IntegerWidth(), fBitmap->Bounds().IntegerHeight());
|
||||
|
||||
#if 0
|
||||
// debug..
|
||||
void *data = fBitmap->Bits();
|
||||
memset(data, 0xcc, fBitmap->BitsLength());
|
||||
#endif
|
||||
}
|
||||
|
@ -18,37 +18,34 @@
|
||||
#include "GalliumContext.h"
|
||||
|
||||
|
||||
class SoftwareRenderer : public BGLRenderer {
|
||||
class SoftwareRenderer : public BGLRenderer, public HGLWinsysContext {
|
||||
public:
|
||||
SoftwareRenderer(BGLView *view,
|
||||
ulong bgl_options,
|
||||
BGLDispatcher *dispatcher);
|
||||
ulong bgl_options);
|
||||
virtual ~SoftwareRenderer();
|
||||
|
||||
virtual void LockGL();
|
||||
virtual void UnlockGL();
|
||||
void LockGL();
|
||||
void UnlockGL();
|
||||
|
||||
virtual void SwapBuffers(bool vsync = false);
|
||||
virtual void Draw(BRect updateRect);
|
||||
virtual status_t CopyPixelsOut(BPoint source, BBitmap *dest);
|
||||
virtual status_t CopyPixelsIn(BBitmap *source, BPoint dest);
|
||||
virtual void FrameResized(float width, float height);
|
||||
void Display(BBitmap* bitmap, BRect* updateRect);
|
||||
|
||||
virtual void EnableDirectMode(bool enabled);
|
||||
virtual void DirectConnected(direct_buffer_info *info);
|
||||
void SwapBuffers(bool vsync = false);
|
||||
void Draw(BRect updateRect);
|
||||
status_t CopyPixelsOut(BPoint source, BBitmap *dest);
|
||||
status_t CopyPixelsIn(BBitmap *source, BPoint dest);
|
||||
void FrameResized(float width, float height);
|
||||
|
||||
void EnableDirectMode(bool enabled);
|
||||
void DirectConnected(direct_buffer_info *info);
|
||||
|
||||
private:
|
||||
|
||||
void _AllocateBitmap();
|
||||
|
||||
GalliumContext* fContextObj;
|
||||
BBitmap* fBitmap;
|
||||
context_id fContextID;
|
||||
|
||||
bool fDirectModeEnabled;
|
||||
direct_buffer_info* fInfo;
|
||||
BLocker fInfoLocker;
|
||||
ulong fOptions;
|
||||
ulong fOptions;
|
||||
GLuint fWidth;
|
||||
GLuint fHeight;
|
||||
color_space fColorSpace;
|
||||
|
@ -37,9 +37,10 @@
|
||||
#include "frontend/api.h"
|
||||
#include "frontend/sw_winsys.h"
|
||||
|
||||
#include "bitmap_wrapper.h"
|
||||
#include "hgl_sw_winsys.h"
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <OS.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
# define TRACE(x...) printf("hgl:winsys: " x)
|
||||
@ -63,6 +64,7 @@ struct haiku_displaytarget
|
||||
unsigned size;
|
||||
|
||||
void* data;
|
||||
BBitmap* bitmap;
|
||||
};
|
||||
|
||||
|
||||
@ -126,10 +128,18 @@ hgl_winsys_displaytarget_create(struct sw_winsys* winsys,
|
||||
haikuDisplayTarget->stride = align(formatStride, alignment);
|
||||
haikuDisplayTarget->size = haikuDisplayTarget->stride * blockSize;
|
||||
|
||||
haikuDisplayTarget->data
|
||||
= align_malloc(haikuDisplayTarget->size, alignment);
|
||||
if (textureUsage & PIPE_BIND_DISPLAY_TARGET) {
|
||||
haikuDisplayTarget->data = NULL;
|
||||
haikuDisplayTarget->bitmap = new BBitmap(
|
||||
BRect(0, 0, width - 1, height - 1),
|
||||
haikuDisplayTarget->colorSpace,
|
||||
haikuDisplayTarget->stride);
|
||||
} else {
|
||||
haikuDisplayTarget->data
|
||||
= align_malloc(haikuDisplayTarget->size, alignment);
|
||||
|
||||
assert(haikuDisplayTarget->data);
|
||||
haikuDisplayTarget->bitmap = NULL;
|
||||
}
|
||||
|
||||
*stride = haikuDisplayTarget->stride;
|
||||
|
||||
@ -151,6 +161,9 @@ hgl_winsys_displaytarget_destroy(struct sw_winsys* winsys,
|
||||
if (haikuDisplayTarget->data != NULL)
|
||||
align_free(haikuDisplayTarget->data);
|
||||
|
||||
if (haikuDisplayTarget->bitmap != NULL)
|
||||
delete haikuDisplayTarget->bitmap;
|
||||
|
||||
FREE(haikuDisplayTarget);
|
||||
}
|
||||
|
||||
@ -179,13 +192,16 @@ hgl_winsys_displaytarget_map(struct sw_winsys* winsys,
|
||||
struct haiku_displaytarget* haikuDisplayTarget
|
||||
= hgl_sw_displaytarget(displayTarget);
|
||||
|
||||
if (haikuDisplayTarget->bitmap != NULL)
|
||||
return haikuDisplayTarget->bitmap->Bits();
|
||||
|
||||
return haikuDisplayTarget->data;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hgl_winsys_displaytarget_unmap(struct sw_winsys* winsys,
|
||||
struct sw_displaytarget* disptarget)
|
||||
struct sw_displaytarget* displayTarget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -198,19 +214,11 @@ hgl_winsys_displaytarget_display(struct sw_winsys* winsys,
|
||||
{
|
||||
assert(contextPrivate);
|
||||
|
||||
Bitmap* bitmap = (Bitmap*)contextPrivate;
|
||||
|
||||
struct haiku_displaytarget* haikuDisplayTarget
|
||||
= hgl_sw_displaytarget(displayTarget);
|
||||
|
||||
import_bitmap_bits(bitmap, haikuDisplayTarget->data,
|
||||
haikuDisplayTarget->size, haikuDisplayTarget->stride,
|
||||
haikuDisplayTarget->colorSpace);
|
||||
|
||||
// Dump the rendered bitmap to disk for debugging
|
||||
//dump_bitmap(bitmap);
|
||||
|
||||
return;
|
||||
HGLWinsysContext *context = (HGLWinsysContext*)contextPrivate;
|
||||
context->Display(haikuDisplayTarget->bitmap, NULL);
|
||||
}
|
||||
|
||||
|
||||
@ -221,7 +229,7 @@ hgl_create_sw_winsys()
|
||||
|
||||
if (!winsys)
|
||||
return NULL;
|
||||
|
||||
|
||||
// Attach winsys hooks for Haiku
|
||||
winsys->destroy = hgl_winsys_destroy;
|
||||
winsys->is_displaytarget_format_supported
|
@ -27,6 +27,16 @@
|
||||
#ifndef _HGL_SOFTWAREWINSYS_H
|
||||
#define _HGL_SOFTWAREWINSYS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
class BBitmap;
|
||||
class BRect;
|
||||
|
||||
class HGLWinsysContext {
|
||||
public:
|
||||
virtual void Display(BBitmap *bitmap, BRect *updateRect) = 0;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
libswhgl = static_library(
|
||||
'swhgl',
|
||||
files('hgl_sw_winsys.c'),
|
||||
files('hgl_sw_winsys.cpp'),
|
||||
gnu_symbol_visibility : 'hidden',
|
||||
include_directories : [inc_gallium, inc_include, inc_src, inc_gallium_aux,
|
||||
include_directories('../../../frontends/hgl')
|
||||
|
@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* Copyright 2000-2015 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>
|
||||
*/
|
||||
|
||||
|
||||
#include "glapi/glapi.h"
|
||||
#include "glapi/glapi_priv.h"
|
||||
|
||||
|
||||
extern "C" {
|
||||
/*
|
||||
* 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::SetTable(struct _glapi_table* table)
|
||||
{
|
||||
_glapi_set_dispatch(table);
|
||||
return B_OK;
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
/*
|
||||
* Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* Copyright 2000-2015 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 "main/glheader.h"
|
||||
|
||||
#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 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
|
@ -8,23 +8,18 @@
|
||||
|
||||
#include "GLRenderer.h"
|
||||
|
||||
#include "GLDispatcher.h"
|
||||
|
||||
|
||||
BGLRenderer::BGLRenderer(BGLView* view, ulong glOptions,
|
||||
BGLDispatcher* dispatcher)
|
||||
BGLRenderer::BGLRenderer(BGLView* view, ulong glOptions)
|
||||
:
|
||||
fRefCount(1),
|
||||
fView(view),
|
||||
fOptions(glOptions),
|
||||
fDispatcher(dispatcher)
|
||||
fOptions(glOptions)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BGLRenderer::~BGLRenderer()
|
||||
{
|
||||
delete fDispatcher;
|
||||
}
|
||||
|
||||
|
||||
@ -38,7 +33,7 @@ BGLRenderer::Acquire()
|
||||
void
|
||||
BGLRenderer::Release()
|
||||
{
|
||||
if (atomic_add(&fRefCount, -1) < 1)
|
||||
if (atomic_add(&fRefCount, -1) <= 1)
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
@ -12,28 +12,34 @@
|
||||
#include <image.h>
|
||||
|
||||
#include <kernel/image.h>
|
||||
#include <system/safemode_defs.h>
|
||||
#include <private/system/safemode_defs.h>
|
||||
|
||||
#include <Directory.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <Path.h>
|
||||
#include <strings.h>
|
||||
#include "GLDispatcher.h"
|
||||
#include "GLRendererRoster.h"
|
||||
|
||||
#include <new>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
extern "C" status_t _kern_get_safemode_option(const char* parameter,
|
||||
char* buffer, size_t* _bufferSize);
|
||||
|
||||
GLRendererRoster *GLRendererRoster::fInstance = NULL;
|
||||
|
||||
GLRendererRoster::GLRendererRoster(BGLView* view, ulong options)
|
||||
GLRendererRoster *GLRendererRoster::Roster()
|
||||
{
|
||||
if (fInstance == NULL) {
|
||||
fInstance = new GLRendererRoster();
|
||||
}
|
||||
return fInstance;
|
||||
}
|
||||
|
||||
GLRendererRoster::GLRendererRoster()
|
||||
:
|
||||
fNextID(0),
|
||||
fView(view),
|
||||
fOptions(options),
|
||||
fSafeMode(false),
|
||||
fABISubDirectory(NULL)
|
||||
{
|
||||
@ -84,14 +90,19 @@ GLRendererRoster::~GLRendererRoster()
|
||||
|
||||
|
||||
BGLRenderer*
|
||||
GLRendererRoster::GetRenderer(int32 id)
|
||||
GLRendererRoster::GetRenderer(BGLView *view, ulong options)
|
||||
{
|
||||
RendererMap::const_iterator iterator = fRenderers.find(id);
|
||||
if (iterator == fRenderers.end())
|
||||
return NULL;
|
||||
|
||||
struct renderer_item item = iterator->second;
|
||||
return item.renderer;
|
||||
for (
|
||||
RendererMap::const_iterator iterator = fRenderers.begin();
|
||||
iterator != fRenderers.end();
|
||||
iterator++
|
||||
) {
|
||||
renderer_item item = *iterator;
|
||||
BGLRenderer* renderer;
|
||||
renderer = item.entry(view, options);
|
||||
return renderer;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -102,6 +113,7 @@ GLRendererRoster::AddDefaultPaths()
|
||||
const directory_which paths[] = {
|
||||
B_USER_NONPACKAGED_ADDONS_DIRECTORY,
|
||||
B_USER_ADDONS_DIRECTORY,
|
||||
B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY,
|
||||
B_SYSTEM_ADDONS_DIRECTORY,
|
||||
};
|
||||
|
||||
@ -162,24 +174,22 @@ GLRendererRoster::AddPath(const char* path)
|
||||
|
||||
|
||||
status_t
|
||||
GLRendererRoster::AddRenderer(BGLRenderer* renderer,
|
||||
GLRendererRoster::AddRenderer(InstantiateRenderer entry,
|
||||
image_id image, const entry_ref* ref, ino_t node)
|
||||
{
|
||||
renderer_item item;
|
||||
item.renderer = renderer;
|
||||
item.entry = entry;
|
||||
item.image = image;
|
||||
item.node = node;
|
||||
if (ref != NULL)
|
||||
item.ref = *ref;
|
||||
|
||||
try {
|
||||
fRenderers[fNextID] = item;
|
||||
fRenderers.push_back(item);
|
||||
} catch (...) {
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
renderer->fOwningRoster = this;
|
||||
renderer->fID = fNextID++;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -194,30 +204,29 @@ GLRendererRoster::CreateRenderer(const entry_ref& ref)
|
||||
return status;
|
||||
|
||||
BPath path(&ref);
|
||||
printf("OpenGL load add-on: %s\n", path.Path());
|
||||
|
||||
image_id image = load_add_on(path.Path());
|
||||
if (image < B_OK)
|
||||
return image;
|
||||
|
||||
BGLRenderer* (*instantiate_renderer)
|
||||
(BGLView* view, ulong options, BGLDispatcher* dispatcher);
|
||||
InstantiateRenderer instantiate_renderer;
|
||||
|
||||
status = get_image_symbol(
|
||||
image, "instantiate_gl_renderer",
|
||||
B_SYMBOL_TYPE_TEXT, (void**)&instantiate_renderer
|
||||
);
|
||||
|
||||
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
|
||||
if ((status = AddRenderer(instantiate_renderer, image, &ref, nodeRef.node)) != B_OK) {
|
||||
unload_add_on(image);
|
||||
return status;
|
||||
}
|
||||
printf("OpenGL add-on registered: %s\n", path.Path());
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
printf("OpenGL add-on failed to instantiate: %s\n", path.Path());
|
||||
unload_add_on(image);
|
||||
|
||||
return status;
|
||||
|
@ -9,42 +9,43 @@
|
||||
#define _GLRENDERER_ROSTER_H
|
||||
|
||||
|
||||
#include "GLRenderer.h"
|
||||
#include <GLRenderer.h>
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
|
||||
typedef BGLRenderer* (*InstantiateRenderer) (BGLView* view, ulong options);
|
||||
|
||||
struct renderer_item {
|
||||
BGLRenderer* renderer;
|
||||
InstantiateRenderer entry;
|
||||
entry_ref ref;
|
||||
ino_t node;
|
||||
image_id image;
|
||||
};
|
||||
|
||||
typedef std::map<renderer_id, renderer_item> RendererMap;
|
||||
typedef std::vector<renderer_item> RendererMap;
|
||||
|
||||
|
||||
class GLRendererRoster {
|
||||
public:
|
||||
GLRendererRoster(BGLView* view, ulong options);
|
||||
virtual ~GLRendererRoster();
|
||||
|
||||
BGLRenderer* GetRenderer(int32 id = 0);
|
||||
static GLRendererRoster *Roster();
|
||||
BGLRenderer* GetRenderer(BGLView *view, ulong options);
|
||||
|
||||
private:
|
||||
GLRendererRoster();
|
||||
virtual ~GLRendererRoster();
|
||||
|
||||
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 AddRenderer(InstantiateRenderer entry, 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;
|
||||
static GLRendererRoster* fInstance;
|
||||
bool fSafeMode;
|
||||
const char* fABISubDirectory;
|
||||
|
||||
RendererMap fRenderers;
|
||||
};
|
||||
|
||||
|
||||
|
@ -20,10 +20,10 @@
|
||||
#include <DirectWindow.h>
|
||||
#include "GLRenderer.h"
|
||||
|
||||
#include "interface/DirectWindowPrivate.h"
|
||||
#include "GLDispatcher.h"
|
||||
#include <private/interface/DirectWindowPrivate.h>
|
||||
#include "GLRendererRoster.h"
|
||||
|
||||
#include "glapi/glapi.h"
|
||||
|
||||
struct glview_direct_info {
|
||||
direct_buffer_info* direct_info;
|
||||
@ -39,7 +39,6 @@ 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),
|
||||
@ -47,11 +46,9 @@ BGLView::BGLView(BRect rect, const char* name, ulong resizingMode, ulong mode,
|
||||
fDisplayLock("BGLView display lock"),
|
||||
fClipInfo(NULL),
|
||||
fRenderer(NULL),
|
||||
fRoster(NULL),
|
||||
fDitherMap(NULL)
|
||||
{
|
||||
fRoster = new GLRendererRoster(this, options);
|
||||
fRenderer = fRoster->GetRenderer();
|
||||
fRenderer = GLRendererRoster::Roster()->GetRenderer(this, options);
|
||||
}
|
||||
|
||||
|
||||
@ -77,6 +74,15 @@ BGLView::LockGL()
|
||||
void
|
||||
BGLView::UnlockGL()
|
||||
{
|
||||
thread_id lockerThread = fDisplayLock.LockingThread();
|
||||
thread_id callerThread = find_thread(NULL);
|
||||
|
||||
if (lockerThread != B_ERROR && lockerThread != callerThread) {
|
||||
printf("UnlockGL is called from wrong thread, lockerThread: %d, callerThread: %d\n",
|
||||
(int)lockerThread, (int)callerThread);
|
||||
debugger("[!]");
|
||||
}
|
||||
|
||||
if (fRenderer != NULL && fDisplayLock.CountLocks() == 1)
|
||||
fRenderer->UnlockGL();
|
||||
fDisplayLock.Unlock();
|
||||
@ -113,15 +119,7 @@ BGLView::EmbeddedView()
|
||||
void*
|
||||
BGLView::GetGLProcAddress(const char* procName)
|
||||
{
|
||||
BGLDispatcher* glDispatcher = NULL;
|
||||
|
||||
if (fRenderer)
|
||||
glDispatcher = fRenderer->GLDispatcher();
|
||||
|
||||
if (glDispatcher)
|
||||
return (void*)glDispatcher->AddressOf(procName);
|
||||
|
||||
return NULL;
|
||||
return (void*)_glapi_get_proc_address(procName);
|
||||
}
|
||||
|
||||
|
||||
@ -170,9 +168,8 @@ void
|
||||
BGLView::Draw(BRect updateRect)
|
||||
{
|
||||
if (fRenderer) {
|
||||
_LockDraw();
|
||||
fRenderer->Draw(updateRect);
|
||||
_UnlockDraw();
|
||||
if (!fClipInfo || !fClipInfo->enable_direct_mode)
|
||||
fRenderer->Draw(updateRect);
|
||||
return;
|
||||
}
|
||||
// TODO: auto-size and center the string
|
||||
@ -237,10 +234,6 @@ BGLView::AllAttached()
|
||||
void
|
||||
BGLView::DetachedFromWindow()
|
||||
{
|
||||
if (fRenderer)
|
||||
fRenderer->Release();
|
||||
fRenderer = NULL;
|
||||
|
||||
BView::DetachedFromWindow();
|
||||
}
|
||||
|
||||
@ -260,12 +253,9 @@ BGLView::FrameResized(float width, float height)
|
||||
v->ConvertToParent(&fBounds);
|
||||
|
||||
if (fRenderer) {
|
||||
LockGL();
|
||||
_LockDraw();
|
||||
_CallDirectConnected();
|
||||
//_LockDraw();
|
||||
fRenderer->FrameResized(width, height);
|
||||
_UnlockDraw();
|
||||
UnlockGL();
|
||||
//_UnlockDraw();
|
||||
}
|
||||
|
||||
BView::FrameResized(width, height);
|
||||
@ -342,6 +332,7 @@ BGLView::GetSupportedSuites(BMessage* data)
|
||||
void
|
||||
BGLView::DirectConnected(direct_buffer_info* info)
|
||||
{
|
||||
printf("BGLView::DirectConnected\n");
|
||||
if (fClipInfo == NULL) {
|
||||
fClipInfo = new (std::nothrow) glview_direct_info();
|
||||
if (fClipInfo == NULL)
|
||||
@ -350,33 +341,33 @@ BGLView::DirectConnected(direct_buffer_info* info)
|
||||
|
||||
direct_buffer_info* localInfo = fClipInfo->direct_info;
|
||||
|
||||
_LockDraw();
|
||||
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();
|
||||
|
||||
_UnlockDraw();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BGLView::EnableDirectMode(bool enabled)
|
||||
{
|
||||
printf("BGLView::EnableDirectMode: %d\n", (int)enabled);
|
||||
if (fRenderer)
|
||||
fRenderer->EnableDirectMode(enabled);
|
||||
if (fClipInfo == NULL) {
|
||||
@ -412,8 +403,10 @@ BGLView::_UnlockDraw()
|
||||
void
|
||||
BGLView::_CallDirectConnected()
|
||||
{
|
||||
if (!fClipInfo)
|
||||
if (!fClipInfo || !fClipInfo->direct_connected) {
|
||||
fRenderer->DirectConnected(NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
direct_buffer_info* localInfo = fClipInfo->direct_info;
|
||||
direct_buffer_info* info = (direct_buffer_info*)malloc(
|
||||
@ -472,10 +465,9 @@ BGLView::BGLView(BRect rect, char* name, ulong resizingMode, ulong mode,
|
||||
fDisplayLock("BGLView display lock"),
|
||||
fClipInfo(NULL),
|
||||
fRenderer(NULL),
|
||||
fRoster(NULL),
|
||||
fDitherMap(NULL)
|
||||
{
|
||||
fRoster = new GLRendererRoster(this, options);
|
||||
fRenderer = GLRendererRoster::Roster()->GetRenderer(this, options);
|
||||
}
|
||||
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
libgl = shared_library(
|
||||
'GL',
|
||||
files(
|
||||
'GLView.cpp', 'GLRenderer.cpp', 'GLRendererRoster.cpp', 'GLDispatcher.cpp',
|
||||
'GLView.cpp', 'GLRenderer.cpp', 'GLRendererRoster.cpp',
|
||||
),
|
||||
link_args : [ld_args_bsymbolic, ld_args_gc_sections],
|
||||
include_directories : [
|
||||
|
Loading…
x
Reference in New Issue
Block a user