Ejemplo n.º 1
0
BOOL APIENTRY
DrvCopyContext(
    DHGLRC dhrcSource,
    DHGLRC dhrcDest,
    UINT fuMask )
{
    struct stw_context *src;
    struct stw_context *dst;
    BOOL ret = FALSE;

    if (!stw_dev)
        return FALSE;

    pipe_mutex_lock( stw_dev->ctx_mutex );

    src = stw_lookup_context_locked( dhrcSource );
    dst = stw_lookup_context_locked( dhrcDest );

    if (src && dst) {
        /* FIXME */
        assert(0);
        (void) src;
        (void) dst;
        (void) fuMask;
    }

    pipe_mutex_unlock( stw_dev->ctx_mutex );

    return ret;
}
Ejemplo n.º 2
0
BOOL APIENTRY
DrvReleaseContext(
    DHGLRC dhglrc )
{
    struct stw_context *ctx;

    if (!stw_dev)
        return FALSE;

    pipe_mutex_lock( stw_dev->ctx_mutex );
    ctx = stw_lookup_context_locked( dhglrc );
    pipe_mutex_unlock( stw_dev->ctx_mutex );

    if (!ctx)
        return FALSE;

    /* The expectation is that ctx is the same context which is
     * current for this thread.  We should check that and return False
     * if not the case.
     */
    if (ctx != stw_current_context())
        return FALSE;

    if (stw_make_current( NULL, 0 ) == FALSE)
        return FALSE;

    return TRUE;
}
Ejemplo n.º 3
0
BOOL APIENTRY
DrvDeleteContext(
    DHGLRC dhglrc )
{
    struct stw_context *ctx ;
    BOOL ret = FALSE;

    if (!stw_dev)
        return FALSE;

    pipe_mutex_lock( stw_dev->ctx_mutex );
    ctx = stw_lookup_context_locked(dhglrc);
    handle_table_remove(stw_dev->ctx_table, dhglrc);
    pipe_mutex_unlock( stw_dev->ctx_mutex );

    if (ctx) {
        struct stw_context *curctx = stw_current_context();

        /* Unbind current if deleting current context. */
        if (curctx == ctx)
            stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);

        if (ctx->hud) {
            hud_destroy(ctx->hud);
        }

        ctx->st->destroy(ctx->st);
        FREE(ctx);

        ret = TRUE;
    }

    return ret;
}
Ejemplo n.º 4
0
BOOL APIENTRY
DrvShareLists(
    DHGLRC dhglrc1,
    DHGLRC dhglrc2 )
{
    struct stw_context *ctx1;
    struct stw_context *ctx2;
    BOOL ret = FALSE;

    if (!stw_dev)
        return FALSE;

    pipe_mutex_lock( stw_dev->ctx_mutex );

    ctx1 = stw_lookup_context_locked( dhglrc1 );
    ctx2 = stw_lookup_context_locked( dhglrc2 );

    if (ctx1 && ctx2 && ctx2->st->share)
        ret = ctx2->st->share(ctx2->st, ctx1->st);

    pipe_mutex_unlock( stw_dev->ctx_mutex );

    return ret;
}
Ejemplo n.º 5
0
BOOL
stw_make_current(
    HDC hdc,
    DHGLRC dhglrc )
{
    struct stw_context *curctx = NULL;
    struct stw_context *ctx = NULL;
    struct stw_framebuffer *fb = NULL;
    BOOL ret = FALSE;

    if (!stw_dev)
        return FALSE;

    curctx = stw_current_context();
    if (curctx != NULL) {
        if (curctx->dhglrc == dhglrc) {
            if (curctx->hdc == hdc) {
                /* Return if already current. */
                return TRUE;
            }
        } else {
            curctx->st->flush(curctx->st, ST_FLUSH_FRONT, NULL);
        }
    }

    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;
        }

        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 (fb->iPixelFormat != ctx->iPixelFormat) {
            SetLastError(ERROR_INVALID_PIXEL_FORMAT);
            goto fail;
        }

        /* Bind the new framebuffer */
        ctx->hdc = hdc;

        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);
    }

fail:

    if (fb) {
        stw_framebuffer_release(fb);
    }

    /* 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;
}
Ejemplo n.º 6
0
/**
 * Called via DrvCreateContext(), DrvCreateLayerContext() and
 * wglCreateContextAttribsARB() to actually create a rendering context.
 * \param handle  the desired DHGLRC handle to use for the context, or zero
 *                if a new handle should be allocated.
 * \return the handle for the new context or zero if there was a problem.
 */
