diff options
Diffstat (limited to 'ui')
-rw-r--r-- | ui/gfx/gl/gl.gyp | 2 | ||||
-rw-r--r-- | ui/gfx/gl/gl_context.cc | 16 | ||||
-rw-r--r-- | ui/gfx/gl/gl_context.h | 3 | ||||
-rw-r--r-- | ui/gfx/gl/gl_context_cgl.cc | 8 | ||||
-rw-r--r-- | ui/gfx/gl/gl_context_egl.cc | 9 | ||||
-rw-r--r-- | ui/gfx/gl/gl_context_glx.cc | 9 | ||||
-rw-r--r-- | ui/gfx/gl/gl_context_osmesa.cc | 10 | ||||
-rw-r--r-- | ui/gfx/gl/gl_context_wgl.cc | 9 | ||||
-rw-r--r-- | ui/gfx/gl/gl_surface.cc | 13 | ||||
-rw-r--r-- | ui/gfx/gl/gl_surface.h | 4 | ||||
-rw-r--r-- | ui/gfx/gl/scoped_make_current.cc | 36 | ||||
-rw-r--r-- | ui/gfx/gl/scoped_make_current.h | 33 | ||||
-rw-r--r-- | ui/gfx/surface/accelerated_surface_mac.cc | 4 |
13 files changed, 150 insertions, 6 deletions
diff --git a/ui/gfx/gl/gl.gyp b/ui/gfx/gl/gl.gyp index 65b949e..3a9ad6d 100644 --- a/ui/gfx/gl/gl.gyp +++ b/ui/gfx/gl/gl.gyp @@ -69,6 +69,8 @@ 'gl_surface_osmesa.h', 'gl_switches.cc', 'gl_switches.h', + 'scoped_make_current.cc', + 'scoped_make_current.h', '<(gl_binding_output_dir)/gl_bindings_autogen_gl.cc', '<(gl_binding_output_dir)/gl_bindings_autogen_gl.h', '<(gl_binding_output_dir)/gl_bindings_autogen_mock.cc', diff --git a/ui/gfx/gl/gl_context.cc b/ui/gfx/gl/gl_context.cc index 87379bf..6c25052e 100644 --- a/ui/gfx/gl/gl_context.cc +++ b/ui/gfx/gl/gl_context.cc @@ -6,13 +6,17 @@ #include "base/command_line.h" #include "base/logging.h" +#include "base/threading/thread_local.h" #include "ui/gfx/gl/gl_context.h" #include "ui/gfx/gl/gl_bindings.h" #include "ui/gfx/gl/gl_implementation.h" +#include "ui/gfx/gl/gl_surface.h" #include "ui/gfx/gl/gl_switches.h" namespace gfx { +static base::ThreadLocalPointer<GLContext> current_context_; + GLContext::GLContext(GLShareGroup* share_group) : share_group_(share_group) { if (!share_group_.get()) share_group_ = new GLShareGroup; @@ -22,6 +26,9 @@ GLContext::GLContext(GLShareGroup* share_group) : share_group_(share_group) { GLContext::~GLContext() { share_group_->RemoveContext(this); + if (GetCurrent() == this) { + SetCurrent(NULL, NULL); + } } std::string GLContext::GetExtensions() { @@ -61,6 +68,15 @@ bool GLContext::LosesAllContextsOnContextLost() } } +GLContext* GLContext::GetCurrent() { + return current_context_.Get(); +} + +void GLContext::SetCurrent(GLContext* context, GLSurface* surface) { + current_context_.Set(context); + GLSurface::SetCurrent(surface); +} + bool GLContext::WasAllocatedUsingARBRobustness() { return false; } diff --git a/ui/gfx/gl/gl_context.h b/ui/gfx/gl/gl_context.h index 5340ada..0a617f4 100644 --- a/ui/gfx/gl/gl_context.h +++ b/ui/gfx/gl/gl_context.h @@ -64,10 +64,13 @@ class GL_EXPORT GLContext : public base::RefCounted<GLContext> { static bool LosesAllContextsOnContextLost(); + static GLContext* GetCurrent(); + virtual bool WasAllocatedUsingARBRobustness(); protected: virtual ~GLContext(); + static void SetCurrent(GLContext* context, GLSurface* surface); private: scoped_refptr<GLShareGroup> share_group_; diff --git a/ui/gfx/gl/gl_context_cgl.cc b/ui/gfx/gl/gl_context_cgl.cc index 5598dd65..6e5defa 100644 --- a/ui/gfx/gl/gl_context_cgl.cc +++ b/ui/gfx/gl/gl_context_cgl.cc @@ -64,6 +64,7 @@ bool GLContextCGL::MakeCurrent(GLSurface* surface) { return false; } + SetCurrent(this, surface); surface->OnMakeCurrent(this); return true; } @@ -72,12 +73,17 @@ void GLContextCGL::ReleaseCurrent(GLSurface* surface) { if (!IsCurrent(surface)) return; + SetCurrent(NULL, NULL); CGLSetCurrentContext(NULL); CGLSetPBuffer(static_cast<CGLContextObj>(context_), NULL, 0, 0, 0); } bool GLContextCGL::IsCurrent(GLSurface* surface) { - if (CGLGetCurrentContext() != context_) + bool native_context_is_current = CGLGetCurrentContext() == context_; + + DCHECK(native_context_is_current == (GetCurrent() == this)); + + if (!native_context_is_current) return false; if (surface) { diff --git a/ui/gfx/gl/gl_context_egl.cc b/ui/gfx/gl/gl_context_egl.cc index ba25498..cde22d2 100644 --- a/ui/gfx/gl/gl_context_egl.cc +++ b/ui/gfx/gl/gl_context_egl.cc @@ -95,6 +95,7 @@ bool GLContextEGL::MakeCurrent(GLSurface* surface) { return false; } + SetCurrent(this, surface); surface->OnMakeCurrent(this); return true; } @@ -103,6 +104,7 @@ void GLContextEGL::ReleaseCurrent(GLSurface* surface) { if (!IsCurrent(surface)) return; + SetCurrent(NULL, NULL); eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, @@ -111,7 +113,12 @@ void GLContextEGL::ReleaseCurrent(GLSurface* surface) { bool GLContextEGL::IsCurrent(GLSurface* surface) { DCHECK(context_); - if (context_ != eglGetCurrentContext()) + + bool native_context_is_current = context_ == eglGetCurrentContext(); + + DCHECK(native_context_is_current == (GetCurrent() == this)); + + if (!native_context_is_current) return false; if (surface) { diff --git a/ui/gfx/gl/gl_context_glx.cc b/ui/gfx/gl/gl_context_glx.cc index 47238cc..c7d5998 100644 --- a/ui/gfx/gl/gl_context_glx.cc +++ b/ui/gfx/gl/gl_context_glx.cc @@ -171,6 +171,7 @@ bool GLContextGLX::MakeCurrent(GLSurface* surface) { return false; } + SetCurrent(this, surface); surface->OnMakeCurrent(this); return true; } @@ -179,11 +180,17 @@ void GLContextGLX::ReleaseCurrent(GLSurface* surface) { if (!IsCurrent(surface)) return; + SetCurrent(NULL, NULL); glXMakeContextCurrent(GLSurfaceGLX::GetDisplay(), 0, 0, NULL); } bool GLContextGLX::IsCurrent(GLSurface* surface) { - if (glXGetCurrentContext() != static_cast<GLXContext>(context_)) + bool native_context_is_current = + glXGetCurrentContext() == static_cast<GLXContext>(context_); + + DCHECK(native_context_is_current == (GetCurrent() == this)); + + if (!native_context_is_current) return false; if (surface) { diff --git a/ui/gfx/gl/gl_context_osmesa.cc b/ui/gfx/gl/gl_context_osmesa.cc index c6b8c42..0db285f 100644 --- a/ui/gfx/gl/gl_context_osmesa.cc +++ b/ui/gfx/gl/gl_context_osmesa.cc @@ -67,6 +67,7 @@ bool GLContextOSMesa::MakeCurrent(GLSurface* surface) { // Row 0 is at the top. OSMesaPixelStore(OSMESA_Y_UP, 0); + SetCurrent(this, surface); surface->OnMakeCurrent(this); return true; } @@ -75,12 +76,19 @@ void GLContextOSMesa::ReleaseCurrent(GLSurface* surface) { if (!IsCurrent(surface)) return; + SetCurrent(NULL, NULL); OSMesaMakeCurrent(NULL, NULL, GL_UNSIGNED_BYTE, 0, 0); } bool GLContextOSMesa::IsCurrent(GLSurface* surface) { DCHECK(context_); - if (context_ != OSMesaGetCurrentContext()) + + bool native_context_is_current = + context_ == OSMesaGetCurrentContext(); + + DCHECK(native_context_is_current == (GetCurrent() == this)); + + if (!native_context_is_current) return false; if (surface) { diff --git a/ui/gfx/gl/gl_context_wgl.cc b/ui/gfx/gl/gl_context_wgl.cc index f86e955..487f950 100644 --- a/ui/gfx/gl/gl_context_wgl.cc +++ b/ui/gfx/gl/gl_context_wgl.cc @@ -82,6 +82,7 @@ bool GLContextWGL::MakeCurrent(GLSurface* surface) { return false; } + SetCurrent(this, surface); surface->OnMakeCurrent(this); return true; } @@ -90,11 +91,17 @@ void GLContextWGL::ReleaseCurrent(GLSurface* surface) { if (!IsCurrent(surface)) return; + SetCurrent(NULL, NULL); wglMakeCurrent(NULL, NULL); } bool GLContextWGL::IsCurrent(GLSurface* surface) { - if (wglGetCurrentContext() != context_) + bool native_context_is_current = + wglGetCurrentContext() == context_; + + DCHECK(native_context_is_current == (GetCurrent() == this)); + + if (!native_context_is_current) return false; if (surface) { diff --git a/ui/gfx/gl/gl_surface.cc b/ui/gfx/gl/gl_surface.cc index 399d816..a0e881d 100644 --- a/ui/gfx/gl/gl_surface.cc +++ b/ui/gfx/gl/gl_surface.cc @@ -4,14 +4,19 @@ #include "ui/gfx/gl/gl_surface.h" +#include "base/threading/thread_local.h" #include "ui/gfx/gl/gl_context.h" namespace gfx { +static base::ThreadLocalPointer<GLSurface> current_surface_; + GLSurface::GLSurface() { } GLSurface::~GLSurface() { + if (GetCurrent() == this) + SetCurrent(NULL); } bool GLSurface::Initialize() @@ -26,4 +31,12 @@ unsigned int GLSurface::GetBackingFrameBufferObject() { void GLSurface::OnMakeCurrent(GLContext* context) { } +GLSurface* GLSurface::GetCurrent() { + return current_surface_.Get(); +} + +void GLSurface::SetCurrent(GLSurface* surface) { + current_surface_.Set(surface); +} + } // namespace gfx diff --git a/ui/gfx/gl/gl_surface.h b/ui/gfx/gl/gl_surface.h index 88b4f24..6e31418 100644 --- a/ui/gfx/gl/gl_surface.h +++ b/ui/gfx/gl/gl_surface.h @@ -65,11 +65,15 @@ class GL_EXPORT GLSurface : public base::RefCounted<GLSurface> { bool software, const gfx::Size& size); + static GLSurface* GetCurrent(); + protected: virtual ~GLSurface(); + static void SetCurrent(GLSurface* surface); private: friend class base::RefCounted<GLSurface>; + friend class GLContext; DISALLOW_COPY_AND_ASSIGN(GLSurface); }; diff --git a/ui/gfx/gl/scoped_make_current.cc b/ui/gfx/gl/scoped_make_current.cc new file mode 100644 index 0000000..6939861 --- /dev/null +++ b/ui/gfx/gl/scoped_make_current.cc @@ -0,0 +1,36 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gfx/gl/scoped_make_current.h" + +#include "base/logging.h" + +namespace gfx { + +ScopedMakeCurrent::ScopedMakeCurrent(GLContext* context, GLSurface* surface) + : previous_context_(GLContext::GetCurrent()) + , previous_surface_(GLSurface::GetCurrent()) + , context_(context) + , surface_(surface) + , succeeded_(false) { + DCHECK(context); + DCHECK(surface); + succeeded_ = context->MakeCurrent(surface); +} + +ScopedMakeCurrent::~ScopedMakeCurrent() { + if (previous_context_.get()) { + DCHECK(previous_surface_.get()); + previous_context_->MakeCurrent(previous_surface_.get()); + } else { + context_->ReleaseCurrent(surface_.get()); + } +} + +bool ScopedMakeCurrent::Succeeded() { + return succeeded_; +} + +} // namespace gfx + diff --git a/ui/gfx/gl/scoped_make_current.h b/ui/gfx/gl/scoped_make_current.h new file mode 100644 index 0000000..d0d74f7 --- /dev/null +++ b/ui/gfx/gl/scoped_make_current.h @@ -0,0 +1,33 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GFX_GL_SCOPED_MAKE_CURRENT_H_ +#define UI_GFX_GL_SCOPED_MAKE_CURRENT_H_ +#pragma once + +#include "ui/gfx/gl/gl_context.h" +#include "ui/gfx/gl/gl_surface.h" + +namespace gfx { + +class GL_EXPORT ScopedMakeCurrent { + public: + explicit ScopedMakeCurrent(GLContext* context, GLSurface* surface); + ~ScopedMakeCurrent(); + + bool Succeeded(); + + private: + scoped_refptr<GLContext> previous_context_; + scoped_refptr<GLSurface> previous_surface_; + scoped_refptr<GLContext> context_; + scoped_refptr<GLSurface> surface_; + bool succeeded_; + DISALLOW_COPY_AND_ASSIGN(ScopedMakeCurrent); +}; + +} // namespace gfx + +#endif // UI_GFX_GL_SCOPED_MAKE_CURRENT_H_ + diff --git a/ui/gfx/surface/accelerated_surface_mac.cc b/ui/gfx/surface/accelerated_surface_mac.cc index cbbee4b..d6b63cd 100644 --- a/ui/gfx/surface/accelerated_surface_mac.cc +++ b/ui/gfx/surface/accelerated_surface_mac.cc @@ -10,6 +10,7 @@ #include "ui/gfx/gl/gl_context.h" #include "ui/gfx/gl/gl_implementation.h" #include "ui/gfx/gl/gl_surface.h" +#include "ui/gfx/gl/scoped_make_current.h" #include "ui/gfx/rect.h" #include "ui/gfx/surface/io_surface_support_mac.h" @@ -237,7 +238,8 @@ uint64 AcceleratedSurface::SetSurfaceSize(const gfx::Size& size) { if (!io_surface_support) return 0; // Caller can try using SetWindowSizeForTransportDIB(). - if (!MakeCurrent()) + gfx::ScopedMakeCurrent make_current(gl_context_.get(), gl_surface_.get()); + if (!make_current.Succeeded()) return 0; gfx::Size clamped_size = ClampToValidDimensions(size); |