Mesa (master): st/wgl: Switch from st_public.h to st_api.h. [V2]

Jose Fonseca jrfonseca at kemper.freedesktop.org
Mon Apr 12 06:32:47 UTC 2010


Module: Mesa
Branch: master
Commit: 192f06adca5e79b4824d92dc41186592ed57f71e
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=192f06adca5e79b4824d92dc41186592ed57f71e

Author: Chia-I Wu <olvaffe at gmail.com>
Date:   Wed Mar 17 10:11:22 2010 +0800

st/wgl: Switch from st_public.h to st_api.h. [V2]

This is only compile tested with crossmingw.

V2:
 - reference count stw_framebuffer

---

 src/gallium/state_trackers/wgl/SConscript          |    1 +
 src/gallium/state_trackers/wgl/stw_context.c       |  125 ++++----
 src/gallium/state_trackers/wgl/stw_context.h       |   10 +-
 src/gallium/state_trackers/wgl/stw_device.c        |   43 +--
 src/gallium/state_trackers/wgl/stw_device.h        |    5 +
 .../state_trackers/wgl/stw_ext_pixelformat.c       |    4 +-
 src/gallium/state_trackers/wgl/stw_framebuffer.c   |   99 +++----
 src/gallium/state_trackers/wgl/stw_framebuffer.h   |   18 +-
 src/gallium/state_trackers/wgl/stw_pixelformat.c   |   47 +--
 src/gallium/state_trackers/wgl/stw_pixelformat.h   |   11 +-
 src/gallium/state_trackers/wgl/stw_st.c            |  306 ++++++++++++++++++++
 src/gallium/state_trackers/wgl/stw_st.h            |   47 +++
 12 files changed, 519 insertions(+), 197 deletions(-)

diff --git a/src/gallium/state_trackers/wgl/SConscript b/src/gallium/state_trackers/wgl/SConscript
index 352c087..f59f3a9 100644
--- a/src/gallium/state_trackers/wgl/SConscript
+++ b/src/gallium/state_trackers/wgl/SConscript
@@ -28,6 +28,7 @@ if env['platform'] in ['windows']:
         'stw_framebuffer.c',
         'stw_getprocaddress.c',
         'stw_pixelformat.c',
+        'stw_st.c',
         'stw_tls.c',
         'stw_wgl.c',
     ]
diff --git a/src/gallium/state_trackers/wgl/stw_context.c b/src/gallium/state_trackers/wgl/stw_context.c
index 1f11b64..663d8b8 100644
--- a/src/gallium/state_trackers/wgl/stw_context.c
+++ b/src/gallium/state_trackers/wgl/stw_context.c
@@ -27,12 +27,13 @@
 
 #include <windows.h>
 
-#include "main/mtypes.h"
-#include "main/context.h"
 #include "pipe/p_compiler.h"
 #include "pipe/p_context.h"
+#include "state_tracker/st_api.h"
+
+/* for _mesa_share_state */
 #include "state_tracker/st_context.h"
-#include "state_tracker/st_public.h"
+#include "main/context.h"
 
 #include "stw_icd.h"
 #include "stw_device.h"
@@ -44,25 +45,13 @@
 
 
 static INLINE struct stw_context *
-stw_context(GLcontext *glctx)
-{
-   if(!glctx)
-      return NULL;
-   assert(glctx->DriverCtx);
-   return (struct stw_context *)glctx->DriverCtx;
-}
-
-static INLINE struct stw_context *
 stw_current_context(void)
 {
-   /* We must check if multiple threads are being used or GET_CURRENT_CONTEXT 
-    * might return the current context of the thread first seen. */
-   _glapi_check_multithread();
+   struct st_context_iface *st;
 
-   {
-      GET_CURRENT_CONTEXT( glctx );
-      return stw_context(glctx);
-   }
+   st = (stw_dev) ? stw_dev->stapi->get_current(stw_dev->stapi) : NULL;
+
+   return (struct stw_context *) ((st) ? st->st_manager_private : NULL);
 }
 
 BOOL APIENTRY
