hgl: Major refactor and cleanup
authorX512 <danger_mail@list.ru>
Tue, 5 Jan 2021 06:12:38 +0000 (00:12 -0600)
committerAlexander von Gluck IV <kallisti5@unixzen.com>
Sun, 10 Jan 2021 02:51:35 +0000 (20:51 -0600)
* Drop old-timey GLDisplatcher
* Refactor haiku-softpipe fixing some hacks
* Bubble BBitmap up to winsys

Reviewed-by: Alexander von Gluck IV <kallisti5@unixzen.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8323>

18 files changed:
include/HaikuGL/GLRenderer.h
include/HaikuGL/GLView.h
src/gallium/frontends/hgl/hgl.c
src/gallium/frontends/hgl/hgl_context.h
src/gallium/targets/haiku-softpipe/GalliumContext.cpp
src/gallium/targets/haiku-softpipe/GalliumContext.h
src/gallium/targets/haiku-softpipe/SoftwareRenderer.cpp
src/gallium/targets/haiku-softpipe/SoftwareRenderer.h
src/gallium/winsys/sw/hgl/hgl_sw_winsys.cpp [moved from src/gallium/winsys/sw/hgl/hgl_sw_winsys.c with 89% similarity]
src/gallium/winsys/sw/hgl/hgl_sw_winsys.h
src/gallium/winsys/sw/hgl/meson.build
src/hgl/GLDispatcher.cpp [deleted file]
src/hgl/GLDispatcher.h [deleted file]
src/hgl/GLRenderer.cpp
src/hgl/GLRendererRoster.cpp
src/hgl/GLRendererRoster.h
src/hgl/GLView.cpp
src/hgl/meson.build

index 166a5fa..5c9c4da 100644 (file)
@@ -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
index a1dd944..e733377 100644 (file)
 
 #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
 
index ee530af..7b13402 100644 (file)
@@ -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_ifacestctxi,
        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 (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;
+                       }
                }
        }
 
@@ -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,49 +250,31 @@ 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;
 }
 
 
-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();
 }
 
 
@@ -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);
+}
index 4cb4526..0b3b534 100644 (file)
@@ -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_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;
@@ -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
 }
index f84b066..15eea94 100644 (file)
@@ -11,6 +11,7 @@
 #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();
@@ -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__);
+               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;
        }
@@ -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);
 }
 
 
index d8d75b9..1947b96 100644 (file)
 #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;
 };
 
 
index 18cb1ac..96f19ae 100644 (file)
@@ -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;
+               }
 
-       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);
 }
 
 
@@ -136,76 +209,54 @@ SoftwareRenderer::UnlockGL()
        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);
 }
 
 
@@ -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
-}
index 10eaef8..66ff71c 100644 (file)
 #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;
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 bcbaf9c..564f9f6 100644 (file)
 #include "frontend/api.h"
 #include "frontend/sw_winsys.h"
 
-#include "bitmap_wrapper.h"
 #include "hgl_sw_winsys.h"
 
+#include <Bitmap.h>
+#include <OS.h>
 
 #ifdef DEBUG
 #   define TRACE(x...) printf("hgl:winsys: " x)
@@ -63,6 +64,7 @@ struct haiku_displaytarget
        unsigned size;
 
        void* data;
+       BBitmap* bitmap;
 };
 
 
@@ -126,10 +128,18 @@ hgl_winsys_displaytarget_create(struct sw_winsys* winsys,
        haikuDisplayTarget->stride = align(formatStride, alignment);
        haikuDisplayTarget->size = haikuDisplayTarget->stride * blockSize;
 
-       haikuDisplayTarget->data
-               = align_malloc(haikuDisplayTarget->size, alignment);
-
-       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;
 
@@ -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
index a81f890..d20c193 100644 (file)
 #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
 
index ceef11b..81dcf5b 100644 (file)
@@ -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 (file)
index f9709e4..0000000
+++ /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 <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;
-}
diff --git a/src/hgl/GLDispatcher.h b/src/hgl/GLDispatcher.h
deleted file mode 100644 (file)
index 7a4bcd3..0000000
+++ /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 <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
index 4573a64..af89b4e 100644 (file)
@@ -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;
 }
 
