예제 #1
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;
}
예제 #2
0
/**
 * Create a new XMesaContext.
 * \param v  the XMesaVisual
 * \param share_list  another XMesaContext with which to share display
 *                    lists or NULL if no sharing is wanted.
 * \return an XMesaContext or NULL if error.
 */
PUBLIC
XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list,
                                 GLuint major, GLuint minor,
                                 GLuint profileMask, GLuint contextFlags)
{
   XMesaDisplay xmdpy = xmesa_init_display(v->display);
   struct st_context_attribs attribs;
   enum st_context_error ctx_err = 0;
   XMesaContext c;

   if (!xmdpy)
      goto no_xmesa_context;

   /* Note: the XMesaContext contains a Mesa struct gl_context struct (inheritance) */
   c = (XMesaContext) CALLOC_STRUCT(xmesa_context);
   if (!c)
      goto no_xmesa_context;

   c->xm_visual = v;
   c->xm_buffer = NULL;   /* set later by XMesaMakeCurrent */
   c->xm_read_buffer = NULL;

   memset(&attribs, 0, sizeof(attribs));
   attribs.visual = v->stvis;
   attribs.major = major;
   attribs.minor = minor;
   if (contextFlags & GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB)
      attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE;
   if (contextFlags & GLX_CONTEXT_DEBUG_BIT_ARB)
      attribs.flags |= ST_CONTEXT_FLAG_DEBUG;
   if (contextFlags & GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB)
      attribs.flags |= ST_CONTEXT_FLAG_ROBUST_ACCESS;

   switch (profileMask) {
   case GLX_CONTEXT_CORE_PROFILE_BIT_ARB:
      /* There are no profiles before OpenGL 3.2.  The
       * GLX_ARB_create_context_profile spec says:
       *
       *     "If the requested OpenGL version is less than 3.2,
       *     GLX_CONTEXT_PROFILE_MASK_ARB is ignored and the functionality
       *     of the context is determined solely by the requested version."
       */
      if (major > 3 || (major == 3 && minor >= 2)) {
         attribs.profile = ST_PROFILE_OPENGL_CORE;
         break;
      }
      /* fall-through */
   case GLX_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 (major == 3 && minor == 1) {
         attribs.profile = ST_PROFILE_OPENGL_CORE;
      } else {
         attribs.profile = ST_PROFILE_DEFAULT;
      }
      break;
   case GLX_CONTEXT_ES_PROFILE_BIT_EXT:
      if (major >= 2) {
         attribs.profile = ST_PROFILE_OPENGL_ES2;
      } else {
         attribs.profile = ST_PROFILE_OPENGL_ES1;
      }
      break;
   default:
      assert(0);
      goto no_st;
   }

   c->st = stapi->create_context(stapi, xmdpy->smapi, &attribs,
         &ctx_err, (share_list) ? share_list->st : NULL);
   if (c->st == NULL)
      goto no_st;

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

   c->hud = hud_create(c->st->cso_context, NULL);

   return c;

no_st:
   free(c);
no_xmesa_context:
   return NULL;
}
예제 #3
0
파일: xm_api.c 프로젝트: gregory38/mesa-sso
/**
 * Create a new XMesaContext.
 * \param v  the XMesaVisual
 * \param share_list  another XMesaContext with which to share display
 *                    lists or NULL if no sharing is wanted.
 * \return an XMesaContext or NULL if error.
 */
