summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
Diffstat (limited to 'ui')
-rw-r--r--ui/gfx/gl/gl.gyp2
-rw-r--r--ui/gfx/gl/gl_context.cc16
-rw-r--r--ui/gfx/gl/gl_context.h3
-rw-r--r--ui/gfx/gl/gl_context_cgl.cc8
-rw-r--r--ui/gfx/gl/gl_context_egl.cc9
-rw-r--r--ui/gfx/gl/gl_context_glx.cc9
-rw-r--r--ui/gfx/gl/gl_context_osmesa.cc10
-rw-r--r--ui/gfx/gl/gl_context_wgl.cc9
-rw-r--r--ui/gfx/gl/gl_surface.cc13
-rw-r--r--ui/gfx/gl/gl_surface.h4
-rw-r--r--ui/gfx/gl/scoped_make_current.cc36
-rw-r--r--ui/gfx/gl/scoped_make_current.h33
-rw-r--r--ui/gfx/surface/accelerated_surface_mac.cc4
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);