From 065cf4f91474f65691e2eed6d5011a7c6e43fe99 Mon Sep 17 00:00:00 2001 From: X512 Date: Tue, 5 Jan 2021 00:12:38 -0600 Subject: [PATCH] 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 Part-of: --- include/HaikuGL/GLRenderer.h | 7 +- include/HaikuGL/GLView.h | 25 +- src/gallium/frontends/hgl/hgl.c | 170 +++++----- src/gallium/frontends/hgl/hgl_context.h | 39 +-- .../targets/haiku-softpipe/GalliumContext.cpp | 184 +++++----- .../targets/haiku-softpipe/GalliumContext.h | 18 +- .../haiku-softpipe/SoftwareRenderer.cpp | 318 ++++++++---------- .../targets/haiku-softpipe/SoftwareRenderer.h | 31 +- .../{hgl_sw_winsys.c => hgl_sw_winsys.cpp} | 40 ++- src/gallium/winsys/sw/hgl/hgl_sw_winsys.h | 10 + src/gallium/winsys/sw/hgl/meson.build | 2 +- src/hgl/GLDispatcher.cpp | 65 ---- src/hgl/GLDispatcher.h | 105 ------ src/hgl/GLRenderer.cpp | 11 +- src/hgl/GLRendererRoster.cpp | 73 ++-- src/hgl/GLRendererRoster.h | 29 +- src/hgl/GLView.cpp | 60 ++-- src/hgl/meson.build | 2 +- 18 files changed, 506 insertions(+), 683 deletions(-) rename src/gallium/winsys/sw/hgl/{hgl_sw_winsys.c => hgl_sw_winsys.cpp} (89%) delete mode 100644 src/hgl/GLDispatcher.cpp delete mode 100644 src/hgl/GLDispatcher.h diff --git a/include/HaikuGL/GLRenderer.h b/include/HaikuGL/GLRenderer.h index 166a5fa8ecf..5c9c4daaeb6 100644 --- a/include/HaikuGL/GLRenderer.h +++ b/include/HaikuGL/GLRenderer.h @@ -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 diff --git a/include/HaikuGL/GLView.h b/include/HaikuGL/GLView.h index a1dd944aad5..e733377a7fa 100644 --- a/include/HaikuGL/GLView.h +++ b/include/HaikuGL/GLView.h @@ -12,18 +12,19 @@ #include -#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 diff --git a/src/gallium/frontends/hgl/hgl.c b/src/gallium/frontends/hgl/hgl.c index ee530afbea8..7b13402e2d9 100644 --- a/src/gallium/frontends/hgl/hgl.c +++ b/src/gallium/frontends/hgl/hgl.c @@ -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); +} diff --git a/src/gallium/frontends/hgl/hgl_context.h b/src/gallium/frontends/hgl/hgl_context.h index 4cb452657ae..0b3b53483f7 100644 --- a/src/gallium/frontends/hgl/hgl_context.h +++ b/src/gallium/frontends/hgl/hgl_context.h @@ -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 } diff --git a/src/gallium/targets/haiku-softpipe/GalliumContext.cpp b/src/gallium/targets/haiku-softpipe/GalliumContext.cpp index f84b066b125..15eea948d07 100644 --- a/src/gallium/targets/haiku-softpipe/GalliumContext.cpp +++ b/src/gallium/targets/haiku-softpipe/GalliumContext.cpp @@ -11,6 +11,7 @@ #include "GalliumContext.h" #include +#include #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); } diff --git a/src/gallium/targets/haiku-softpipe/GalliumContext.h b/src/gallium/targets/haiku-softpipe/GalliumContext.h index d8d75b91c06..1947b96c305 100644 --- a/src/gallium/targets/haiku-softpipe/GalliumContext.h +++ b/src/gallium/targets/haiku-softpipe/GalliumContext.h @@ -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; }; diff --git a/src/gallium/targets/haiku-softpipe/SoftwareRenderer.cpp b/src/gallium/targets/haiku-softpipe/SoftwareRenderer.cpp index 18cb1ac2e19..96f19ae0884 100644 --- a/src/gallium/targets/haiku-softpipe/SoftwareRenderer.cpp +++ b/src/gallium/targets/haiku-softpipe/SoftwareRenderer.cpp @@ -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 -} diff --git a/src/gallium/targets/haiku-softpipe/SoftwareRenderer.h b/src/gallium/targets/haiku-softpipe/SoftwareRenderer.h index 10eaef870f3..66ff71c10d1 100644 --- a/src/gallium/targets/haiku-softpipe/SoftwareRenderer.h +++ b/src/gallium/targets/haiku-softpipe/SoftwareRenderer.h @@ -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; diff --git a/src/gallium/winsys/sw/hgl/hgl_sw_winsys.c b/src/gallium/winsys/sw/hgl/hgl_sw_winsys.cpp similarity index 89% rename from src/gallium/winsys/sw/hgl/hgl_sw_winsys.c rename to src/gallium/winsys/sw/hgl/hgl_sw_winsys.cpp index bcbaf9cabe5..564f9f61268 100644 --- a/src/gallium/winsys/sw/hgl/hgl_sw_winsys.c +++ b/src/gallium/winsys/sw/hgl/hgl_sw_winsys.cpp @@ -37,9 +37,10 @@ #include "frontend/api.h" #include "frontend/sw_winsys.h" -#include "bitmap_wrapper.h" #include "hgl_sw_winsys.h" +#include +#include #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 diff --git a/src/gallium/winsys/sw/hgl/hgl_sw_winsys.h b/src/gallium/winsys/sw/hgl/hgl_sw_winsys.h index a81f890826e..d20c1933a30 100644 --- a/src/gallium/winsys/sw/hgl/hgl_sw_winsys.h +++ b/src/gallium/winsys/sw/hgl/hgl_sw_winsys.h @@ -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 diff --git a/src/gallium/winsys/sw/hgl/meson.build b/src/gallium/winsys/sw/hgl/meson.build index ceef11bfebd..81dcf5bb5da 100644 --- a/src/gallium/winsys/sw/hgl/meson.build +++ b/src/gallium/winsys/sw/hgl/meson.build @@ -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') diff --git a/src/hgl/GLDispatcher.cpp b/src/hgl/GLDispatcher.cpp deleted file mode 100644 index f9709e444f9..00000000000 --- a/src/hgl/GLDispatcher.cpp +++ /dev/null @@ -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 - * Philippe Houdoin - * Alexander von Gluck IV - */ - - -#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; -} diff --git a/src/hgl/GLDispatcher.h b/src/hgl/GLDispatcher.h deleted file mode 100644 index 7a4bcd33299..00000000000 --- a/src/hgl/GLDispatcher.h +++ /dev/null @@ -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 - * Philippe Houdoin - */ -#ifndef GLDISPATCHER_H -#define GLDISPATCHER_H - - -#include -#include -#include - -#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 diff --git a/src/hgl/GLRenderer.cpp b/src/hgl/GLRenderer.cpp index 4573a64a35c..af89b4e15eb 100644 --- a/src/hgl/GLRenderer.cpp +++ b/src/hgl/GLRenderer.cpp @@ -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; } diff --git a/src/hgl/GLRendererRoster.cpp b/src/hgl/GLRendererRoster.cpp index 9e5d847a1d7..9bb10498756 100644 --- a/src/hgl/GLRendererRoster.cpp +++ b/src/hgl/GLRendererRoster.cpp @@ -12,28 +12,34 @@ #include #include -#include +#include #include #include #include #include -#include "GLDispatcher.h" #include "GLRendererRoster.h" #include #include +#include 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; diff --git a/src/hgl/GLRendererRoster.h b/src/hgl/GLRendererRoster.h index f0116cc88f9..66abad9d5e2 100644 --- a/src/hgl/GLRendererRoster.h +++ b/src/hgl/GLRendererRoster.h @@ -9,42 +9,43 @@ #define _GLRENDERER_ROSTER_H -#include "GLRenderer.h" +#include -#include +#include +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 RendererMap; +typedef std::vector 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; }; diff --git a/src/hgl/GLView.cpp b/src/hgl/GLView.cpp index 91850db96cf..3462c885494 100644 --- a/src/hgl/GLView.cpp +++ b/src/hgl/GLView.cpp @@ -20,10 +20,10 @@ #include #include "GLRenderer.h" -#include "interface/DirectWindowPrivate.h" -#include "GLDispatcher.h" +#include #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); } diff --git a/src/hgl/meson.build b/src/hgl/meson.build index e01c572f2d0..eeecbe03b9a 100644 --- a/src/hgl/meson.build +++ b/src/hgl/meson.build @@ -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 : [