st/dri: Add multi-api support

Make st/dri screens capable of creating OpenGL ES and
OpenGL ES2 contexts.

TODO: Figure out the "get_current" problem with multiple
st_api's for real.

(s/API_OPENGLES1/API_OPENGLES/ by Chia-I Wu)
This commit is contained in:
nobled 2010-08-30 20:23:54 +00:00 committed by Chia-I Wu
parent ecd7ec9d62
commit 8e3b658b7f
5 changed files with 45 additions and 12 deletions

View File

@ -54,12 +54,14 @@ dri_create_context(gl_api api, const __GLcontextModes * visual,
{
__DRIscreen *sPriv = cPriv->driScreenPriv;
struct dri_screen *screen = dri_screen(sPriv);
struct st_api *stapi = screen->st_api;
struct st_api *stapi;
struct dri_context *ctx = NULL;
struct st_context_iface *st_share = NULL;
struct st_visual stvis;
if (api != API_OPENGL)
assert(api <= API_OPENGLES2);
stapi = screen->st_api[api];
if (!stapi)
return GL_FALSE;
if (sharedContextPrivate) {
@ -71,6 +73,7 @@ dri_create_context(gl_api api, const __GLcontextModes * visual,
goto fail;
cPriv->driverPrivate = ctx;
ctx->api = api;
ctx->cPriv = cPriv;
ctx->sPriv = sPriv;
ctx->lock = screen->drmLock;
@ -124,7 +127,7 @@ dri_unbind_context(__DRIcontext * cPriv)
/* dri_util.c ensures cPriv is not null */
struct dri_screen *screen = dri_screen(cPriv->driScreenPriv);
struct dri_context *ctx = dri_context(cPriv);
struct st_api *stapi = screen->st_api;
struct st_api *stapi = screen->st_api[ctx->api];
if (--ctx->bind_count == 0) {
if (ctx->st == stapi->get_current(stapi)) {
@ -144,7 +147,7 @@ dri_make_current(__DRIcontext * cPriv,
/* dri_util.c ensures cPriv is not null */
struct dri_screen *screen = dri_screen(cPriv->driScreenPriv);
struct dri_context *ctx = dri_context(cPriv);
struct st_api *stapi = screen->st_api;
struct st_api *stapi = screen->st_api[ctx->api];
struct dri_drawable *draw = dri_drawable(driDrawPriv);
struct dri_drawable *read = dri_drawable(driReadPriv);
struct st_context_iface *old_st = stapi->get_current(stapi);
@ -172,10 +175,24 @@ struct dri_context *
dri_get_current(__DRIscreen *sPriv)
{
struct dri_screen *screen = dri_screen(sPriv);
struct st_api *stapi = screen->st_api;
struct st_context_iface *st;
struct st_api *stapi;
struct st_context_iface *st = NULL;
gl_api api;
st = stapi->get_current(stapi);
/* XXX: How do we do this when the screen supports
multiple rendering API's? Pick the first one,
like this? (NB: all three API's use the same
implementation of get_current (see st_manager.c),
so maybe it doesn't matter right now since
they'll all return the same result.) */
for (api = API_OPENGL; api <= API_OPENGLES2; ++api) {
stapi = screen->st_api[api];
if (!stapi)
continue;
st = stapi->get_current(stapi);
if (st)
break;
}
return (struct dri_context *) (st) ? st->st_manager_private : NULL;
}

View File

@ -58,6 +58,7 @@ struct dri_context
unsigned int bind_count;
/* gallium */
gl_api api;
struct st_context_iface *st;
/* hooks filled in by dri2 & drisw */

View File

@ -344,8 +344,10 @@ dri_destroy_option_cache(struct dri_screen * screen)
void
dri_destroy_screen_helper(struct dri_screen * screen)
{
if (screen->st_api && screen->st_api->destroy)
screen->st_api->destroy(screen->st_api);
gl_api api;
for (api = API_OPENGL; api <= API_OPENGLES2; ++api)
if (screen->st_api[api] && screen->st_api[api]->destroy)
screen->st_api[api]->destroy(screen->st_api[api]);
if (screen->base.screen)
screen->base.screen->destroy(screen->base.screen);
@ -378,9 +380,14 @@ dri_init_screen_helper(struct dri_screen *screen,
screen->base.get_egl_image = dri_get_egl_image;
screen->base.get_param = dri_get_param;
screen->st_api = st_gl_api_create();
if (!screen->st_api)
screen->st_api[API_OPENGL] = st_gl_api_create();
screen->st_api[API_OPENGLES1] = st_gl_api_create_es1();
screen->st_api[API_OPENGLES2] = st_gl_api_create_es2();
if (!screen->st_api[API_OPENGL] &&
!screen->st_api[API_OPENGLES1] &&
!screen->st_api[API_OPENGLES2])
return NULL;
if(pscreen->get_param(pscreen, PIPE_CAP_NPOT_TEXTURES))

View File

@ -47,7 +47,7 @@ struct dri_screen
{
/* st_api */
struct st_manager base;
struct st_api *st_api;
struct st_api *st_api[1+API_OPENGLES2]; /* GL, GLES1, GLES2 */
/* on old libGL's invalidate doesn't get called as it should */
boolean broken_invalidate;

View File

@ -439,6 +439,14 @@ dri2_init_screen(__DRIscreen * sPriv)
if (!configs)
goto fail;
sPriv->api_mask = 0;
if (screen->st_api[API_OPENGL])
sPriv->api_mask |= 1 << __DRI_API_OPENGL;
if (screen->st_api[API_OPENGLES1])
sPriv->api_mask |= 1 << __DRI_API_GLES;
if (screen->st_api[API_OPENGLES2])
sPriv->api_mask |= 1 << __DRI_API_GLES2;
screen->auto_fake_front = dri_with_format(sPriv);
screen->broken_invalidate = !sPriv->dri2.useInvalidate;