EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw) { if (!EglValidate::surfaceTarget(readdraw)) { return EGL_NO_SURFACE; } ThreadInfo* thread = getThreadInfo(); EglDisplay* dpy = static_cast<EglDisplay*>(thread->eglDisplay); ContextPtr ctx = thread->eglContext; if(dpy && ctx.Ptr()) { SurfacePtr surface = readdraw == EGL_READ ? ctx->read() : ctx->draw(); if(surface.Ptr()) { // This double check is required because a surface might still be // current after it is destroyed - in which case its handle should // be invalid, that is EGL_NO_SURFACE should be returned even // though the surface is current. EGLSurface s = (EGLSurface)SafePointerFromUInt(surface->getHndl()); surface = dpy->getSurface(s); if(surface.Ptr()) { return s; } } } return EGL_NO_SURFACE; }
EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay display, EGLSurface draw, EGLSurface read, EGLContext context) { VALIDATE_DISPLAY(display); bool releaseContext = EglValidate::releaseContext(context, read, draw); if(!releaseContext && EglValidate::badContextMatch(context, read, draw)) { RETURN_ERROR(EGL_FALSE, EGL_BAD_MATCH); } ThreadInfo* thread = getThreadInfo(); ContextPtr prevCtx = thread->eglContext; if(releaseContext) { //releasing current context if(prevCtx.Ptr()) { g_eglInfo->getIface(prevCtx->version())->flush(); if(!dpy->nativeType()->makeCurrent(NULL,NULL,NULL)) { RETURN_ERROR(EGL_FALSE,EGL_BAD_ACCESS); } thread->updateInfo(ContextPtr(NULL),dpy,NULL,ShareGroupPtr(NULL),dpy->getManager(prevCtx->version())); } } else { //assining new context VALIDATE_CONTEXT(context); VALIDATE_SURFACE(draw,newDrawSrfc); VALIDATE_SURFACE(read,newReadSrfc); EglSurface* newDrawPtr = newDrawSrfc.Ptr(); EglSurface* newReadPtr = newReadSrfc.Ptr(); ContextPtr newCtx = ctx; if (newCtx.Ptr() && prevCtx.Ptr()) { if (newCtx.Ptr() == prevCtx.Ptr()) { if (newDrawPtr == prevCtx->draw().Ptr() && newReadPtr == prevCtx->read().Ptr()) { // nothing to do return EGL_TRUE; } } else { // Make sure previous context is detached from surfaces releaseContext = true; } } //surfaces compatibility check if(!((*ctx->getConfig()).compatibleWith((*newDrawPtr->getConfig()))) || !((*ctx->getConfig()).compatibleWith((*newReadPtr->getConfig())))) { RETURN_ERROR(EGL_FALSE,EGL_BAD_MATCH); } EglOS::Display* nativeDisplay = dpy->nativeType(); EglOS::Surface* nativeRead = newReadPtr->native(); EglOS::Surface* nativeDraw = newDrawPtr->native(); //checking native window validity if(newReadPtr->type() == EglSurface::WINDOW && !nativeDisplay->isValidNativeWin(nativeRead)) { RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_WINDOW); } if(newDrawPtr->type() == EglSurface::WINDOW && !nativeDisplay->isValidNativeWin(nativeDraw)) { RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_WINDOW); } if(prevCtx.Ptr()) { g_eglInfo->getIface(prevCtx->version())->flush(); } if (!dpy->nativeType()->makeCurrent( newReadPtr->native(), newDrawPtr->native(), newCtx->nativeType())) { RETURN_ERROR(EGL_FALSE,EGL_BAD_ACCESS); } //TODO: handle the following errors // EGL_BAD_CURRENT_SURFACE , EGL_CONTEXT_LOST , EGL_BAD_ACCESS thread->updateInfo(newCtx,dpy,newCtx->getGlesContext(),newCtx->getShareGroup(),dpy->getManager(newCtx->version())); newCtx->setSurfaces(newReadSrfc,newDrawSrfc); g_eglInfo->getIface(newCtx->version())->initContext(newCtx->getGlesContext(),newCtx->getShareGroup()); // Initialize the GLES extension function table used in // eglGetProcAddress for the context's GLES version if not // yet initialized. We initialize it here to make sure we call the // GLES getProcAddress after when a context is bound. g_eglInfo->initClientExtFuncTable(newCtx->version()); } // release previous context surface binding if(prevCtx.Ptr() && releaseContext) { prevCtx->setSurfaces(SurfacePtr(NULL),SurfacePtr(NULL)); } return EGL_TRUE; }