| Index: ui/gl/gl_context.cc
|
| diff --git a/ui/gl/gl_context.cc b/ui/gl/gl_context.cc
|
| index 46d566e42ea4e323a8daf7a19994adb744bbb83f..f18b11cefa37851828571b76653ebdc515be79ec 100644
|
| --- a/ui/gl/gl_context.cc
|
| +++ b/ui/gl/gl_context.cc
|
| @@ -46,6 +46,7 @@ void GLContext::ScopedReleaseCurrent::Cancel() {
|
|
|
| GLContext::GLContext(GLShareGroup* share_group)
|
| : share_group_(share_group),
|
| + current_virtual_context_(nullptr),
|
| state_dirtied_externally_(false),
|
| swap_interval_(1),
|
| force_swap_interval_zero_(false) {
|
| @@ -186,24 +187,67 @@ bool GLContext::InitializeDynamicBindings() {
|
| return initialized;
|
| }
|
|
|
| -void GLContext::SetupForVirtualization() {
|
| - if (!virtual_gl_api_) {
|
| - virtual_gl_api_.reset(new VirtualGLApi());
|
| - virtual_gl_api_->Initialize(&g_driver_gl, this);
|
| - }
|
| -}
|
| -
|
| bool GLContext::MakeVirtuallyCurrent(
|
| GLContext* virtual_context, GLSurface* surface) {
|
| - DCHECK(virtual_gl_api_);
|
| if (!ForceGpuSwitchIfNeeded())
|
| return false;
|
| - return virtual_gl_api_->MakeCurrent(virtual_context, surface);
|
| + bool switched_real_contexts = GLContext::GetRealCurrent() != this;
|
| + GLSurface* current_surface = GLSurface::GetCurrent();
|
| + if (switched_real_contexts || surface != current_surface) {
|
| + // MakeCurrent 'lite' path that avoids potentially expensive MakeCurrent()
|
| + // calls if the GLSurface uses the same underlying surface or renders to
|
| + // an FBO.
|
| + if (switched_real_contexts || !current_surface ||
|
| + !virtual_context->IsCurrent(surface)) {
|
| + if (!MakeCurrent(surface)) {
|
| + return false;
|
| + }
|
| + }
|
| + }
|
| +
|
| + DCHECK_EQ(this, GLContext::GetRealCurrent());
|
| + DCHECK(IsCurrent(NULL));
|
| + DCHECK(virtual_context->IsCurrent(surface));
|
| +
|
| + if (switched_real_contexts || virtual_context != current_virtual_context_) {
|
| +#if DCHECK_IS_ON()
|
| + GLenum error = glGetError();
|
| + // Accepting a context loss error here enables using debug mode to work on
|
| + // context loss handling in virtual context mode.
|
| + // There should be no other errors from the previous context leaking into
|
| + // the new context.
|
| + DCHECK(error == GL_NO_ERROR || error == GL_CONTEXT_LOST_KHR) <<
|
| + "GL error was: " << error;
|
| +#endif
|
| +
|
| + // Set all state that is different from the real state
|
| + if (virtual_context->GetGLStateRestorer()->IsInitialized()) {
|
| + GLStateRestorer* virtual_state = virtual_context->GetGLStateRestorer();
|
| + GLStateRestorer* current_state =
|
| + current_virtual_context_
|
| + ? current_virtual_context_->GetGLStateRestorer()
|
| + : nullptr;
|
| + if (current_state)
|
| + current_state->PauseQueries();
|
| + virtual_state->ResumeQueries();
|
| +
|
| + virtual_state->RestoreState(
|
| + (current_state && !switched_real_contexts) ? current_state : NULL);
|
| + }
|
| + current_virtual_context_ = virtual_context;
|
| + }
|
| +
|
| + virtual_context->SetCurrent(surface);
|
| + if (!surface->OnMakeCurrent(virtual_context)) {
|
| + LOG(ERROR) << "Could not make GLSurface current.";
|
| + return false;
|
| + }
|
| + return true;
|
| }
|
|
|
| void GLContext::OnReleaseVirtuallyCurrent(GLContext* virtual_context) {
|
| - if (virtual_gl_api_)
|
| - virtual_gl_api_->OnReleaseVirtuallyCurrent(virtual_context);
|
| + if (current_virtual_context_ == virtual_context)
|
| + current_virtual_context_ = nullptr;
|
| }
|
|
|
| void GLContext::SetRealGLApi() {
|
|
|