EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface) { if (!fglEGLValidateDisplay(dpy)) { setError(EGL_BAD_DISPLAY); return EGL_FALSE; } if (surface == EGL_NO_SURFACE) return EGL_TRUE; FGLRenderSurface *fglSurface = (FGLRenderSurface *)surface; if (!fglSurface->isValid() || fglSurface->isTerminated()) { setError(EGL_BAD_SURFACE); return EGL_FALSE; } if (fglSurface->ctx) { // Mark the surface for destruction on context detach fglSurface->terminate(); return EGL_TRUE; } delete fglSurface; return EGL_TRUE; }
EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) { if (!fglEGLValidateDisplay(dpy)) { setError(EGL_BAD_DISPLAY); return EGL_FALSE; } FGLRenderSurface *d = (FGLRenderSurface *)surface; if (!d->isValid() || d->isTerminated()) { setError(EGL_BAD_SURFACE); return EGL_FALSE; } /* Flush the context attached to the surface if it's current */ FGLContext *ctx = getGlThreadSpecific(); if ((FGLContext *)d->ctx == ctx) glFinish(); /* post the surface */ if (!d->swapBuffers()) /* Error code should have been set */ return EGL_FALSE; /* if it's bound to a context, update the buffer */ if (d->ctx != EGL_NO_CONTEXT) { FGLContext *c = (FGLContext *)d->ctx; d->bindDrawSurface(c); } return EGL_TRUE; }
EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) { /* * Do all the EGL sanity checks */ if (!fglEGLValidateDisplay(dpy)) { setError(EGL_BAD_DISPLAY); return EGL_FALSE; } if (read != draw) { setError(EGL_BAD_MATCH); return EGL_FALSE; } if (draw == EGL_NO_SURFACE && ctx != EGL_NO_CONTEXT) { setError(EGL_BAD_MATCH); return EGL_FALSE; } if (draw != EGL_NO_SURFACE && ctx == EGL_NO_CONTEXT) { setError(EGL_BAD_MATCH); return EGL_FALSE; } FGLRenderSurface *surface = (FGLRenderSurface *)draw; if (ctx != EGL_NO_CONTEXT) { if (surface->isTerminated() || !surface->isValid()) { setError(EGL_BAD_SURFACE); return EGL_FALSE; } if (surface->ctx && surface->ctx != ctx) { // already bound to another thread setError(EGL_BAD_ACCESS); return EGL_FALSE; } } /* * Proceed with the main part */ return fglMakeCurrent((FGLContext *)ctx, surface); }
/** * Unbinds context from rendering surface and client API. * Deletes the surface if it was marked for termination before. * Destroys the context if it was marked for termination before. * @param c Context to unbind. */ static void fglUnbindContext(FGLContext *c) { /* Make sure all the work finished */ glFinish(); /* Mark the context as not current anymore */ c->egl.flags &= ~FGL_IS_CURRENT; /* Unbind draw surface */ FGLRenderSurface *d = (FGLRenderSurface *)c->egl.draw; d->disconnect(); d->ctx = EGL_NO_CONTEXT; c->egl.draw = EGL_NO_SURFACE; /* Delete it if it's terminated */ if (d->isTerminated()) delete d; /* Delete the context if it's terminated */ if (c->egl.flags & FGL_TERMINATE) fglDestroyContext(c); }
EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value) { if (!fglEGLValidateDisplay(dpy)) { setError(EGL_BAD_DISPLAY); return EGL_FALSE; } FGLRenderSurface *fglSurface = static_cast<FGLRenderSurface *>(surface); if (!fglSurface->isValid() || fglSurface->isTerminated()) { setError(EGL_BAD_SURFACE); return EGL_FALSE; } EGLBoolean ret = EGL_TRUE; switch (attribute) { case EGL_CONFIG_ID: *value = (EGLint)fglSurface->config; break; case EGL_WIDTH: *value = fglSurface->getWidth(); break; case EGL_HEIGHT: *value = fglSurface->getHeight(); break; case EGL_LARGEST_PBUFFER: /* FIXME: Return something */ break; case EGL_TEXTURE_FORMAT: *value = EGL_NO_TEXTURE; break; case EGL_TEXTURE_TARGET: *value = EGL_NO_TEXTURE; break; case EGL_MIPMAP_TEXTURE: *value = EGL_FALSE; break; case EGL_MIPMAP_LEVEL: *value = 0; break; case EGL_RENDER_BUFFER: *value = EGL_BACK_BUFFER; break; case EGL_HORIZONTAL_RESOLUTION: /* pixel/mm * EGL_DISPLAY_SCALING */ *value = fglSurface->getHorizontalResolution(); break; case EGL_VERTICAL_RESOLUTION: /* pixel/mm * EGL_DISPLAY_SCALING */ *value = fglSurface->getVerticalResolution(); break; case EGL_PIXEL_ASPECT_RATIO: { /* w/h * EGL_DISPLAY_SCALING */ int wr = fglSurface->getHorizontalResolution(); int hr = fglSurface->getVerticalResolution(); *value = (wr * EGL_DISPLAY_SCALING) / hr; break; } case EGL_SWAP_BEHAVIOR: *value = fglSurface->getSwapBehavior(); break; default: setError(EGL_BAD_ATTRIBUTE); ret = EGL_FALSE; } return ret; }