return EGL_TRUE;
}
-/**
- * Return the current context of the given API.
- */
-static struct egl_g3d_context *
-egl_g3d_get_current_context(EGLint api)
-{
- _EGLThreadInfo *t = _eglGetCurrentThread();
- EGLint api_index = _eglConvertApiToIndex(api);
- return egl_g3d_context(t->CurrentContexts[api_index]);
-}
-
/**
* Return the state tracker for the given context.
*/
struct egl_g3d_config *gconf;
EGLBoolean valid;
+ gconf = CALLOC_STRUCT(egl_g3d_config);
+ if (!gconf)
+ continue;
+
+ _eglInitConfig(&gconf->base, dpy, id);
+
api_mask = get_mode_api_mask(&native_configs[i]->mode, gdrv->api_mask);
if (!api_mask) {
_eglLog(_EGL_DEBUG, "no state tracker supports config 0x%x",
native_configs[i]->mode.visualID);
- continue;
}
- gconf = CALLOC_STRUCT(egl_g3d_config);
- if (!gconf)
- continue;
-
- _eglInitConfig(&gconf->base, id);
valid = _eglConfigFromContextModesRec(&gconf->base,
&native_configs[i]->mode, api_mask, api_mask);
if (valid) {
* Set force_validate to skip an unnecessary check.
*/
gctx->force_validate = EGL_TRUE;
- egl_g3d_validate_context(gctx->base.Display, &gctx->base);
+ egl_g3d_validate_context(gctx->base.Resource.Display, &gctx->base);
}
static EGLBoolean
return NULL;
}
- if (!_eglInitContext(drv, &gctx->base, conf, attribs)) {
+ if (!_eglInitContext(&gctx->base, dpy, conf, attribs)) {
free(gctx);
return NULL;
}
return &gctx->base;
}
-static EGLBoolean
-egl_g3d_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
+/**
+ * Destroy a context.
+ */
+static void
+destroy_context(_EGLDisplay *dpy, _EGLContext *ctx)
{
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
- if (_eglIsContextBound(&gctx->base))
- return EGL_TRUE;
+ /* FIXME a context might live longer than its display */
+ if (!dpy->Initialized)
+ _eglLog(_EGL_FATAL, "destroy a context with an unitialized display");
egl_g3d_realloc_context(dpy, &gctx->base);
-
- /* it will destroy pipe context */
+ /* it will destroy the associated pipe context */
gctx->stapi->st_destroy_context(gctx->st_ctx);
free(gctx);
+}
+static EGLBoolean
+egl_g3d_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
+{
+ if (!_eglIsContextBound(ctx))
+ destroy_context(dpy, ctx);
return EGL_TRUE;
}
return NULL;
}
- if (!_eglInitSurface(drv, &gsurf->base, EGL_WINDOW_BIT, conf, attribs)) {
+ if (!_eglInitSurface(&gsurf->base, dpy, EGL_WINDOW_BIT, conf, attribs)) {
free(gsurf);
return NULL;
}
return NULL;
}
- if (!_eglInitSurface(drv, &gsurf->base, EGL_PIXMAP_BIT, conf, attribs)) {
+ if (!_eglInitSurface(&gsurf->base, dpy, EGL_PIXMAP_BIT, conf, attribs)) {
free(gsurf);
return NULL;
}
return NULL;
}
- if (!_eglInitSurface(drv, &gsurf->base, EGL_PBUFFER_BIT, conf, attribs)) {
+ if (!_eglInitSurface(&gsurf->base, dpy, EGL_PBUFFER_BIT, conf, attribs)) {
free(gsurf);
return NULL;
}
return &gsurf->base;
}
-static EGLBoolean
-egl_g3d_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
+/**
+ * Destroy a surface.
+ */
+static void
+destroy_surface(_EGLDisplay *dpy, _EGLSurface *surf)
{
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
- if (_eglIsSurfaceBound(&gsurf->base))
- return EGL_TRUE;
+ /* FIXME a surface might live longer than its display */
+ if (!dpy->Initialized)
+ _eglLog(_EGL_FATAL, "destroy a surface with an unitialized display");
pipe_surface_reference(&gsurf->render_surface, NULL);
gsurf->native->destroy(gsurf->native);
free(gsurf);
+}
+
+static EGLBoolean
+egl_g3d_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
+{
+ if (!_eglIsSurfaceBound(surf))
+ destroy_surface(dpy, surf);
return EGL_TRUE;
}
_EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx)
{
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+ struct egl_g3d_surface *gdraw = egl_g3d_surface(draw);
struct egl_g3d_context *old_gctx;
- EGLint api;
EGLBoolean ok = EGL_TRUE;
- /* find the old context */
- api = (gctx) ? gctx->base.ClientAPI : eglQueryAPI();
- old_gctx = egl_g3d_get_current_context(api);
- if (old_gctx && !_eglIsContextLinked(&old_gctx->base))
- old_gctx = NULL;
-
- if (!_eglMakeCurrent(drv, dpy, draw, read, ctx))
+ /* bind the new context and return the "orphaned" one */
+ if (!_eglBindContext(&ctx, &draw, &read))
return EGL_FALSE;
+ old_gctx = egl_g3d_context(ctx);
if (old_gctx) {
/* flush old context */
}
if (gctx) {
- struct egl_g3d_surface *gdraw = egl_g3d_surface(draw);
-
ok = egl_g3d_realloc_context(dpy, &gctx->base);
if (ok) {
ok = gctx->stapi->st_make_current(gctx->st_ctx,
old_gctx->base.WindowRenderBuffer = EGL_NONE;
}
+ if (ctx && !_eglIsContextLinked(ctx))
+ destroy_context(dpy, ctx);
+ if (draw && !_eglIsSurfaceLinked(draw))
+ destroy_surface(dpy, draw);
+ if (read && read != draw && !_eglIsSurfaceLinked(read))
+ destroy_surface(dpy, read);
+
return ok;
}
static EGLBoolean
egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
- NativePixmapType target)
+ EGLNativePixmapType target)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
static EGLBoolean
egl_g3d_wait_native(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine)
{
- _EGLSurface *surf = _eglGetCurrentSurface(EGL_DRAW);
- struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+ _EGLContext *ctx = _eglGetCurrentContext();
if (engine != EGL_CORE_NATIVE_ENGINE)
return _eglError(EGL_BAD_PARAMETER, "eglWaitNative");
- if (gsurf)
+ if (ctx && ctx->DrawSurface) {
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(ctx->DrawSurface);
gsurf->native->wait(gsurf->native);
+ }
return EGL_TRUE;
}
_EGLSurface *surf, EGLint buffer)
{
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
- struct egl_g3d_context *gctx;
+ _EGLContext *ctx = _eglGetAPIContext(EGL_OPENGL_ES_API);
+ struct egl_g3d_context *gctx = egl_g3d_context(ctx);
enum pipe_format target_format;
int target;
}
/* flush properly if the surface is bound */
- if (gsurf->base.Binding) {
- gctx = egl_g3d_context(gsurf->base.Binding);
+ if (gsurf->base.CurrentContext) {
+ gctx = egl_g3d_context(gsurf->base.CurrentContext);
gctx->stapi->st_flush(gctx->st_ctx,
PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
}
- /* XXX change to EGL_OPENGL_ES_API once OpenGL ES is merged */
- gctx = egl_g3d_get_current_context(EGL_OPENGL_API);
if (gctx) {
if (!gsurf->render_surface)
return EGL_FALSE;
return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
if (gsurf->render_surface) {
- _EGLThreadInfo *t = _eglGetCurrentThread();
- /* XXX change to EGL_OPENGL_ES_API once OpenGL ES is merged */
- struct egl_g3d_context *gctx = egl_g3d_context(
- t->CurrentContexts[_eglConvertApiToIndex(EGL_OPENGL_API)]);
+ _EGLContext *ctx = _eglGetAPIContext(EGL_OPENGL_ES_API);
+ struct egl_g3d_context *gctx = egl_g3d_context(ctx);
/* what if the context the surface binds to is no longer current? */
if (gctx)
return NULL;
}
- if (!_eglInitSurface(drv, &gsurf->base,
+ if (!_eglInitSurface(&gsurf->base, dpy,
EGL_SCREEN_BIT_MESA, conf, attribs)) {
free(gsurf);
return NULL;