static EGLBoolean egl_g3d_release_tex_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint buffer) { struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT || !gsurf->base.BoundToTexture) return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage"); if (buffer != EGL_BACK_BUFFER) return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage"); if (gsurf->render_texture) { _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) { gctx->stctxi->teximage(gctx->stctxi, ST_TEXTURE_2D, gsurf->base.MipmapLevel, PIPE_FORMAT_NONE, NULL, FALSE); } } gsurf->base.BoundToTexture = EGL_FALSE; return EGL_TRUE; }
static EGLBoolean egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint buffer) { struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); _EGLContext *es1 = _eglGetAPIContext(EGL_OPENGL_ES_API); struct egl_g3d_context *gctx; enum pipe_format internal_format; enum st_texture_type target; if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT) return _eglError(EGL_BAD_SURFACE, "eglBindTexImage"); if (buffer != EGL_BACK_BUFFER) return _eglError(EGL_BAD_PARAMETER, "eglBindTexImage"); if (gsurf->base.BoundToTexture) return _eglError(EGL_BAD_ACCESS, "eglBindTexImage"); switch (gsurf->base.TextureFormat) { case EGL_TEXTURE_RGB: internal_format = PIPE_FORMAT_R8G8B8_UNORM; break; case EGL_TEXTURE_RGBA: internal_format = PIPE_FORMAT_B8G8R8A8_UNORM; break; default: return _eglError(EGL_BAD_MATCH, "eglBindTexImage"); } switch (gsurf->base.TextureTarget) { case EGL_TEXTURE_2D: target = ST_TEXTURE_2D; break; default: return _eglError(EGL_BAD_MATCH, "eglBindTexImage"); } if (!es1) return EGL_TRUE; if (!gsurf->render_texture) return EGL_FALSE; /* flush properly if the surface is bound */ if (gsurf->base.CurrentContext) { gctx = egl_g3d_context(gsurf->base.CurrentContext); gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, NULL); } gctx = egl_g3d_context(es1); if (gctx->stctxi->teximage) { if (!gctx->stctxi->teximage(gctx->stctxi, target, gsurf->base.MipmapLevel, internal_format, gsurf->render_texture, gsurf->base.MipmapTexture)) return EGL_FALSE; gsurf->base.BoundToTexture = EGL_TRUE; } return EGL_TRUE; }
/** * Return true if the given context and surfaces can be made current. */ static EGLBoolean _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read) { _EGLThreadInfo *t = _eglGetCurrentThread(); _EGLDisplay *dpy; EGLint conflict_api; if (_eglIsCurrentThreadDummy()) return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent"); /* this is easy */ if (!ctx) { if (draw || read) return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); return EGL_TRUE; } dpy = ctx->Resource.Display; if (!dpy->Extensions.KHR_surfaceless_context && (draw == NULL || read == NULL)) return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); /* * The spec says * * "If ctx is current to some other thread, or if either draw or read are * bound to contexts in another thread, an EGL_BAD_ACCESS error is * generated." * * and * * "at most one context may be bound to a particular surface at a given * time" */ if (ctx->Binding && ctx->Binding != t) return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); if (draw && draw->CurrentContext && draw->CurrentContext != ctx) { if (draw->CurrentContext->Binding != t || draw->CurrentContext->ClientAPI != ctx->ClientAPI) return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); } if (read && read->CurrentContext && read->CurrentContext != ctx) { if (read->CurrentContext->Binding != t || read->CurrentContext->ClientAPI != ctx->ClientAPI) return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); } /* simply require the configs to be equal */ if ((draw && draw->Config != ctx->Config) || (read && read->Config != ctx->Config)) return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); switch (ctx->ClientAPI) { /* OpenGL and OpenGL ES are conflicting */ case EGL_OPENGL_ES_API: conflict_api = EGL_OPENGL_API; break; case EGL_OPENGL_API: conflict_api = EGL_OPENGL_ES_API; break; default: conflict_api = -1; break; } if (conflict_api >= 0 && _eglGetAPIContext(conflict_api)) return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); return EGL_TRUE; }
/** * Return true if the given context and surfaces can be made current. */ static EGLBoolean _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read) { _EGLThreadInfo *t = _eglGetCurrentThread(); _EGLDisplay *dpy; EGLint conflict_api; if (_eglIsCurrentThreadDummy()) return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent"); /* this is easy */ if (!ctx) { if (draw || read) return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); return EGL_TRUE; } dpy = ctx->Resource.Display; if (!dpy->Extensions.KHR_surfaceless_context && (draw == NULL || read == NULL)) return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); /* * The spec says * * "If ctx is current to some other thread, or if either draw or read are * bound to contexts in another thread, an EGL_BAD_ACCESS error is * generated." * * and * * "at most one context may be bound to a particular surface at a given * time" */ if (ctx->Binding && ctx->Binding != t) return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); if (draw && draw->CurrentContext && draw->CurrentContext != ctx) { if (draw->CurrentContext->Binding != t || draw->CurrentContext->ClientAPI != ctx->ClientAPI) return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); } if (read && read->CurrentContext && read->CurrentContext != ctx) { if (read->CurrentContext->Binding != t || read->CurrentContext->ClientAPI != ctx->ClientAPI) return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); } /* If the context has a config then it must match that of the two * surfaces */ if (ctx->Config) { if ((draw && draw->Config != ctx->Config) || (read && read->Config != ctx->Config)) return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); } else { /* Otherwise we must be using the EGL_MESA_configless_context * extension */ assert(dpy->Extensions.MESA_configless_context); /* The extension doesn't permit binding draw and read buffers with * differing contexts */ if (draw && read && draw->Config != read->Config) return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); } switch (ctx->ClientAPI) { /* OpenGL and OpenGL ES are conflicting */ case EGL_OPENGL_ES_API: conflict_api = EGL_OPENGL_API; break; case EGL_OPENGL_API: conflict_api = EGL_OPENGL_ES_API; break; default: conflict_api = -1; break; } if (conflict_api >= 0 && _eglGetAPIContext(conflict_api)) return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); return EGL_TRUE; }
/** * Return true if the given context and surfaces can be made current. */ static EGLBoolean _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read) { _EGLThreadInfo *t = _eglGetCurrentThread(); EGLint conflict_api; if (_eglIsCurrentThreadDummy()) return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent"); /* this is easy */ if (!ctx) { if (draw || read) return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); return EGL_TRUE; } /* ctx/draw/read must be all given */ if (draw == NULL || read == NULL) return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); /* context stealing from another thread is not allowed */ if (ctx->Binding && ctx->Binding != t) return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); /* * The spec says * * "If ctx is current to some other thread, or if either draw or read are * bound to contexts in another thread, an EGL_BAD_ACCESS error is * generated." * * But it also says * * "at most one context may be bound to a particular surface at a given * time" * * The latter is more restrictive so we can check only the latter case. */ if ((draw->CurrentContext && draw->CurrentContext != ctx) || (read->CurrentContext && read->CurrentContext != ctx)) return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); /* simply require the configs to be equal */ if (draw->Config != ctx->Config || read->Config != ctx->Config) return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); switch (ctx->ClientAPI) { #ifdef EGL_VERSION_1_4 /* OpenGL and OpenGL ES are conflicting */ case EGL_OPENGL_ES_API: conflict_api = EGL_OPENGL_API; break; case EGL_OPENGL_API: conflict_api = EGL_OPENGL_ES_API; break; #endif default: conflict_api = -1; break; } if (conflict_api >= 0 && _eglGetAPIContext(conflict_api)) return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); return EGL_TRUE; }