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