PUBLIC
XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list,
                                 GLuint major, GLuint minor,
                                 GLuint profileMask, GLuint contextFlags)
{
   XMesaDisplay xmdpy = xmesa_init_display(v->display);
   struct st_context_attribs attribs;
   enum st_context_error ctx_err = 0;
   XMesaContext c;

   if (!xmdpy)
      return NULL;

   /* Note: the XMesaContext contains a Mesa struct gl_context struct (inheritance) */
   c = (XMesaContext) CALLOC_STRUCT(xmesa_context);
   if (!c)
      return NULL;

   c->xm_visual = v;
   c->xm_buffer = NULL;   /* set later by XMesaMakeCurrent */
   c->xm_read_buffer = NULL;

   memset(&attribs, 0, sizeof(attribs));
   attribs.visual = v->stvis;
   attribs.major = major;
   attribs.minor = minor;
   if (contextFlags & GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB)
      attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE;
   if (contextFlags & GLX_CONTEXT_DEBUG_BIT_ARB)
      attribs.flags |= ST_CONTEXT_FLAG_DEBUG;
   if (contextFlags & GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB)
      attribs.flags |= ST_CONTEXT_FLAG_ROBUST_ACCESS;

   /* There are no profiles before OpenGL 3.2.  The
    * GLX_ARB_create_context_profile spec says:
    *
    *     "If the requested OpenGL version is less than 3.2,
    *     GLX_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 GLX_CONTEXT_PROFILE_MASK_ARB is
    *     GLX_CONTEXT_CORE_PROFILE_BIT_ARB."
    */
   attribs.profile = ST_PROFILE_DEFAULT;
   if ((major > 3 || (major == 3 && minor >= 2))
       && ((profileMask & GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB) == 0))
      attribs.profile = ST_PROFILE_OPENGL_CORE;

   c->st = stapi->create_context(stapi, xmdpy->smapi, &attribs,
         &ctx_err, (share_list) ? share_list->st : NULL);
   if (c->st == NULL)
      goto fail;

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

   c->hud = hud_create(c->st->pipe, c->st->cso_context);

   return c;

fail:
   if (c->st)
      c->st->destroy(c->st);

   free(c);
   return NULL;
}
GLboolean
dri_create_context(gl_api api, const struct gl_config * visual,
		   __DRIcontext * cPriv,
		   unsigned major_version,
		   unsigned minor_version,
		   uint32_t flags,
                   bool notify_reset,
		   unsigned *error,
		   void *sharedContextPrivate)
{
   __DRIscreen *sPriv = cPriv->driScreenPriv;
   struct dri_screen *screen = dri_screen(sPriv);
   struct st_api *stapi = screen->st_api;
   struct dri_context *ctx = NULL;
   struct st_context_iface *st_share = NULL;
   struct st_context_attribs attribs;
   enum st_context_error ctx_err = 0;

   memset(&attribs, 0, sizeof(attribs));
   switch (api) {
   case API_OPENGLES:
      attribs.profile = ST_PROFILE_OPENGL_ES1;
      break;
   case API_OPENGLES2:
      attribs.profile = ST_PROFILE_OPENGL_ES2;
      break;
   case API_OPENGL_COMPAT:
   case API_OPENGL_CORE:
      attribs.profile = api == API_OPENGL_COMPAT ? ST_PROFILE_DEFAULT
                                                 : ST_PROFILE_OPENGL_CORE;
      attribs.major = major_version;
      attribs.minor = minor_version;

      if ((flags & __DRI_CTX_FLAG_DEBUG) != 0)
	 attribs.flags |= ST_CONTEXT_FLAG_DEBUG;

      if ((flags & __DRI_CTX_FLAG_FORWARD_COMPATIBLE) != 0)
	 attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE;
      break;
   default:
      *error = __DRI_CTX_ERROR_BAD_API;
      goto fail;
   }

   if (flags & ~(__DRI_CTX_FLAG_DEBUG | __DRI_CTX_FLAG_FORWARD_COMPATIBLE)) {
      *error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
      goto fail;
   }

   if (notify_reset) {
      *error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
      goto fail;
   }

   if (sharedContextPrivate) {
      st_share = ((struct dri_context *)sharedContextPrivate)->st;
   }

   ctx = CALLOC_STRUCT(dri_context);
   if (ctx == NULL) {
      *error = __DRI_CTX_ERROR_NO_MEMORY;
      goto fail;
   }

   cPriv->driverPrivate = ctx;
   ctx->cPriv = cPriv;
   ctx->sPriv = sPriv;

   dri_fill_st_options(&attribs.options, &screen->optionCache);
   dri_fill_st_visual(&attribs.visual, screen, visual);
   ctx->st = stapi->create_context(stapi, &screen->base, &attribs, &ctx_err,
				   st_share);
   if (ctx->st == NULL) {
      switch (ctx_err) {
      case ST_CONTEXT_SUCCESS:
	 *error = __DRI_CTX_ERROR_SUCCESS;
	 break;
      case ST_CONTEXT_ERROR_NO_MEMORY:
	 *error = __DRI_CTX_ERROR_NO_MEMORY;
	 break;
      case ST_CONTEXT_ERROR_BAD_API:
	 *error = __DRI_CTX_ERROR_BAD_API;
	 break;
      case ST_CONTEXT_ERROR_BAD_VERSION:
	 *error = __DRI_CTX_ERROR_BAD_VERSION;
	 break;
      case ST_CONTEXT_ERROR_BAD_FLAG:
	 *error = __DRI_CTX_ERROR_BAD_FLAG;
	 break;
      case ST_CONTEXT_ERROR_UNKNOWN_ATTRIBUTE:
	 *error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
	 break;
      case ST_CONTEXT_ERROR_UNKNOWN_FLAG:
	 *error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
	 break;
      }
      goto fail;
   }
   ctx->st->st_manager_private = (void *) ctx;
   ctx->stapi = stapi;

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

   *error = __DRI_CTX_ERROR_SUCCESS;
   return GL_TRUE;

 fail:
   if (ctx && ctx->st)
      ctx->st->destroy(ctx->st);

   free(ctx);
   return GL_FALSE;
}