DHGLRC
stw_create_context_attribs(HDC hdc, INT iLayerPlane, DHGLRC hShareContext,
                           int majorVersion, int minorVersion,
                           int contextFlags, int profileMask,
                           DHGLRC handle)
{
    int iPixelFormat;
    struct stw_framebuffer *fb;
    const struct stw_pixelformat_info *pfi;
    struct st_context_attribs attribs;
    struct stw_context *ctx = NULL;
    struct stw_context *shareCtx = NULL;
    enum st_context_error ctx_err = 0;

    if (!stw_dev)
        return 0;

    if (iLayerPlane != 0)
        return 0;

    iPixelFormat = GetPixelFormat(hdc);
    if(!iPixelFormat)
        return 0;

    /*
     * GDI only knows about displayable pixel formats, so determine the pixel
     * format from the framebuffer.
     *
     * TODO: Remove the GetPixelFormat() above, and stop relying on GDI.
     */
    fb = stw_framebuffer_from_hdc( hdc );
    if (fb) {
        assert(iPixelFormat == fb->iDisplayablePixelFormat);
        iPixelFormat = fb->iPixelFormat;
        stw_framebuffer_release(fb);
    }

    pfi = stw_pixelformat_get_info( iPixelFormat );

    if (hShareContext != 0) {
        pipe_mutex_lock( stw_dev->ctx_mutex );
        shareCtx = stw_lookup_context_locked( hShareContext );
        pipe_mutex_unlock( stw_dev->ctx_mutex );
    }

    ctx = CALLOC_STRUCT( stw_context );
    if (ctx == NULL)
        goto no_ctx;

    ctx->hdc = hdc;
    ctx->iPixelFormat = iPixelFormat;

    memset(&attribs, 0, sizeof(attribs));
    attribs.visual = pfi->stvis;
    attribs.major = majorVersion;
    attribs.minor = minorVersion;
    if (contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB)
        attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE;
    if (contextFlags & WGL_CONTEXT_DEBUG_BIT_ARB)
        attribs.flags |= ST_CONTEXT_FLAG_DEBUG;

    switch (profileMask) {
    case WGL_CONTEXT_CORE_PROFILE_BIT_ARB:
        /* There are no profiles before OpenGL 3.2.  The
         * WGL_ARB_create_context_profile spec says:
         *
         *     "If the requested OpenGL version is less than 3.2,
         *     WGL_CONTEXT_PROFILE_MASK_ARB is ignored and the functionality
         *     of the context is determined solely by the requested version."
         */
        if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 2)) {
            attribs.profile = ST_PROFILE_OPENGL_CORE;
            break;
        }
    /* fall-through */
    case WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:
        /*
         * The spec also says:
         *
         *     "If version 3.1 is requested, the context returned may implement
         *     any of the following versions:
         *
         *       * Version 3.1. The GL_ARB_compatibility extension may or may not
         *         be implemented, as determined by the implementation.
         *       * The core profile of version 3.2 or greater."
         *
         * and because Mesa doesn't support GL_ARB_compatibility, the only chance to
         * honour a 3.1 context is through core profile.
         */
        if (majorVersion == 3 && minorVersion == 1) {
            attribs.profile = ST_PROFILE_OPENGL_CORE;
        } else {
            attribs.profile = ST_PROFILE_DEFAULT;
        }
        break;
    case WGL_CONTEXT_ES_PROFILE_BIT_EXT:
        if (majorVersion >= 2) {
            attribs.profile = ST_PROFILE_OPENGL_ES2;
        } else {
            attribs.profile = ST_PROFILE_OPENGL_ES1;
        }
        break;
    default:
        assert(0);
        goto no_st_ctx;
    }

    ctx->st = stw_dev->stapi->create_context(stw_dev->stapi,
              stw_dev->smapi, &attribs, &ctx_err, shareCtx ? shareCtx->st : NULL);
    if (ctx->st == NULL)
        goto no_st_ctx;

    ctx->st->st_manager_private = (void *) ctx;

    if (ctx->st->cso_context) {
        ctx->hud = hud_create(ctx->st->pipe, ctx->st->cso_context);
    }

    pipe_mutex_lock( stw_dev->ctx_mutex );
    if (handle) {
        /* We're replacing the context data for this handle. See the
         * wglCreateContextAttribsARB() function.
         */
        struct stw_context *old_ctx =
            stw_lookup_context_locked((unsigned) handle);
        if (old_ctx) {
            /* free the old context data associated with this handle */
            if (old_ctx->hud) {
                hud_destroy(old_ctx->hud);
            }
            ctx->st->destroy(old_ctx->st);
            FREE(old_ctx);
        }

        /* replace table entry */
        handle_table_set(stw_dev->ctx_table, (unsigned) handle, ctx);
    }
    else {
        /* create new table entry */
        handle = (DHGLRC) handle_table_add(stw_dev->ctx_table, ctx);
    }

    ctx->dhglrc = handle;

    pipe_mutex_unlock( stw_dev->ctx_mutex );
    if (!ctx->dhglrc)
        goto no_hglrc;

    return ctx->dhglrc;

