BGLRenderer & operator=(const BGLRenderer &);
public:
- BGLRenderer(BGLView *view, ulong bgl_options,
- BGLDispatcher *dispatcher);
+ BGLRenderer(BGLView *view, ulong bgl_options);
virtual ~BGLRenderer();
void Acquire();
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;
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
#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
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;
}
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);
}
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 (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 (((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;
+ 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;
+ }
}
}
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++)
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++)
* 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);
// 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;
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;
}
-struct st_api*
-hgl_create_st_api()
-{
- CALLED();
- return st_gl_api_create();
-}
-
-
-struct st_manager *
-hgl_create_st_manager(struct hgl_context* context)
+void
+hgl_destroy_st_framebuffer(struct hgl_buffer *buffer)
{
- struct st_manager* manager;
-
CALLED();
- // Required things
- assert(context);
- assert(context->screen);
-
- manager = CALLOC_STRUCT(st_manager);
- assert(manager);
+ int i;
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
+ pipe_resource_reference(&buffer->textures[i], NULL);
- //manager->display = dpy;
- manager->screen = context->screen;
- manager->get_param = hgl_st_manager_get_param;
- manager->st_manager_private = (void *)context;
-
- return manager;
+ FREE(buffer->stfbi);
+ FREE(buffer);
}
-void
-hgl_destroy_st_manager(struct st_manager *manager)
+struct st_api*
+hgl_create_st_api()
{
CALLED();
-
- FREE(manager);
+ return st_gl_api_create();
}
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;
}
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);
+}
#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"
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_context
+struct hgl_display
{
+ mtx_t mutex;
+
struct st_api* api;
- // API
struct st_manager* manager;
- // Manager
- struct st_context_iface* st;
- // Interface Object
- struct st_visual* stVisual;
- // Visual
+};
- struct pipe_screen* screen;
- //struct pipe_resource* textures[ST_ATTACHMENT_COUNT];
+struct hgl_context
+{
+ struct hgl_display* display;
+ struct st_context_iface* st;
+ struct st_visual* stVisual;
// Post processing
struct pp_queue_t* postProcess;
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
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);
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
}
#include "GalliumContext.h"
#include <stdio.h>
+#include <algorithm>
#include "GLView.h"
#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();
for (context_id i = 0; i < CONTEXT_MAX; i++)
fContext[i] = NULL;
- CreateScreen();
+ CreateDisplay();
(void) mtx_init(&fMutex, mtx_plain);
}
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();
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();
}
// 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;
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",
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,
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);
}
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();
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;
}
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;
}
CALLED();
Lock();
- struct hgl_context *context = fContext[contextID];
- Unlock();
+ struct hgl_context* context = fContext[contextID];
if (!context) {
ERROR("%s: context not found\n", __func__);
+ Unlock();
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__);
- return B_ERROR;
- }
+ // will flush front buffer if no double buffering is used
+ context->st->flush(context->st, ST_FLUSH_FRONT, NULL, NULL, NULL);
- fScreen->flush_frontbuffer(fScreen, context->st->pipe, surface->texture, 0, 0,
- context->bitmap, 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;
}
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);
}
#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:
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;
};
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"),
{
CALLED();
- // Disable double buffer for the moment.
- //options &= ~BGL_DOUBLE;
-
// Initialize the "Haiku Software GL Pipe"
time_t beg;
time_t end;
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));
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)
if (fContextObj)
delete fContextObj;
- if (fBitmap)
- delete fBitmap;
}
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;
+ }
- if (fBitmap && cs == fColorSpace && fContextObj->Validate(fWidth, fHeight)) {
- fContextObj->SetCurrentContext(fBitmap, fContextID);
- return;
+ fContextObj->Validate(fWidth, fHeight);
+ fColorSpace = cs;
}
- fColorSpace = cs;
-
- _AllocateBitmap();
- fContextObj->SetCurrentContext(fBitmap, fContextID);
+ // do not hold fInfoLocker here to avoid deadlock
+ fContextObj->SetCurrentContext(true, fContextID);
}
if ((fOptions & BGL_DOUBLE) == 0) {
SwapBuffers();
}
- fContextObj->SetCurrentContext(NULL, fContextID);
+ fContextObj->SetCurrentContext(false, fContextID);
BGLRenderer::UnlockGL();
}
void
-SoftwareRenderer::SwapBuffers(bool vsync)
+SoftwareRenderer::Display(BBitmap *bitmap, BRect *updateRect)
{
// CALLED();
- if (!fBitmap)
- return;
-
- BScreen screen(GLView()->Window());
- fContextObj->SwapBuffers(fContextID);
-
- BAutolock lock(fInfoLocker);
-
- if (!fDirectModeEnabled || fInfo == NULL) {
+ if (!fDirectModeEnabled) {
+ // TODO: avoid timeout
if (GLView()->LockLooperWithTimeout(1000) == B_OK) {
- GLView()->DrawBitmap(fBitmap, B_ORIGIN);
+ GLView()->DrawBitmap(bitmap, 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;
+ } 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)
+{
+ BScreen screen(GLView()->Window());
+ fContextObj->SwapBuffers(fContextID);
+ 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);
}
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;
}
{
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;
}
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
-}
#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);
-private:
-
- void _AllocateBitmap();
+ void EnableDirectMode(bool enabled);
+ void DirectConnected(direct_buffer_info *info);
+private:
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;
#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)
unsigned size;
void* data;
+ BBitmap* bitmap;
};
haikuDisplayTarget->stride = align(formatStride, alignment);
haikuDisplayTarget->size = haikuDisplayTarget->stride * blockSize;
- haikuDisplayTarget->data
- = align_malloc(haikuDisplayTarget->size, alignment);
-
- assert(haikuDisplayTarget->data);
+ 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);
+
+ haikuDisplayTarget->bitmap = NULL;
+ }
*stride = haikuDisplayTarget->stride;
if (haikuDisplayTarget->data != NULL)
align_free(haikuDisplayTarget->data);
+ if (haikuDisplayTarget->bitmap != NULL)
+ delete haikuDisplayTarget->bitmap;
+
FREE(haikuDisplayTarget);
}
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;
}
{
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);
}
if (!winsys)
return NULL;
-
+
// Attach winsys hooks for Haiku
winsys->destroy = hgl_winsys_destroy;
winsys->is_displaytarget_format_supported
#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
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')
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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
#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;
}
void
BGLRenderer::Release()
{
- if (atomic_add(&fRefCount, -1) < 1)
+ if (atomic_add(&fRefCount, -1) <= 1)
delete this;
}
#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)
{
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;
}
const directory_which paths[] = {
B_USER_NONPACKAGED_ADDONS_DIRECTORY,
B_USER_ADDONS_DIRECTORY,
+ B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY,
B_SYSTEM_ADDONS_DIRECTORY,
};
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;
}
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);
- if (status == B_OK) {
- BGLRenderer* renderer
- = instantiate_renderer(fView, fOptions, new BGLDispatcher());
- if (!renderer) {
- unload_add_on(image);
- return B_UNSUPPORTED;
- }
+ status = get_image_symbol(
+ image, "instantiate_gl_renderer",
+ B_SYMBOL_TYPE_TEXT, (void**)&instantiate_renderer
+ );
- if (AddRenderer(renderer, image, &ref, nodeRef.node) != B_OK) {
- renderer->Release();
- // this will delete the renderer
+ if (status == B_OK) {
+ 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;
#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;
};
#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;
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),
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);
}
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();
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);
}
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
void
BGLView::DetachedFromWindow()
{
- if (fRenderer)
- fRenderer->Release();
- fRenderer = NULL;
-
BView::DetachedFromWindow();
}
v->ConvertToParent(&fBounds);
if (fRenderer) {
- LockGL();
- _LockDraw();
- _CallDirectConnected();
+ //_LockDraw();
fRenderer->FrameResized(width, height);
- _UnlockDraw();
- UnlockGL();
+ //_UnlockDraw();
}
BView::FrameResized(width, height);
void
BGLView::DirectConnected(direct_buffer_info* info)
{
+ printf("BGLView::DirectConnected\n");
if (fClipInfo == NULL) {
fClipInfo = new (std::nothrow) glview_direct_info();
if (fClipInfo == NULL)
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) {
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(
fDisplayLock("BGLView display lock"),
fClipInfo(NULL),
fRenderer(NULL),
- fRoster(NULL),
fDitherMap(NULL)
{
- fRoster = new GLRendererRoster(this, options);
+ fRenderer = GLRendererRoster::Roster()->GetRenderer(this, options);
}
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 : [