EGLint EglDisplayImpl::MakeCurrent(EGLContext egl_ctx, EGLSurface egl_draw, EGLSurface egl_read) { if (egl_read != egl_draw) { LOG_ALWAYS_FATAL("Read and draw surfaces must be the same."); return EGL_BAD_MATCH; } ContextPtr ctx = contexts_.Get(egl_ctx); SurfacePtr sfc = surfaces_.Get(egl_draw); bool release = ctx == NULL && sfc == NULL; // If a context is being set, then a surface must be set. Similarly, if a // context is being cleared, the surface must be cleared. Any other // combination is an error. const bool invalid_surface = ctx != NULL ? sfc == NULL : sfc != NULL; if (!release && invalid_surface) { return EGL_BAD_MATCH; } EglThreadInfo& info = EglThreadInfo::GetInstance(); ContextPtr prev_ctx = info.GetCurrentContext(); SurfacePtr prev_sfc = prev_ctx != NULL ? prev_ctx->GetSurface() : SurfacePtr(); if (release) { if (prev_ctx != NULL) { prev_ctx->Flush(); info.SetCurrentContext(ContextPtr()); } } else { if (ctx == NULL) { return EGL_BAD_CONTEXT; } if (ctx->config != sfc->config) { return EGL_BAD_MATCH; } if (ctx != NULL && prev_ctx != NULL) { if (ctx == prev_ctx) { if (sfc == prev_sfc) { // Reassigning the same context and surface. return EGL_SUCCESS; } } else { // Make sure to clear the previous context. release = true; } } if (prev_ctx != NULL) { prev_ctx->Flush(); } if (!ctx->SetCurrent()) { return EGL_BAD_ACCESS; } info.SetCurrentContext(ctx); ctx->SetSurface(sfc); } if (prev_ctx != NULL && release) { prev_ctx->ClearCurrent(); prev_ctx->ClearSurface(); } return EGL_SUCCESS; }