[Mesa-dev] [PATCH 2/3] st/wgl: add support for WGL_ARB_make_current_read

Miklós Máté mtmkls at gmail.com
Sun Mar 26 22:29:21 UTC 2017


Hi,

On 24/03/17 22:42, Brian Paul wrote:
> This adds the wglMakeContextCurrentARB() and wglMakeContextCurrentARB()
One of these should be wglGetCurrentReadDCARB().

> functions.
> ---
>   src/gallium/state_trackers/wgl/stw_context.c       | 77 ++++++++++++++++++----
>   src/gallium/state_trackers/wgl/stw_context.h       |  5 +-
>   src/gallium/state_trackers/wgl/stw_ext_context.c   | 15 +++++
>   .../state_trackers/wgl/stw_ext_extensionsstring.c  |  1 +
>   .../state_trackers/wgl/stw_ext_rendertexture.c     |  5 +-
>   .../state_trackers/wgl/stw_getprocaddress.c        |  3 +
>   src/gallium/state_trackers/wgl/stw_wgl.c           |  7 ++
>   src/gallium/state_trackers/wgl/stw_wgl.h           | 10 +++
>   8 files changed, 107 insertions(+), 16 deletions(-)
>
> diff --git a/src/gallium/state_trackers/wgl/stw_context.c b/src/gallium/state_trackers/wgl/stw_context.c
> index 85cffa6..18273ac 100644
> --- a/src/gallium/state_trackers/wgl/stw_context.c
> +++ b/src/gallium/state_trackers/wgl/stw_context.c
> @@ -187,6 +187,7 @@ stw_create_context_attribs(HDC hdc, INT iLayerPlane, DHGLRC hShareContext,
>         goto no_ctx;
>   
>      ctx->hdc = hdc;
> +   ctx->hReadDC = hdc;
>      ctx->iPixelFormat = iPixelFormat;
>      ctx->shared = shareCtx != NULL;
>   
> @@ -357,7 +358,7 @@ DrvReleaseContext(DHGLRC dhglrc)
>      if (ctx != stw_current_context())
>         return FALSE;
>   
> -   if (stw_make_current( NULL, 0 ) == FALSE)
> +   if (stw_make_current( NULL, NULL, 0 ) == FALSE)
>         return FALSE;
>   
>      return TRUE;
> @@ -389,9 +390,20 @@ stw_get_current_dc( void )
>      return ctx->hdc;
>   }
>   
> +HDC
> +stw_get_current_read_dc( void )
> +{
> +   struct stw_context *ctx;
> +
> +   ctx = stw_current_context();
> +   if (!ctx)
> +      return NULL;
> +
> +   return ctx->hReadDC;
> +}
>   
>   BOOL
> -stw_make_current(HDC hdc, DHGLRC dhglrc)
> +stw_make_current(HDC hdc, HDC hReadDC, DHGLRC dhglrc)
>   {
>      struct stw_context *old_ctx = NULL;
>      struct stw_context *ctx = NULL;
> @@ -403,7 +415,7 @@ stw_make_current(HDC hdc, DHGLRC dhglrc)
>      old_ctx = stw_current_context();
>      if (old_ctx != NULL) {
>         if (old_ctx->dhglrc == dhglrc) {
> -         if (old_ctx->hdc == hdc) {
> +         if (old_ctx->hdc == hdc && old_ctx->hReadDC == hReadDC) {
>               /* Return if already current. */
>               return TRUE;
>            }
> @@ -421,6 +433,7 @@ stw_make_current(HDC hdc, DHGLRC dhglrc)
>   
>      if (dhglrc) {
>         struct stw_framebuffer *fb = NULL;
> +      struct stw_framebuffer *fbRead = NULL;
>         stw_lock_contexts(stw_dev);
>         ctx = stw_lookup_context_locked( dhglrc );
>         stw_unlock_contexts(stw_dev);
> @@ -454,6 +467,7 @@ stw_make_current(HDC hdc, DHGLRC dhglrc)
>   
>         /* Bind the new framebuffer */
>         ctx->hdc = hdc;
> +      ctx->hReadDC = hReadDC;
>   
>         struct stw_framebuffer *old_fb = ctx->current_framebuffer;
>         if (old_fb != fb) {
> @@ -462,12 +476,47 @@ stw_make_current(HDC hdc, DHGLRC dhglrc)
>         }
>         stw_framebuffer_unlock(fb);
>   
> -      /* Note: when we call this function we will wind up in the
> -       * stw_st_framebuffer_validate_locked() function which will incur
> -       * a recursive fb->mutex lock.
> -       */
> -      ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st,
> -                                         fb->stfb, fb->stfb);
> +      if (hReadDC) {
> +         if (hReadDC == hDrawDC) {
> +            fbRead = fb;
> +         }
> +         else {
> +            fbRead = stw_framebuffer_from_hdc( hReadDC );
> +
> +            if (fbRead) {
> +               stw_framebuffer_update(fbRead);
> +            }
> +            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(hReadDC);
> +               if (iPixelFormat)
> +                  fbRead = stw_framebuffer_create( hReadDC, iPixelFormat );
> +               if (!fbRead)
> +                  goto fail;
> +            }
> +
> +            if (fbRead->iPixelFormat != ctx->iPixelFormat) {
> +               stw_framebuffer_unlock(fbRead);
> +               SetLastError(ERROR_INVALID_PIXEL_FORMAT);
> +               goto fail;
> +            }
> +            stw_framebuffer_unlock(fbRead);
> +         }
> +         ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st,
> +                                            fb->stfb, fbRead->stfb);
> +      }
> +      else {
> +         /* Note: when we call this function we will wind up in the
> +          * stw_st_framebuffer_validate_locked() function which will incur
> +          * a recursive fb->mutex lock.
> +          */
> +         ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st,
> +                                            fb->stfb, fb->stfb);
> +      }
>   
>         if (old_fb && old_fb != fb) {
>            stw_lock_framebuffers(stw_dev);
> @@ -477,14 +526,16 @@ stw_make_current(HDC hdc, DHGLRC dhglrc)
>         }
>   
>   fail:
> -      /* fb must be unlocked at this point. */
> -      assert(!stw_own_mutex(&fb->mutex));
> +      if (fb) {
> +         /* fb must be unlocked at this point. */
> +         assert(!stw_own_mutex(&fb->mutex));
> +      }
Nice catch here.

>   
>         /* On failure, make the thread's current rendering context not current
>          * before returning.
>          */
>         if (!ret) {
> -         stw_make_current(NULL, 0);
> +         stw_make_current(NULL, NULL, 0);
>         }
>      } else {
>         ret = stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
> @@ -870,7 +921,7 @@ DrvSetContext(HDC hdc, DHGLRC dhglrc, PFN_SETPROCTABLE pfnSetProcTable)
>   {
>      PGLCLTPROCTABLE r = (PGLCLTPROCTABLE)&cpt;
>   
> -   if (!stw_make_current(hdc, dhglrc))
> +   if (!stw_make_current(hdc, hdc, dhglrc))
>         r = NULL;
>   
>      return r;
> diff --git a/src/gallium/state_trackers/wgl/stw_context.h b/src/gallium/state_trackers/wgl/stw_context.h
> index 0f180c8..d0e7f2c 100644
> --- a/src/gallium/state_trackers/wgl/stw_context.h
> +++ b/src/gallium/state_trackers/wgl/stw_context.h
> @@ -40,6 +40,7 @@ struct stw_context
>      DHGLRC dhglrc;
>      int iPixelFormat;
>      HDC hdc;
> +   HDC hReadDC;
>      BOOL shared;
>   
>      struct stw_framebuffer *current_framebuffer;
> @@ -59,7 +60,9 @@ struct stw_context *stw_current_context(void);
>   
>   HDC stw_get_current_dc( void );
>   
> -BOOL stw_make_current( HDC hdc, DHGLRC dhglrc );
> +HDC stw_get_current_read_dc( void );
> +
> +BOOL stw_make_current( HDC hdc, HDC hReadDC, DHGLRC dhglrc );
>   
>   void stw_notify_current_locked( struct stw_framebuffer *fb );
>   
> diff --git a/src/gallium/state_trackers/wgl/stw_ext_context.c b/src/gallium/state_trackers/wgl/stw_ext_context.c
> index 4c58316..6326d20 100644
> --- a/src/gallium/state_trackers/wgl/stw_ext_context.c
> +++ b/src/gallium/state_trackers/wgl/stw_ext_context.c
> @@ -195,3 +195,18 @@ wglCreateContextAttribsARB(HDC hDC, HGLRC hShareContext, const int *attribList)
>   
>      return context;
>   }
> +
> +
> +/** Defined by WGL_ARB_make_current_read */
> +BOOL APIENTRY
> +wglMakeContextCurrentARB(HDC hDrawDC, HDC hReadDC, HGLRC hglrc)
> +{
> +   DHGLRC dhglrc = 0;
> +
> +   if (stw_dev && stw_dev->callbacks.wglCbGetDhglrc) {
> +      /* Convert HGLRC to DHGLRC */
> +      dhglrc = stw_dev->callbacks.wglCbGetDhglrc(hglrc);
> +   }
> +
> +   return stw_make_current(hDrawDC, hReadDC, dhglrc);
> +}
> diff --git a/src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c b/src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c
> index 86b93fb..06af8b1 100644
> --- a/src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c
> +++ b/src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c
> @@ -44,6 +44,7 @@ static const char *stw_extension_string =
>      "WGL_ARB_render_texture "
>      "WGL_EXT_create_context_es_profile "
>      "WGL_EXT_create_context_es2_profile "
> +   "WGL_ARB_make_current_read "
I think these should be sorted alphabetically.

MM

>   /*   "WGL_EXT_swap_interval " */
>      "WGL_EXT_extensions_string";
>   
> diff --git a/src/gallium/state_trackers/wgl/stw_ext_rendertexture.c b/src/gallium/state_trackers/wgl/stw_ext_rendertexture.c
> index 9d76696..5503102 100644
> --- a/src/gallium/state_trackers/wgl/stw_ext_rendertexture.c
> +++ b/src/gallium/state_trackers/wgl/stw_ext_rendertexture.c
> @@ -104,6 +104,7 @@ BOOL WINAPI
>   wglBindTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
>   {
>      HDC prevDrawable = stw_get_current_dc();
> +   HDC prevReadable = stw_get_current_read_dc();
>      HDC dc;
>      struct stw_context *curctx = stw_current_context();
>      struct stw_framebuffer *fb;
> @@ -172,7 +173,7 @@ wglBindTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
>      pixelFormatSave = fb->iPixelFormat;
>      fb->iPixelFormat = curctx->iPixelFormat;
>      dc = wglGetPbufferDCARB(hPbuffer);
> -   retVal = stw_make_current(dc, curctx->dhglrc);
> +   retVal = stw_make_current(dc, dc, curctx->dhglrc);
>      fb->iPixelFormat = pixelFormatSave;
>      if (!retVal) {
>         debug_printf("stw_make_current(#1) failed in wglBindTexImageARB()\n");
> @@ -185,7 +186,7 @@ wglBindTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
>                                     fb->textureFace, texFormat);
>   
>      /* rebind previous drawing surface */
> -   retVal = stw_make_current(prevDrawable, curctx->dhglrc);
> +   retVal = stw_make_current(prevDrawable, prevReadable, curctx->dhglrc);
>      if (!retVal) {
>         debug_printf("stw_make_current(#2) failed in wglBindTexImageARB()\n");
>      }
> diff --git a/src/gallium/state_trackers/wgl/stw_getprocaddress.c b/src/gallium/state_trackers/wgl/stw_getprocaddress.c
> index 66718c5..9273d10 100644
> --- a/src/gallium/state_trackers/wgl/stw_getprocaddress.c
> +++ b/src/gallium/state_trackers/wgl/stw_getprocaddress.c
> @@ -79,6 +79,9 @@ static const struct stw_extension_entry stw_extension_entries[] = {
>      STW_EXTENSION_ENTRY( wglReleaseTexImageARB ),
>      STW_EXTENSION_ENTRY( wglSetPbufferAttribARB ),
>   
> +   /*  WGL_ARB_make_current_read */
> +   STW_EXTENSION_ENTRY( wglMakeContextCurrentARB ),
> +   STW_EXTENSION_ENTRY( wglGetCurrentReadDCARB ),
>      { NULL, NULL }
>   };
>   
> diff --git a/src/gallium/state_trackers/wgl/stw_wgl.c b/src/gallium/state_trackers/wgl/stw_wgl.c
> index 5146e6a..de4b4f6 100644
> --- a/src/gallium/state_trackers/wgl/stw_wgl.c
> +++ b/src/gallium/state_trackers/wgl/stw_wgl.c
> @@ -99,6 +99,13 @@ wglGetCurrentDC( VOID )
>      return stw_get_current_dc();
>   }
>   
> +WINGDIAPI HDC APIENTRY
> +wglGetCurrentReadDCARB( VOID )
> +{
> +   return stw_get_current_read_dc();
> +}
> +
> +
>   WINGDIAPI BOOL APIENTRY
>   wglMakeCurrent(
>      HDC hdc,
> diff --git a/src/gallium/state_trackers/wgl/stw_wgl.h b/src/gallium/state_trackers/wgl/stw_wgl.h
> index 31a391d..92d70b5 100644
> --- a/src/gallium/state_trackers/wgl/stw_wgl.h
> +++ b/src/gallium/state_trackers/wgl/stw_wgl.h
> @@ -59,6 +59,16 @@ wglSetPixelFormat(HDC hdc,
>                     int iPixelFormat,
>                     CONST PIXELFORMATDESCRIPTOR *ppfd);
>   
> +WINGDIAPI HDC APIENTRY
> +wglGetCurrentReadDCARB( VOID );
> +
> +WINGDIAPI BOOL APIENTRY
> +wglMakeContextCurrentARB(
> +   HDC hDrawDC,
> +   HDC hReadDC,
> +   HGLRC hglrc );
> +
> +
>   #ifndef WGL_SWAPMULTIPLE_MAX
>   
>   typedef struct _WGLSWAP




More information about the mesa-dev mailing list