@@ -114,7 +103,11 @@ DrvShareLists(
    ctx2 = stw_lookup_context_locked( dhglrc2 );
 
    if (ctx1 && ctx2) {
-      ret = _mesa_share_state(ctx2->st->ctx, ctx1->st->ctx);
+      struct st_context *st1, *st2;
+
+      st1 = (struct st_context *) ctx1->st;
+      st2 = (struct st_context *) ctx2->st;
+      ret = _mesa_share_state(st2->ctx, st1->ctx);
    }
 
    pipe_mutex_unlock( stw_dev->ctx_mutex );
@@ -122,20 +115,6 @@ DrvShareLists(
    return ret;
 }
 
-static void
-stw_viewport(GLcontext * glctx, GLint x, GLint y,
-             GLsizei width, GLsizei height)
-{
-   struct stw_context *ctx = (struct stw_context *)glctx->DriverCtx;
-   struct stw_framebuffer *fb;
-   
-   fb = stw_framebuffer_from_hdc( ctx->hdc );
-   if(fb) {
-      stw_framebuffer_update(fb);
-      stw_framebuffer_release(fb);
-   }
-}
-
 DHGLRC APIENTRY
 DrvCreateContext(
    HDC hdc )
@@ -150,9 +129,7 @@ DrvCreateLayerContext(
 {
    int iPixelFormat;
    const struct stw_pixelformat_info *pfi;
-   GLvisual visual;
    struct stw_context *ctx = NULL;
-   struct pipe_context *pipe = NULL;
    
    if(!stw_dev)
       return 0;
@@ -165,7 +142,6 @@ DrvCreateLayerContext(
       return 0;
    
    pfi = stw_pixelformat_get_info( iPixelFormat - 1 );
-   stw_pixelformat_visual(&visual, pfi);
    
    ctx = CALLOC_STRUCT( stw_context );
    if (ctx == NULL)
@@ -174,18 +150,12 @@ DrvCreateLayerContext(
    ctx->hdc = hdc;
    ctx->iPixelFormat = iPixelFormat;
 
-   /* priv == hdc, pass to stw_flush_frontbuffer as context_private
-    */
-   pipe = stw_dev->screen->context_create( stw_dev->screen, hdc );
-   if (pipe == NULL) 
-      goto no_pipe;
-
-   ctx->st = st_create_context( pipe, &visual, NULL );
+   ctx->st = stw_dev->stapi->create_context(stw_dev->stapi,
+         stw_dev->smapi, &pfi->stvis, NULL);
    if (ctx->st == NULL) 
       goto no_st_ctx;
 
-   ctx->st->ctx->DriverCtx = ctx;
-   ctx->st->ctx->Driver.Viewport = stw_viewport;
+   ctx->st->st_manager_private = (void *) ctx;
 
    pipe_mutex_lock( stw_dev->ctx_mutex );
    ctx->dhglrc = handle_table_add(stw_dev->ctx_table, ctx);
@@ -196,11 +166,8 @@ DrvCreateLayerContext(
    return ctx->dhglrc;
 
 no_hglrc:
-   st_destroy_context(ctx->st);
-   goto no_pipe; /* st_context_destroy already destroys pipe */
+   ctx->st->destroy(ctx->st);
 no_st_ctx:
-   pipe->destroy( pipe );
-no_pipe:
    FREE(ctx);
 no_ctx:
    return 0;
@@ -226,9 +193,9 @@ DrvDeleteContext(
       
       /* Unbind current if deleting current context. */
       if (curctx == ctx)
-         st_make_current( NULL, NULL, NULL, NULL );
+         stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
 
-      st_destroy_context(ctx->st);
+      ctx->st->destroy(ctx->st);
       FREE(ctx);
 
       ret = TRUE;
@@ -306,7 +273,7 @@ stw_make_current(
    curctx = stw_current_context();
    if (curctx != NULL) {
       if (curctx->dhglrc != dhglrc)
-	 st_flush(curctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+         curctx->st->flush(curctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
       
       /* Return if already current. */
       if (curctx->dhglrc == dhglrc && curctx->hdc == hdc) {
@@ -314,10 +281,12 @@ stw_make_current(
          fb = stw_framebuffer_from_hdc( hdc );
          goto success;
       }
+
+      stw_framebuffer_reference(&curctx->current_framebuffer, NULL);
    }
 
    if (hdc == NULL || dhglrc == 0) {
-      return st_make_current( NULL, NULL, NULL, NULL );
+      return stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
    }
 
    pipe_mutex_lock( stw_dev->ctx_mutex ); 
@@ -327,7 +296,10 @@ stw_make_current(
       goto fail;
 
    fb = stw_framebuffer_from_hdc( hdc );
-   if(!fb) { 
+   if (fb) {
+      stw_framebuffer_update(fb);
+   }
+   else {
       /* Applications should call SetPixelFormat before creating a context,
        * but not all do, and the opengl32 runtime seems to use a default pixel
        * format in some cases, so we must create a framebuffer for those here
@@ -342,23 +314,17 @@ stw_make_current(
    if(fb->iPixelFormat != ctx->iPixelFormat)
       goto fail;
 
-   /* Lazy allocation of the frame buffer */
-   if(!stw_framebuffer_allocate(fb))
-      goto fail;
-
    /* Bind the new framebuffer */
    ctx->hdc = hdc;
    
-   /* pass to stw_flush_frontbuffer as context_private */
-   ctx->st->pipe->priv = hdc;
-   
-   if(!st_make_current( ctx->st, fb->stfb, fb->stfb, hdc ))
+   if (!stw_dev->stapi->make_current(stw_dev->stapi, ctx->st, fb->stfb, fb->stfb))
       goto fail;
 
+   stw_framebuffer_reference(&curctx->current_framebuffer, fb);
+
 success:
    assert(fb);
    if(fb) {
-      stw_framebuffer_update(fb);
       stw_framebuffer_release(fb);
    }
    
@@ -367,11 +333,40 @@ success:
 fail:
    if(fb)
       stw_framebuffer_release(fb);
-   st_make_current( NULL, NULL, NULL, NULL );
+   stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
    return FALSE;
 }
 
 /**
+ * Flush the current context if it is bound to the framebuffer.
+ */
+void
+stw_flush_current_locked( struct stw_framebuffer *fb )
+{
+   struct stw_context *ctx = stw_current_context();
+
+   if (ctx && ctx->current_framebuffer == fb) {
+      ctx->st->flush(ctx->st,
+            PIPE_FLUSH_RENDER_CACHE | 
+            PIPE_FLUSH_SWAPBUFFERS |
+            PIPE_FLUSH_FRAME,
+            NULL);
+   }
+}
+
+/**
+ * Notify the current context that the framebuffer has become invalid.
+ */
+void
+stw_notify_current_locked( struct stw_framebuffer *fb )
+{
+   struct stw_context *ctx = stw_current_context();
+
+   if (ctx && ctx->current_framebuffer == fb)
+      ctx->st->notify_invalid_framebuffer(ctx->st, fb->stfb);
+}
+
+/**
  * Although WGL allows different dispatch entrypoints per context
  */
 static const GLCLTPROCTABLE cpt =
diff --git a/src/gallium/state_trackers/wgl/stw_context.h b/src/gallium/state_trackers/wgl/stw_context.h
index 256c27e..0bbed84 100644
--- a/src/gallium/state_trackers/wgl/stw_context.h
+++ b/src/gallium/state_trackers/wgl/stw_context.h
@@ -30,14 +30,17 @@
 
 #include <windows.h>
 
-struct st_context;
+struct stw_framebuffer;
+struct st_context_iface;
 
 struct stw_context
 {
-   struct st_context *st;
+   struct st_context_iface *st;
    DHGLRC dhglrc;
    int iPixelFormat;
    HDC hdc;
+
+   struct stw_framebuffer *current_framebuffer;
 };
 
 DHGLRC stw_get_current_context( void );
@@ -46,4 +49,7 @@ HDC stw_get_current_dc( void );
 
 BOOL stw_make_current( HDC hdc, DHGLRC dhglrc );
 
+void stw_flush_current_locked( struct stw_framebuffer *fb );
+void stw_notify_current_locked( struct stw_framebuffer *fb );
+
 #endif /* STW_CONTEXT_H */
diff --git a/src/gallium/state_trackers/wgl/stw_device.c b/src/gallium/state_trackers/wgl/stw_device.c
index ea300f2..61b2075 100644
--- a/src/gallium/state_trackers/wgl/stw_device.c
+++ b/src/gallium/state_trackers/wgl/stw_device.c
@@ -30,8 +30,8 @@
 #include "glapi/glthread.h"
 #include "util/u_debug.h"
 #include "util/u_math.h"
+#include "util/u_memory.h"
 #include "pipe/p_screen.h"
-#include "state_tracker/st_public.h"
 
 #include "stw_device.h"
 #include "stw_winsys.h"
@@ -39,6 +39,7 @@
 #include "stw_icd.h"
 #include "stw_tls.h"
 #include "stw_framebuffer.h"
+#include "stw_st.h"
 
 #ifdef WIN32_THREADS
 extern _glthread_Mutex OneTimeLock;
@@ -48,28 +49,6 @@ extern _glthread_Mutex OneTimeLock;
 struct stw_device *stw_dev = NULL;
 
 
-/**
- * XXX: Dispatch pipe_screen::flush_front_buffer to our 
- * stw_winsys::flush_front_buffer.
- */
-static void 
-stw_flush_frontbuffer(struct pipe_screen *screen,
-                     struct pipe_surface *surface,
-                     void *context_private )
-{
-   HDC hdc = (HDC)context_private;
-   struct stw_framebuffer *fb;
-   
-   fb = stw_framebuffer_from_hdc( hdc );
-   if (!fb) {
-      /* fb can be NULL if window was destroyed already */
-      return;
-   }
-
-   stw_framebuffer_present_locked(hdc, fb, surface);
-}
-
-
 boolean
 stw_init(const struct stw_winsys *stw_winsys)
 {
@@ -95,6 +74,11 @@ stw_init(const struct stw_winsys *stw_winsys)
    _glthread_INIT_MUTEX(OneTimeLock);
 #endif
 
+   stw_dev->stapi = stw_st_create_api();
+   stw_dev->smapi = CALLOC_STRUCT(st_manager);
+   if (!stw_dev->stapi || !stw_dev->smapi)
+      goto error1;
+
    screen = stw_winsys->create_screen();
    if(!screen)
       goto error1;
@@ -102,12 +86,9 @@ stw_init(const struct stw_winsys *stw_winsys)
    if(stw_winsys->get_adapter_luid)
       stw_winsys->get_adapter_luid(screen, &stw_dev->AdapterLuid);
 
+   stw_dev->smapi->screen = screen;
    stw_dev->screen = screen;
 
-   /* XXX
-    */
-   stw_dev->screen->flush_frontbuffer = &stw_flush_frontbuffer;
-   
    pipe_mutex_init( stw_dev->ctx_mutex );
    pipe_mutex_init( stw_dev->fb_mutex );
 
@@ -121,6 +102,11 @@ stw_init(const struct stw_winsys *stw_winsys)
    return TRUE;
 
 error1:
+   if (stw_dev->smapi)
+      FREE(stw_dev->smapi);
+   if (stw_dev->stapi)
+      stw_dev->stapi->destroy(stw_dev->stapi);
+
    stw_dev = NULL;
    return FALSE;
 }
@@ -170,6 +156,9 @@ stw_cleanup(void)
    pipe_mutex_destroy( stw_dev->fb_mutex );
    pipe_mutex_destroy( stw_dev->ctx_mutex );
    
+   FREE(stw_dev->smapi);
+   stw_dev->stapi->destroy(stw_dev->stapi);
+
    stw_dev->screen->destroy(stw_dev->screen);
 
 #ifdef WIN32_THREADS
diff --git a/src/gallium/state_trackers/wgl/stw_device.h b/src/gallium/state_trackers/wgl/stw_device.h
index 2e9ba19..1b83696 100644
--- a/src/gallium/state_trackers/wgl/stw_device.h
+++ b/src/gallium/state_trackers/wgl/stw_device.h
@@ -40,6 +40,8 @@
 
 
 struct pipe_screen;
+struct st_api;
+struct st_manager;
 struct stw_framebuffer;
 
 struct stw_device
@@ -48,6 +50,9 @@ struct stw_device
    
    struct pipe_screen *screen;
    
+   struct st_api *stapi;
+   struct st_manager *smapi;
+
    LUID AdapterLuid;
 
    struct stw_pixelformat_info pixelformats[STW_MAX_PIXELFORMATS];
diff --git a/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c b/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c
index 8a9995a..ab56800 100644
--- a/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c
+++ b/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c
@@ -227,11 +227,11 @@ stw_query_attrib(
       break;
 
    case WGL_SAMPLE_BUFFERS_ARB:
-      *pvalue = pfi->numSampleBuffers;
+      *pvalue = 1;
       break;
 
    case WGL_SAMPLES_ARB:
-      *pvalue = pfi->numSamples;
+      *pvalue = pfi->stvis.samples;
       break;
 
    default:
diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.c b/src/gallium/state_trackers/wgl/stw_framebuffer.c
index 4f1629d..259b22f 100644
--- a/src/gallium/state_trackers/wgl/stw_framebuffer.c
+++ b/src/gallium/state_trackers/wgl/stw_framebuffer.c
@@ -27,18 +27,19 @@
 
 #include <windows.h>
 
-#include "main/context.h"
 #include "pipe/p_format.h"
 #include "pipe/p_screen.h"
 #include "util/u_format.h"
-#include "state_tracker/st_context.h"
-#include "state_tracker/st_public.h"
+#include "util/u_memory.h"
+#include "state_tracker/st_api.h"
 
 #include "stw_icd.h"
 #include "stw_framebuffer.h"
 #include "stw_device.h"
 #include "stw_winsys.h"
 #include "stw_tls.h"
+#include "stw_context.h"
+#include "stw_st.h"
 
 
 /**
@@ -63,8 +64,8 @@ stw_framebuffer_from_hwnd_locked(
 
 /**
  * Destroy this framebuffer. Both stw_dev::fb_mutex and stw_framebuffer::mutex
- * must be held, by this order. Obviously no further access to fb can be done 
- * after this.
+ * must be held, by this order.  If there are still references to the
+ * framebuffer, nothing will happen.
  */
 static INLINE void
 stw_framebuffer_destroy_locked(
@@ -72,6 +73,13 @@ stw_framebuffer_destroy_locked(
 {
    struct stw_framebuffer **link;
 
+   /* check the reference count */
+   fb->refcnt--;
+   if (fb->refcnt) {
+      pipe_mutex_unlock( fb->mutex );
+      return;
+   }
+
    link = &stw_dev->fb_head;
    while (*link != fb)
       link = &(*link)->next;
@@ -82,7 +90,7 @@ stw_framebuffer_destroy_locked(
    if(fb->shared_surface)
       stw_dev->stw_winsys->shared_surface_close(stw_dev->screen, fb->shared_surface);
 
-   st_unreference_framebuffer(fb->stfb);
+   stw_st_destroy_framebuffer_locked(fb->stfb);
    
    pipe_mutex_unlock( fb->mutex );
 
@@ -230,9 +238,14 @@ stw_framebuffer_create(
    fb->iPixelFormat = iPixelFormat;
 
    fb->pfi = pfi = stw_pixelformat_get_info( iPixelFormat - 1 );
+   fb->stfb = stw_st_create_framebuffer( fb );
+   if (!fb->stfb) {
+      FREE( fb );
+      return NULL;
+   }
+
+   fb->refcnt = 1;
 
-   stw_pixelformat_visual(&fb->visual, pfi);
-   
    stw_framebuffer_get_size(fb);
 
    pipe_mutex_init( fb->mutex );
@@ -251,47 +264,31 @@ stw_framebuffer_create(
    return fb;
 }
 
-
-BOOL
-stw_framebuffer_allocate(
+/**
+ * Have ptr reference fb.  The referenced framebuffer should be locked.
+ */
+void
+stw_framebuffer_reference(
+   struct stw_framebuffer **ptr,
    struct stw_framebuffer *fb)
 {
-   assert(fb);
-   
-   if(!fb->stfb) {
-      const struct stw_pixelformat_info *pfi = fb->pfi;
-      enum pipe_format colorFormat, depthFormat, stencilFormat;
+   struct stw_framebuffer *old_fb = *ptr;
 
-      colorFormat = pfi->color_format;
+   if (old_fb == fb)
+      return;
 
-      if(util_format_get_component_bits(pfi->depth_stencil_format, UTIL_FORMAT_COLORSPACE_ZS, 0))
-         depthFormat = pfi->depth_stencil_format;
-      else
-         depthFormat = PIPE_FORMAT_NONE;
-   
-      if(util_format_get_component_bits(pfi->depth_stencil_format, UTIL_FORMAT_COLORSPACE_ZS, 1))
-         stencilFormat = pfi->depth_stencil_format;
-      else
-         stencilFormat = PIPE_FORMAT_NONE;
-   
-      assert(fb->must_resize);
-      assert(fb->width);
-      assert(fb->height);
-
-      fb->stfb = st_create_framebuffer(
-         &fb->visual,
-         colorFormat,
-         depthFormat,
-         stencilFormat,
-         fb->width,
-         fb->height,
-         (void *) fb );
-      
-      // to notify the context
-      fb->must_resize = TRUE;
+   if (fb)
+      fb->refcnt++;
+   if (old_fb) {
+      pipe_mutex_lock(stw_dev->fb_mutex);
+
+      pipe_mutex_lock(old_fb->mutex);
+      stw_framebuffer_destroy_locked(old_fb);
+
+      pipe_mutex_unlock(stw_dev->fb_mutex);
    }
-   
-   return fb->stfb ? TRUE : FALSE;
+
+   *ptr = fb;
 }
 
 
@@ -313,11 +310,6 @@ stw_framebuffer_update(
     * to know of their existing without using the not very portable PSAPI.
     */
    stw_framebuffer_get_size(fb);
-   
-   if(fb->must_resize) {
-      st_resize_framebuffer(fb->stfb, fb->width, fb->height);
-      fb->must_resize = FALSE;
-   }
 }                      
 
 
@@ -516,6 +508,7 @@ DrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data)
    }
 
    stw_framebuffer_update(fb);
+   stw_notify_current_locked(fb);
 
    stw_framebuffer_release(fb);
 
@@ -544,6 +537,7 @@ stw_framebuffer_present_locked(HDC hdc,
       data.rect = fb->client_rect;
       data.pPrivateData = (void *)surface;
 
+      stw_notify_current_locked(fb);
       stw_framebuffer_release(fb);
 
       return stw_dev->callbacks.wglCbPresentBuffers(hdc, &data);
@@ -554,7 +548,7 @@ stw_framebuffer_present_locked(HDC hdc,
       stw_dev->stw_winsys->present( screen, surface, hdc );
 
       stw_framebuffer_update(fb);
-
+      stw_notify_current_locked(fb);
       stw_framebuffer_release(fb);
 
       return TRUE;
@@ -567,7 +561,6 @@ DrvSwapBuffers(
    HDC hdc )
 {
    struct stw_framebuffer *fb;
-   struct pipe_surface *surface = NULL;
 
    if (!stw_dev)
       return FALSE;
@@ -581,9 +574,9 @@ DrvSwapBuffers(
       return TRUE;
    }
 
-   st_swapbuffers(fb->stfb, &surface, NULL);
+   stw_flush_current_locked(fb);
 
-   return stw_framebuffer_present_locked(hdc, fb, surface);
+   return stw_st_swap_framebuffer_locked(fb->stfb);
 }
 
 
diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.h b/src/gallium/state_trackers/wgl/stw_framebuffer.h
index e61e9bf..89d1230 100644
--- a/src/gallium/state_trackers/wgl/stw_framebuffer.h
+++ b/src/gallium/state_trackers/wgl/stw_framebuffer.h
@@ -30,11 +30,10 @@
 
 #include <windows.h>
 
-#include "main/mtypes.h"
-
 #include "os/os_thread.h"
 
 struct pipe_surface;
+struct st_framebuffer_iface;
 struct stw_pixelformat_info;
 
 /**
@@ -64,13 +63,15 @@ struct stw_framebuffer
 
    int iPixelFormat;
    const struct stw_pixelformat_info *pfi;
-   GLvisual visual;
+
+   struct st_framebuffer_iface *stfb;
 
    /*
     * Mutable members. 
     */
 
-   struct st_framebuffer *stfb;
+   unsigned refcnt;
+
    
    /* FIXME: Make this work for multiple contexts bound to the same framebuffer */
    boolean must_resize;
@@ -114,6 +115,11 @@ stw_framebuffer_create(
    HDC hdc,
    int iPixelFormat );
 
+void
+stw_framebuffer_reference(
+   struct stw_framebuffer **ptr,
+   struct stw_framebuffer *fb);
+
 /**
  * Search a framebuffer with a matching HWND.
  * 
@@ -135,10 +141,6 @@ stw_framebuffer_from_hdc(
    HDC hdc );
 
 BOOL
-stw_framebuffer_allocate(
-   struct stw_framebuffer *fb );
-
-BOOL
 stw_framebuffer_present_locked(HDC hdc,
                                struct stw_framebuffer *fb,
                                struct pipe_surface *surface);
diff --git a/src/gallium/state_trackers/wgl/stw_pixelformat.c b/src/gallium/state_trackers/wgl/stw_pixelformat.c
index a07de99..11e779d 100644
--- a/src/gallium/state_trackers/wgl/stw_pixelformat.c
+++ b/src/gallium/state_trackers/wgl/stw_pixelformat.c
@@ -142,9 +142,6 @@ stw_pixelformat_add(
    
    memset(pfi, 0, sizeof *pfi);
    
-   pfi->color_format = color->format;
-   pfi->depth_stencil_format = depth->format;
-   
    pfi->pfd.nSize = sizeof pfi->pfd;
    pfi->pfd.nVersion = 1;
 
@@ -184,11 +181,22 @@ stw_pixelformat_add(
    pfi->pfd.dwVisibleMask = 0;
    pfi->pfd.dwDamageMask = 0;
 
-   if(samples) {
-      pfi->numSampleBuffers = 1;
-      pfi->numSamples = samples;
-      extended = TRUE;
-   }
+   /*
+    * since state trackers can allocate depth/stencil/accum buffers, we provide
+    * only color buffers here
+    */
+   pfi->stvis.buffer_mask = ST_ATTACHMENT_FRONT_LEFT_MASK;
+   if (doublebuffer)
+      pfi->stvis.buffer_mask = ST_ATTACHMENT_BACK_LEFT_MASK;
+
+   pfi->stvis.color_format = color->format;
+   pfi->stvis.depth_stencil_format = depth->format;
+
+   pfi->stvis.accum_format = (accum) ?
+      PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE;
+
+   pfi->stvis.samples = samples;
+   pfi->stvis.render_buffer = ST_ATTACHMENT_INVALID;
    
    ++stw_dev->pixelformat_extended_count;
    
@@ -264,29 +272,6 @@ stw_pixelformat_get_info( uint index )
 }
 
 
-void
-stw_pixelformat_visual(GLvisual *visual, 
-                       const struct stw_pixelformat_info *pfi )
-{
-   memset(visual, 0, sizeof *visual);
-   _mesa_initialize_visual(
-      visual,
-      (pfi->pfd.dwFlags & PFD_DOUBLEBUFFER) ? GL_TRUE : GL_FALSE,
-      (pfi->pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE,
-      pfi->pfd.cRedBits,
-      pfi->pfd.cGreenBits,
-      pfi->pfd.cBlueBits,
-      pfi->pfd.cAlphaBits,
-      pfi->pfd.cDepthBits,
-      pfi->pfd.cStencilBits,
-      pfi->pfd.cAccumRedBits,
-      pfi->pfd.cAccumGreenBits,
-      pfi->pfd.cAccumBlueBits,
-      pfi->pfd.cAccumAlphaBits,
-      pfi->numSamples );
-}
-
-
 LONG APIENTRY
 DrvDescribePixelFormat(
    HDC hdc,
diff --git a/src/gallium/state_trackers/wgl/stw_pixelformat.h b/src/gallium/state_trackers/wgl/stw_pixelformat.h
index 3a690b3..d405172 100644
--- a/src/gallium/state_trackers/wgl/stw_pixelformat.h
+++ b/src/gallium/state_trackers/wgl/stw_pixelformat.h
@@ -38,16 +38,13 @@
 
 #include "pipe/p_compiler.h"
 #include "pipe/p_format.h"
+#include "state_tracker/st_api.h"
 
 struct stw_pixelformat_info
 {
-   enum pipe_format color_format;
-   enum pipe_format depth_stencil_format;
-   
    PIXELFORMATDESCRIPTOR pfd;
    
-   unsigned numSampleBuffers;
-   unsigned numSamples;
+   struct st_visual stvis;
 };
 
 void
@@ -62,10 +59,6 @@ stw_pixelformat_get_extended_count( void );
 const struct stw_pixelformat_info *
 stw_pixelformat_get_info( uint index );
 
-void
-stw_pixelformat_visual(GLvisual *visual, 
-                       const struct stw_pixelformat_info *pfi );
-
 int
 stw_pixelformat_choose( HDC hdc,
                         CONST PIXELFORMATDESCRIPTOR *ppfd );
diff --git a/src/gallium/state_trackers/wgl/stw_st.c b/src/gallium/state_trackers/wgl/stw_st.c
new file mode 100644
index 0000000..6c71f2a
--- /dev/null
+++ b/src/gallium/state_trackers/wgl/stw_st.c
@@ -0,0 +1,306 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv at lunarg.com>
+ */
+
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+#include "state_tracker/st_manager.h" /* for st_manager_create_api */
+
+#include "stw_st.h"
+#include "stw_device.h"
+#include "stw_framebuffer.h"
+#include "stw_pixelformat.h"
+
+struct stw_st_framebuffer {
+   struct st_framebuffer_iface base;
+
+   struct stw_framebuffer *fb;
+   struct st_visual stvis;
+
+   struct pipe_texture *textures[ST_ATTACHMENT_COUNT];
+   unsigned texture_width, texture_height;
+   unsigned texture_mask;
+
+   struct pipe_surface *front_surface, *back_surface;
+};
+
+static INLINE struct stw_st_framebuffer *
+stw_st_framebuffer(struct st_framebuffer_iface *stfb)
+{
+   return (struct stw_st_framebuffer *) stfb;
+}
+
+/**
+ * Remove outdated textures and create the requested ones.
+ */
+static void
+stw_st_framebuffer_validate_locked(struct st_framebuffer_iface *stfb,
+                                   unsigned width, unsigned height,
+                                   unsigned mask)
+{
+   struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
+   struct pipe_texture templ;
+   unsigned i;
+
+   /* remove outdated textures */
+   if (stwfb->texture_width != width || stwfb->texture_height != height) {
+      for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
+         pipe_texture_reference(&stwfb->textures[i], NULL);
+   }
+
+   memset(&templ, 0, sizeof(templ));
+   templ.target = PIPE_TEXTURE_2D;
+   templ.width0 = width;
+   templ.height0 = height;
+   templ.depth0 = 1;
+   templ.last_level = 0;
+
+   for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
+      enum pipe_format format;
+      unsigned tex_usage;
+
+      /* the texture already exists or not requested */
+      if (stwfb->textures[i] || !(mask & (1 << i))) {
+         /* remember the texture */
+         if (stwfb->textures[i])
+            mask |= (1 << i);
+         continue;
+      }
+
+      switch (i) {
+      case ST_ATTACHMENT_FRONT_LEFT:
+      case ST_ATTACHMENT_BACK_LEFT:
+         format = stwfb->stvis.color_format;
+         tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+                     PIPE_TEXTURE_USAGE_RENDER_TARGET;
+         break;
+      case ST_ATTACHMENT_DEPTH_STENCIL:
+         format = stwfb->stvis.depth_stencil_format;
+         tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
+         break;
+      default:
+         format = PIPE_FORMAT_NONE;
+         break;
+      }
+
+      if (format != PIPE_FORMAT_NONE) {
+         templ.format = format;
+         templ.tex_usage = tex_usage;
+
+         stwfb->textures[i] =
+            stw_dev->screen->texture_create(stw_dev->screen, &templ);
+      }
+   }
+
+   stwfb->texture_width = width;
+   stwfb->texture_height = height;
+   stwfb->texture_mask = mask;
+}
+
+static boolean 
+stw_st_framebuffer_validate(struct st_framebuffer_iface *stfb,
+                            const enum st_attachment_type *statts,
+                            unsigned count,
+                            struct pipe_texture **out)
+{
+   struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
+   unsigned statt_mask, i;
+
+   statt_mask = 0x0;
+   for (i = 0; i < count; i++)
+      statt_mask |= 1 << statts[i];
+
+   pipe_mutex_lock(stwfb->fb->mutex);
+
+   if (stwfb->fb->must_resize || (statt_mask & ~stwfb->texture_mask)) {
+      stw_st_framebuffer_validate_locked(&stwfb->base,
+            statt_mask, stwfb->fb->width, stwfb->fb->height);
+      stwfb->fb->must_resize = FALSE;
+   }
+
+   for (i = 0; i < count; i++) {
+      out[i] = NULL;
+      pipe_texture_reference(&out[i], stwfb->textures[statts[i]]);
+   }
+
+   stw_framebuffer_release(stwfb->fb);
+
+   return TRUE;
+}
+
+static struct pipe_surface *
+get_present_surface_locked(struct st_framebuffer_iface *stfb,
+                           enum st_attachment_type statt)
+{
+   struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
+   struct pipe_texture *ptex;
+   struct pipe_surface *psurf, **cache;
+   
+   ptex = stwfb->textures[statt];
+   if (!ptex)
+      return NULL;
+
+   psurf = NULL;
+
+   switch (statt) {
+   case ST_ATTACHMENT_FRONT_LEFT:
+      cache = &stwfb->front_surface;
+      break;
+   case ST_ATTACHMENT_BACK_LEFT:
+      cache = &stwfb->back_surface;
+      break;
+   default:
+      cache = &psurf;
+      break;
+   }
+
+   if (!*cache) {
+      *cache = stw_dev->screen->get_tex_surface(stw_dev->screen,
+            ptex, 0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ);
+   }
+
+   if (psurf != *cache)
+      pipe_surface_reference(&psurf, *cache);
+
+   return psurf;
+}
+
+/**
+ * Present an attachment of the framebuffer.
+ */
+static boolean
+stw_st_framebuffer_present_locked(struct st_framebuffer_iface *stfb,
+                                  enum st_attachment_type statt)
+{
+   struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
+   struct pipe_surface *psurf;
+   
+   psurf = get_present_surface_locked(&stwfb->base, statt);
+   if (psurf) {
+      stw_framebuffer_present_locked(stwfb->fb->hDC, stwfb->fb, psurf);
+      pipe_surface_reference(&psurf, NULL);
+   }
+
+   return TRUE;
+}
+
+static boolean
+stw_st_framebuffer_flush_front(struct st_framebuffer_iface *stfb,
+                               enum st_attachment_type statt)
+{
+   struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
+
+   pipe_mutex_lock(stwfb->fb->mutex);
+
+   return stw_st_framebuffer_present_locked(&stwfb->base, statt);
+}
+
+/**
+ * Create a framebuffer interface.
+ */
+struct st_framebuffer_iface *
+stw_st_create_framebuffer(struct stw_framebuffer *fb)
+{
+   struct stw_st_framebuffer *stwfb;
+
+   stwfb = CALLOC_STRUCT(stw_st_framebuffer);
+   if (!stwfb)
+      return NULL;
+
+   stwfb->fb = fb;
+   stwfb->stvis = fb->pfi->stvis;
+
+   stwfb->base.visual = &stwfb->stvis;
+   stwfb->base.flush_front = stw_st_framebuffer_flush_front;
+   stwfb->base.validate = stw_st_framebuffer_validate;
+
+   return &stwfb->base;
+}
+
+/**
+ * Destroy a framebuffer interface.
+ */
+void
+stw_st_destroy_framebuffer_locked(struct st_framebuffer_iface *stfb)
+{
+   struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
+   int i;
+
+   pipe_surface_reference(&stwfb->front_surface, NULL);
+   pipe_surface_reference(&stwfb->back_surface, NULL);
+
+   for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
+      pipe_texture_reference(&stwfb->textures[i], NULL);
+
+   FREE(stwfb);
+}
+
+/**
+ * Swap the buffers of the given framebuffer.
+ */
+boolean
+stw_st_swap_framebuffer_locked(struct st_framebuffer_iface *stfb)
+{
+   struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
+   unsigned front = ST_ATTACHMENT_FRONT_LEFT, back = ST_ATTACHMENT_BACK_LEFT;
+   struct pipe_texture *ptex;
+   struct pipe_surface *psurf;
+   unsigned mask;
+
+   /* swap the textures */
+   ptex = stwfb->textures[front];
+   stwfb->textures[front] = stwfb->textures[back];
+   stwfb->textures[back] = ptex;
+
+   /* swap the surfaces */
+   psurf = stwfb->front_surface;
+   stwfb->front_surface = stwfb->back_surface;
+   stwfb->back_surface = psurf;
+
+   /* convert to mask */
+   front = 1 << front;
+   back = 1 << back;
+
+   /* swap the bits in mask */
+   mask = stwfb->texture_mask & ~(front | back);
+   if (stwfb->texture_mask & front)
+      mask |= back;
+   if (stwfb->texture_mask & back)
+      mask |= front;
+   stwfb->texture_mask = mask;
+
+   front = ST_ATTACHMENT_FRONT_LEFT;
+   return stw_st_framebuffer_present_locked(&stwfb->base, front);
+}
+
+/**
+ * Create an st_api of the state tracker.
+ */
+struct st_api *
+stw_st_create_api(void)
+{
+   return st_manager_create_api();
+}
diff --git a/src/gallium/state_trackers/wgl/stw_st.h b/src/gallium/state_trackers/wgl/stw_st.h
new file mode 100644
index 0000000..23771d8
--- /dev/null
+++ b/src/gallium/state_trackers/wgl/stw_st.h
@@ -0,0 +1,47 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv at lunarg.com>
+ */
+
+#ifndef STW_ST_H
+#define STW_ST_H
+
+#include "state_tracker/st_api.h"
+
+struct stw_framebuffer;
+
+struct st_api *
+stw_st_create_api(void);
+
+struct st_framebuffer_iface *
+stw_st_create_framebuffer(struct stw_framebuffer *fb);
+
+void
+stw_st_destroy_framebuffer_locked(struct st_framebuffer_iface *stfb);
+
+boolean
+stw_st_swap_framebuffer_locked(struct st_framebuffer_iface *stfb);
+
+#endif /* STW_ST_H */




More information about the mesa-commit mailing list