st-api: Rework how drawables are invalidated v3.
[mesa.git] / src / gallium / state_trackers / wgl / stw_context.c
index 0fb7cd83069254950343fc505f1f2c83bba33932..c2839fe815ff8aaa22854a097fb1e753fb3f3149 100644 (file)
 
 #include "pipe/p_compiler.h"
 #include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#include "util/u_memory.h"
+#include "util/u_atomic.h"
 #include "state_tracker/st_api.h"
 
-/* for _mesa_share_state */
-#include "state_tracker/st_context.h"
-#include "main/context.h"
-
 #include "stw_icd.h"
 #include "stw_device.h"
 #include "stw_winsys.h"
@@ -102,13 +101,8 @@ DrvShareLists(
    ctx1 = stw_lookup_context_locked( dhglrc1 );
    ctx2 = stw_lookup_context_locked( dhglrc2 );
 
-   if (ctx1 && ctx2) {
-      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);
-   }
+   if (ctx1 && ctx2 && ctx2->st->share)
+      ret = ctx2->st->share(ctx2->st, ctx1->st);
 
    pipe_mutex_unlock( stw_dev->ctx_mutex );
    
@@ -129,6 +123,7 @@ DrvCreateLayerContext(
 {
    int iPixelFormat;
    const struct stw_pixelformat_info *pfi;
+   struct st_context_attribs attribs;
    struct stw_context *ctx = NULL;
    
    if(!stw_dev)
@@ -150,8 +145,12 @@ DrvCreateLayerContext(
    ctx->hdc = hdc;
    ctx->iPixelFormat = iPixelFormat;
 
+   memset(&attribs, 0, sizeof(attribs));
+   attribs.profile = ST_PROFILE_DEFAULT;
+   attribs.visual = pfi->stvis;
+
    ctx->st = stw_dev->stapi->create_context(stw_dev->stapi,
-         stw_dev->smapi, &pfi->stvis, NULL);
+         stw_dev->smapi, &attribs, NULL);
    if (ctx->st == NULL) 
       goto no_st_ctx;
 
@@ -266,75 +265,82 @@ stw_make_current(
    struct stw_context *curctx = NULL;
    struct stw_context *ctx = NULL;
    struct stw_framebuffer *fb = NULL;
+   BOOL ret = FALSE;
 
    if (!stw_dev)
-      goto fail;
+      return FALSE;
 
    curctx = stw_current_context();
    if (curctx != NULL) {
-      if (curctx->dhglrc != dhglrc)
-         curctx->st->flush(curctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
-      
-      /* Return if already current. */
-      if (curctx->dhglrc == dhglrc && curctx->hdc == hdc) {
-         ctx = curctx;
-         fb = stw_framebuffer_from_hdc( hdc );
-         goto success;
+      if (curctx->dhglrc == dhglrc) {
+         if (curctx->hdc == hdc) {
+            /* Return if already current. */
+            return TRUE;
+         }
+      } else {
+         curctx->st->flush(curctx->st, ST_FLUSH_FRONT, NULL);
       }
-
-      stw_framebuffer_reference(&curctx->current_framebuffer, NULL);
-   }
-
-   if (hdc == NULL || dhglrc == 0) {
-      return stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
    }
 
-   pipe_mutex_lock( stw_dev->ctx_mutex ); 
-   ctx = stw_lookup_context_locked( dhglrc );
-   pipe_mutex_unlock( stw_dev->ctx_mutex ); 
-   if(!ctx)
-      goto fail;
-
-   fb = stw_framebuffer_from_hdc( hdc );
-   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
-       */
-      int iPixelFormat = GetPixelFormat(hdc);
-      if(iPixelFormat)
-         fb = stw_framebuffer_create( hdc, iPixelFormat );
-      if(!fb) 
+   if (dhglrc) {
+      pipe_mutex_lock( stw_dev->ctx_mutex );
+      ctx = stw_lookup_context_locked( dhglrc );
+      pipe_mutex_unlock( stw_dev->ctx_mutex );
+      if (!ctx) {
          goto fail;
-   }
-   
-   if(fb->iPixelFormat != ctx->iPixelFormat)
-      goto fail;
+      }
 
-   /* Bind the new framebuffer */
-   ctx->hdc = hdc;
+      fb = stw_framebuffer_from_hdc( hdc );
+      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
+          */
+         int iPixelFormat = GetPixelFormat(hdc);
+         if (iPixelFormat)
+            fb = stw_framebuffer_create( hdc, iPixelFormat );
+         if (!fb)
+            goto fail;
+      }
    
-   if (!stw_dev->stapi->make_current(stw_dev->stapi, ctx->st, fb->stfb, fb->stfb))
-      goto fail;
+      if (fb->iPixelFormat != ctx->iPixelFormat) {
+         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
+         goto fail;
+      }
 
-   stw_framebuffer_reference(&ctx->current_framebuffer, fb);
+      /* Bind the new framebuffer */
+      ctx->hdc = hdc;
 
-success:
-   assert(fb);
-   if(fb) {
-      stw_framebuffer_release(fb);
+      ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st, fb->stfb, fb->stfb);
+      stw_framebuffer_reference(&ctx->current_framebuffer, fb);
+   } else {
+      ret = stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
    }
    
-   return TRUE;
-
 fail:
-   if(fb)
+
+   if (fb) {
       stw_framebuffer_release(fb);
-   stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
-   return FALSE;
+   }
+
+   /* On failure, make the thread's current rendering context not current
+    * before returning */
+   if (!ret) {
+      stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
+      ctx = NULL;
+   }
+
+   /* Unreference the previous framebuffer if any. It must be done after
+    * make_current, as it can be referenced inside.
+    */
+   if (curctx && curctx != ctx) {
+      stw_framebuffer_reference(&curctx->current_framebuffer, NULL);
+   }
+
+   return ret;
 }
 
 /**
@@ -346,11 +352,7 @@ 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);
+      ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL);
    }
 }
 
@@ -360,10 +362,7 @@ stw_flush_current_locked( struct stw_framebuffer *fb )
 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);
+   p_atomic_inc(&fb->stfb->stamp);
 }
 
 /**