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; }
EGLBoolean eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw, EGLint left, EGLint top, EGLint width, EGLint height) { if (!fglEGLValidateDisplay(dpy)) { setError(EGL_BAD_DISPLAY); return EGL_FALSE; } FGLRenderSurface *d = static_cast<FGLRenderSurface *>(draw); if (!d->isValid()) { setError(EGL_BAD_SURFACE); return EGL_FALSE; } if (d->dpy != dpy) { setError(EGL_BAD_DISPLAY); return EGL_FALSE; } // post the surface d->setSwapRectangle(left, top, width, height); return EGL_TRUE; }
EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) { uint32_t configID = (uint32_t)config; if (!fglEGLValidateDisplay(dpy)) { setError(EGL_BAD_DISPLAY); return EGL_NO_SURFACE; } EGLint surfaceType; if (!fglGetConfigAttrib(configID, EGL_SURFACE_TYPE, &surfaceType)) return EGL_NO_SURFACE; if (!(surfaceType & EGL_PBUFFER_BIT)) { setError(EGL_BAD_MATCH); return EGL_NO_SURFACE; } uint32_t depthFormat; uint32_t pixelFormat; if (!fglGetConfigFormatInfo(configID, &pixelFormat, &depthFormat)) { setError(EGL_BAD_MATCH); return EGL_NO_SURFACE; } if (unlikely(!attrib_list)) attrib_list = &dummyAttribList; int32_t width = 0; int32_t height = 0; while (attrib_list[0] != EGL_NONE) { if (attrib_list[0] == EGL_WIDTH) width = attrib_list[1]; if (attrib_list[0] == EGL_HEIGHT) height = attrib_list[1]; attrib_list += 2; } if (width <= 0 || height <= 0) { setError(EGL_BAD_PARAMETER); return EGL_NO_SURFACE; } FGLRenderSurface *surface = new FGLPbufferSurface(dpy, configID, pixelFormat, depthFormat, width, height); if (!surface || !surface->initCheck()) { if (!surface) setError(EGL_BAD_ALLOC); /* otherwise constructor should have set error value for us */ delete surface; return EGL_NO_SURFACE; } return (EGLSurface)surface; }
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); }
EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list) { uint32_t configID = (uint32_t)config; if (!fglEGLValidateDisplay(dpy)) { setError(EGL_BAD_DISPLAY); return EGL_NO_SURFACE; } if (win == 0) { setError(EGL_BAD_MATCH); return EGL_NO_SURFACE; } EGLint surfaceType; if (!fglGetConfigAttrib(configID, EGL_SURFACE_TYPE, &surfaceType)) return EGL_NO_SURFACE; if (!(surfaceType & EGL_WINDOW_BIT)) { setError(EGL_BAD_MATCH); return EGL_NO_SURFACE; } uint32_t depthFormat; uint32_t pixelFormat; if (!fglGetConfigFormatInfo(configID, &pixelFormat, &depthFormat)) { setError(EGL_BAD_MATCH); return EGL_NO_SURFACE; } FGLRenderSurface *surface = platformCreateWindowSurface(dpy, configID, pixelFormat, depthFormat, win); if (!surface || !surface->initCheck()) { if (!surface) setError(EGL_BAD_ALLOC); /* otherwise platform code should have set error value for us */ delete surface; return EGL_NO_SURFACE; } return (EGLSurface)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); }
EGLClientBuffer eglGetRenderBufferANDROID(EGLDisplay dpy, EGLSurface draw) { if (!fglEGLValidateDisplay(dpy)) { setError(EGL_BAD_DISPLAY); return (EGLClientBuffer)0; } FGLRenderSurface *d = static_cast<FGLRenderSurface *>(draw); if (!d->isValid()) { setError(EGL_BAD_SURFACE); return (EGLClientBuffer)0; } if (d->dpy != dpy) { setError(EGL_BAD_DISPLAY); return (EGLClientBuffer)0; } // post the surface return d->getRenderBuffer(); }
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; }