index 9e5d847..9bb1049 100644 (file)
 #include <image.h>
 
 #include <kernel/image.h>
-#include <system/safemode_defs.h>
+#include <private/system/safemode_defs.h>
 
 #include <Directory.h>
 #include <FindDirectory.h>
 #include <Path.h>
 #include <strings.h>
-#include "GLDispatcher.h"
 #include "GLRendererRoster.h"
 
 #include <new>
 #include <string.h>
+#include <stdio.h>
 
 
 extern "C" status_t _kern_get_safemode_option(const char* parameter,
        char* buffer, size_t* _bufferSize);
 
+GLRendererRoster *GLRendererRoster::fInstance = NULL;
 
-GLRendererRoster::GLRendererRoster(BGLView* view, ulong options)
+GLRendererRoster *GLRendererRoster::Roster()
+{
+       if (fInstance == NULL) {
+               fInstance = new GLRendererRoster();
+       }
+       return fInstance;
+}
+
+GLRendererRoster::GLRendererRoster()
        :
-       fNextID(0),
-       fView(view),
-       fOptions(options),
        fSafeMode(false),
        fABISubDirectory(NULL)
 {
@@ -84,14 +90,19 @@ GLRendererRoster::~GLRendererRoster()
 
 
 BGLRenderer*
-GLRendererRoster::GetRenderer(int32 id)
+GLRendererRoster::GetRenderer(BGLView *view, ulong options)
 {
-       RendererMap::const_iterator iterator = fRenderers.find(id);
-       if (iterator == fRenderers.end())
-               return NULL;
-
-       struct renderer_item item = iterator->second;
-       return item.renderer;
+       for (
+               RendererMap::const_iterator iterator = fRenderers.begin();
+               iterator != fRenderers.end();
+               iterator++
+       ) {
+               renderer_item item = *iterator;
+               BGLRenderer* renderer;
+               renderer = item.entry(view, options);
+               return renderer;
+       }
+       return NULL;
 }
 
 
@@ -102,6 +113,7 @@ GLRendererRoster::AddDefaultPaths()
        const directory_which paths[] = {
                B_USER_NONPACKAGED_ADDONS_DIRECTORY,
                B_USER_ADDONS_DIRECTORY,
+               B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY,
                B_SYSTEM_ADDONS_DIRECTORY,
        };
 
@@ -162,24 +174,22 @@ GLRendererRoster::AddPath(const char* path)
 
 
 status_t
-GLRendererRoster::AddRenderer(BGLRenderer* renderer,
+GLRendererRoster::AddRenderer(InstantiateRenderer entry,
        image_id image, const entry_ref* ref, ino_t node)
 {
        renderer_item item;
-       item.renderer = renderer;
+       item.entry = entry;
        item.image = image;
        item.node = node;
        if (ref != NULL)
                item.ref = *ref;
 
        try {
-               fRenderers[fNextID] = item;
+               fRenderers.push_back(item);
        } catch (...) {
                return B_NO_MEMORY;
        }
 
-       renderer->fOwningRoster = this;
-       renderer->fID = fNextID++;
        return B_OK;
 }
 
@@ -194,30 +204,29 @@ GLRendererRoster::CreateRenderer(const entry_ref& ref)
                return status;
 
        BPath path(&ref);
+       printf("OpenGL load add-on: %s\n", path.Path());
+
        image_id image = load_add_on(path.Path());
        if (image < B_OK)
                return image;
 
-       BGLRenderer* (*instantiate_renderer)
-               (BGLView* view, ulong options, BGLDispatcher* dispatcher);
+       InstantiateRenderer instantiate_renderer;
 
-       status = get_image_symbol(image, "instantiate_gl_renderer",
-               B_SYMBOL_TYPE_TEXT, (void**)&instantiate_renderer);
-       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;
index f0116cc..66abad9 100644 (file)
@@ -9,42 +9,43 @@
 #define _GLRENDERER_ROSTER_H
 
 
-#include "GLRenderer.h"
+#include <GLRenderer.h>
 
-#include <map>
+#include <vector>
 
 
+typedef BGLRenderer* (*InstantiateRenderer) (BGLView* view, ulong options);
+
 struct renderer_item {
-       BGLRenderer* renderer;
+       InstantiateRenderer entry;
        entry_ref       ref;
        ino_t           node;
        image_id        image;
 };
 
-typedef std::map<renderer_id, renderer_item> RendererMap;
+typedef std::vector<renderer_item> RendererMap;
 
 
 class GLRendererRoster {
        public:
-               GLRendererRoster(BGLView* view, ulong options);
-               virtual ~GLRendererRoster();
-
-               BGLRenderer* GetRenderer(int32 id = 0);
+               static GLRendererRoster *Roster();
+               BGLRenderer* GetRenderer(BGLView *view, ulong options);
 
        private:
+               GLRendererRoster();
+               virtual ~GLRendererRoster();
+
                void AddDefaultPaths();
                status_t AddPath(const char* path);
-               status_t AddRenderer(BGLRenderer* renderer,
-                       image_id image, const entry_ref* ref, ino_t node);
+               status_t AddRenderer(InstantiateRenderer entry, image_id image,
+                       const entry_ref* ref, ino_t node);
                status_t CreateRenderer(const entry_ref& ref);
 
-               RendererMap     fRenderers;
-               int32           fNextID;
-               BGLView*        fView;
-               ulong           fOptions;
+               static GLRendererRoster* fInstance;
                bool            fSafeMode;
                const char*     fABISubDirectory;
 
+               RendererMap fRenderers;
 };
 
 
index 91850db..3462c88 100644 (file)
 #include <DirectWindow.h>
 #include "GLRenderer.h"
 
-#include "interface/DirectWindowPrivate.h"
-#include "GLDispatcher.h"
+#include <private/interface/DirectWindowPrivate.h>
 #include "GLRendererRoster.h"
 
+#include "glapi/glapi.h"
 
 struct glview_direct_info {
        direct_buffer_info* direct_info;
@@ -39,7 +39,6 @@ BGLView::BGLView(BRect rect, const char* name, ulong resizingMode, ulong mode,
        ulong options)
        :
        BView(rect, name, B_FOLLOW_ALL_SIDES, mode | B_WILL_DRAW | B_FRAME_EVENTS),
-               //  | B_FULL_UPDATE_ON_RESIZE)
        fGc(NULL),
        fOptions(options),
        fDitherCount(0),
@@ -47,11 +46,9 @@ BGLView::BGLView(BRect rect, const char* name, ulong resizingMode, ulong mode,
        fDisplayLock("BGLView display lock"),
        fClipInfo(NULL),
        fRenderer(NULL),
-       fRoster(NULL),
        fDitherMap(NULL)
 {
-       fRoster = new GLRendererRoster(this, options);
-       fRenderer = fRoster->GetRenderer();
+       fRenderer = GLRendererRoster::Roster()->GetRenderer(this, options);
 }
 
 
@@ -77,6 +74,15 @@ BGLView::LockGL()
 void
 BGLView::UnlockGL()
 {
+       thread_id lockerThread = fDisplayLock.LockingThread();
+       thread_id callerThread = find_thread(NULL);
+
+       if (lockerThread != B_ERROR && lockerThread != callerThread) {
+               printf("UnlockGL is called from wrong thread, lockerThread: %d, callerThread: %d\n",
+                       (int)lockerThread, (int)callerThread);
+               debugger("[!]");
+       }
+
        if (fRenderer != NULL && fDisplayLock.CountLocks() == 1)
                fRenderer->UnlockGL();
        fDisplayLock.Unlock();
@@ -113,15 +119,7 @@ BGLView::EmbeddedView()
 void*
 BGLView::GetGLProcAddress(const char* procName)
 {
-       BGLDispatcher* glDispatcher = NULL;
-
-       if (fRenderer)
-               glDispatcher = fRenderer->GLDispatcher();
-
-       if (glDispatcher)
-               return (void*)glDispatcher->AddressOf(procName);
-
-       return NULL;
+       return (void*)_glapi_get_proc_address(procName);
 }
 
 
@@ -170,9 +168,8 @@ void
 BGLView::Draw(BRect updateRect)
 {
        if (fRenderer) {
-               _LockDraw();
-               fRenderer->Draw(updateRect);
-               _UnlockDraw();
+               if (!fClipInfo || !fClipInfo->enable_direct_mode)
+                       fRenderer->Draw(updateRect);
                return;
        }
        // TODO: auto-size and center the string
@@ -237,10 +234,6 @@ BGLView::AllAttached()
 void
 BGLView::DetachedFromWindow()
 {
-       if (fRenderer)
-               fRenderer->Release();
-       fRenderer = NULL;
-
        BView::DetachedFromWindow();
 }
 
@@ -260,12 +253,9 @@ BGLView::FrameResized(float width, float height)
                v->ConvertToParent(&fBounds);
 
        if (fRenderer) {
-               LockGL();
-               _LockDraw();
-               _CallDirectConnected();
+               //_LockDraw();
                fRenderer->FrameResized(width, height);
-               _UnlockDraw();
-               UnlockGL();
+               //_UnlockDraw();
        }
 
        BView::FrameResized(width, height);
@@ -342,6 +332,7 @@ BGLView::GetSupportedSuites(BMessage* data)
 void
 BGLView::DirectConnected(direct_buffer_info* info)
 {
+       printf("BGLView::DirectConnected\n");
        if (fClipInfo == NULL) {
                fClipInfo = new (std::nothrow) glview_direct_info();
                if (fClipInfo == NULL)
@@ -350,33 +341,33 @@ BGLView::DirectConnected(direct_buffer_info* info)
 
        direct_buffer_info* localInfo = fClipInfo->direct_info;
 
+       _LockDraw();
        switch (info->buffer_state & B_DIRECT_MODE_MASK) {
                case B_DIRECT_START:
                        fClipInfo->direct_connected = true;
                        memcpy(localInfo, info, DIRECT_BUFFER_INFO_AREA_SIZE);
-                       _UnlockDraw();
                        break;
 
                case B_DIRECT_MODIFY:
-                       _LockDraw();
                        memcpy(localInfo, info, DIRECT_BUFFER_INFO_AREA_SIZE);
-                       _UnlockDraw();
                        break;
 
                case B_DIRECT_STOP:
                        fClipInfo->direct_connected = false;
-                       _LockDraw();
                        break;
        }
 
        if (fRenderer)
                _CallDirectConnected();
+
+       _UnlockDraw();
 }
 
 
 void
 BGLView::EnableDirectMode(bool enabled)
 {
+       printf("BGLView::EnableDirectMode: %d\n", (int)enabled);
        if (fRenderer)
                fRenderer->EnableDirectMode(enabled);
        if (fClipInfo == NULL) {
@@ -412,8 +403,10 @@ BGLView::_UnlockDraw()
 void
 BGLView::_CallDirectConnected()
 {
-       if (!fClipInfo)
+       if (!fClipInfo || !fClipInfo->direct_connected) {
+               fRenderer->DirectConnected(NULL);
                return;
+       }
 
        direct_buffer_info* localInfo = fClipInfo->direct_info;
        direct_buffer_info* info = (direct_buffer_info*)malloc(
@@ -472,10 +465,9 @@ BGLView::BGLView(BRect rect, char* name, ulong resizingMode, ulong mode,
        fDisplayLock("BGLView display lock"),
        fClipInfo(NULL),
        fRenderer(NULL),
-       fRoster(NULL),
        fDitherMap(NULL)
 {
-       fRoster = new GLRendererRoster(this, options);
+       fRenderer = GLRendererRoster::Roster()->GetRenderer(this, options);
 }
 
 
index e01c572..eeecbe0 100644 (file)
@@ -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 : [