no_hglrc:
    if (ctx->hud) {
        hud_destroy(ctx->hud);
    }
    ctx->st->destroy(ctx->st);
no_st_ctx:
    FREE(ctx);
no_ctx:
    return 0;
}
Ejemplo n.º 7
0
DHGLRC
stw_create_context_attribs(
   HDC hdc,
   INT iLayerPlane,
   DHGLRC hShareContext,
   int majorVersion, int minorVersion,
   int contextFlags, int profileMask)
{
   int iPixelFormat;
   struct stw_framebuffer *fb;
   const struct stw_pixelformat_info *pfi;
   struct st_context_attribs attribs;
   struct stw_context *ctx = NULL;
   struct stw_context *shareCtx = NULL;
   enum st_context_error ctx_err = 0;

   if (!stw_dev)
      return 0;

   if (iLayerPlane != 0)
      return 0;

   iPixelFormat = GetPixelFormat(hdc);
   if(!iPixelFormat)
      return 0;

   /*
    * GDI only knows about displayable pixel formats, so determine the pixel format
    * from the framebuffer.
    *
    * TODO: Remove the GetPixelFormat() above, and stop relying on GDI.
    */
   fb = stw_framebuffer_from_hdc( hdc );
   if (fb) {
      assert(iPixelFormat == fb->iDisplayablePixelFormat);
      iPixelFormat = fb->iPixelFormat;
      stw_framebuffer_release(fb);
   }

   pfi = stw_pixelformat_get_info( iPixelFormat );

   if (hShareContext != 0) {
      pipe_mutex_lock( stw_dev->ctx_mutex );
      shareCtx = stw_lookup_context_locked( hShareContext );
      pipe_mutex_unlock( stw_dev->ctx_mutex );
   }

   ctx = CALLOC_STRUCT( stw_context );
   if (ctx == NULL)
      goto no_ctx;

   ctx->hdc = hdc;
   ctx->iPixelFormat = iPixelFormat;

   memset(&attribs, 0, sizeof(attribs));
   attribs.visual = pfi->stvis;
   attribs.major = majorVersion;
   attribs.minor = minorVersion;
   if (contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB)
      attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE;
   if (contextFlags & WGL_CONTEXT_DEBUG_BIT_ARB)
      attribs.flags |= ST_CONTEXT_FLAG_DEBUG;

   /* There are no profiles before OpenGL 3.2.  The
    * WGL_ARB_create_context_profile spec says:
    *
    *     "If the requested OpenGL version is less than 3.2,
    *     WGL_CONTEXT_PROFILE_MASK_ARB is ignored and the functionality of the
    *     context is determined solely by the requested version."
    *
    * The spec also says:
    *
    *     "The default value for WGL_CONTEXT_PROFILE_MASK_ARB is
    *     WGL_CONTEXT_CORE_PROFILE_BIT_ARB."
    */
   attribs.profile = ST_PROFILE_DEFAULT;
   if ((majorVersion > 3 || (majorVersion == 3 && minorVersion >= 2))
       && ((profileMask & WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB) == 0))
      attribs.profile = ST_PROFILE_OPENGL_CORE;

   ctx->st = stw_dev->stapi->create_context(stw_dev->stapi,
         stw_dev->smapi, &attribs, &ctx_err, shareCtx ? shareCtx->st : NULL);
   if (ctx->st == NULL)
      goto no_st_ctx;

   ctx->st->st_manager_private = (void *) ctx;

   pipe_mutex_lock( stw_dev->ctx_mutex );
   ctx->dhglrc = handle_table_add(stw_dev->ctx_table, ctx);
   pipe_mutex_unlock( stw_dev->ctx_mutex );
   if (!ctx->dhglrc)
      goto no_hglrc;

   return ctx->dhglrc;

no_hglrc:
   ctx->st->destroy(ctx->st);
no_st_ctx:
   FREE(ctx);
no_ctx:
   return 0;
}