Skip to content

Commit

Permalink
GPU: Keep track of the last real context and real surface made current.
Browse files Browse the repository at this point in the history
This allows us to set virtual contexts current, which allows us
to restore from a GLStateRestorer in Scoped{Texture,Framebuffer}Binders
with --enable-virtual-gl-contexts.

BUG=241762,163217

Review URL: https://chromiumcodereview.appspot.com/15928002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@204500 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
backer@chromium.org committed Jun 6, 2013
1 parent 18e4f5f commit 1e9c0c8
Show file tree
Hide file tree
Showing 20 changed files with 113 additions and 62 deletions.
23 changes: 20 additions & 3 deletions ui/gl/gl_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ namespace gfx {
namespace {
base::LazyInstance<base::ThreadLocalPointer<GLContext> >::Leaky
current_context_ = LAZY_INSTANCE_INITIALIZER;

base::LazyInstance<base::ThreadLocalPointer<GLContext> >::Leaky
current_real_context_ = LAZY_INSTANCE_INITIALIZER;
} // namespace

GLContext::GLContext(GLShareGroup* share_group) : share_group_(share_group) {
Expand All @@ -32,7 +35,7 @@ GLContext::GLContext(GLShareGroup* share_group) : share_group_(share_group) {
GLContext::~GLContext() {
share_group_->RemoveContext(this);
if (GetCurrent() == this) {
SetCurrent(NULL, NULL);
SetCurrent(NULL);
}
}

Expand Down Expand Up @@ -90,8 +93,12 @@ GLContext* GLContext::GetCurrent() {
return current_context_.Pointer()->Get();
}

void GLContext::SetCurrent(GLContext* context, GLSurface* surface) {
current_context_.Pointer()->Set(context);
GLContext* GLContext::GetRealCurrent() {
return current_real_context_.Pointer()->Get();
}

void GLContext::SetCurrent(GLSurface* surface) {
current_context_.Pointer()->Set(surface ? this : NULL);
GLSurface::SetCurrent(surface);
}

Expand Down Expand Up @@ -140,4 +147,14 @@ void GLContext::SetRealGLApi() {
SetGLToRealGLApi();
}

GLContextReal::GLContextReal(GLShareGroup* share_group)
: GLContext(share_group) {}

GLContextReal::~GLContextReal() {}

void GLContextReal::SetCurrent(GLSurface* surface) {
GLContext::SetCurrent(surface);
current_real_context_.Pointer()->Set(surface ? this : NULL);
}

} // namespace gfx
22 changes: 21 additions & 1 deletion ui/gl/gl_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ class GL_EXPORT GLContext : public base::RefCounted<GLContext> {

static bool LosesAllContextsOnContextLost();

// Returns the last GLContext made current, virtual or real.
static GLContext* GetCurrent();

virtual bool WasAllocatedUsingRobustnessExtension();
Expand All @@ -107,23 +108,42 @@ class GL_EXPORT GLContext : public base::RefCounted<GLContext> {

// Sets the GL api to the real hardware API (vs the VirtualAPI)
static void SetRealGLApi();
static void SetCurrent(GLContext* context, GLSurface* surface);
virtual void SetCurrent(GLSurface* surface);

// Initialize function pointers to extension functions in the GL
// implementation. Should be called immediately after this context is made
// current.
bool InitializeExtensionBindings();

// Returns the last real (non-virtual) GLContext made current.
static GLContext* GetRealCurrent();

private:
friend class base::RefCounted<GLContext>;

// For GetRealCurrent.
friend class VirtualGLApi;

scoped_refptr<GLShareGroup> share_group_;
scoped_ptr<VirtualGLApi> virtual_gl_api_;
scoped_ptr<GLStateRestorer> state_restorer_;

DISALLOW_COPY_AND_ASSIGN(GLContext);
};

class GL_EXPORT GLContextReal : public GLContext {
public:
explicit GLContextReal(GLShareGroup* share_group);

protected:
virtual ~GLContextReal();

virtual void SetCurrent(GLSurface* surface) OVERRIDE;

private:
DISALLOW_COPY_AND_ASSIGN(GLContextReal);
};

} // namespace gfx

#endif // UI_GL_GL_CONTEXT_H_
6 changes: 3 additions & 3 deletions ui/gl/gl_context_android.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace {

// Used to render into an already current context+surface,
// that we do not have ownership of (draw callback).
class GLNonOwnedContext : public GLContext {
class GLNonOwnedContext : public GLContextReal {
public:
GLNonOwnedContext(GLShareGroup* share_group);

Expand All @@ -44,10 +44,10 @@ class GLNonOwnedContext : public GLContext {
};

GLNonOwnedContext::GLNonOwnedContext(GLShareGroup* share_group)
: GLContext(share_group) {}
: GLContextReal(share_group) {}

bool GLNonOwnedContext::MakeCurrent(GLSurface* surface) {
SetCurrent(this, surface);
SetCurrent(surface);
SetRealGLApi();
return true;
}
Expand Down
8 changes: 4 additions & 4 deletions ui/gl/gl_context_cgl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ static CGLPixelFormatObj GetPixelFormat() {
}

GLContextCGL::GLContextCGL(GLShareGroup* share_group)
: GLContext(share_group),
: GLContextReal(share_group),
context_(NULL),
gpu_preference_(PreferIntegratedGpu),
discrete_pixelformat_(NULL),
Expand Down Expand Up @@ -186,7 +186,7 @@ bool GLContextCGL::MakeCurrent(GLSurface* surface) {
return false;
}

SetCurrent(this, surface);
SetCurrent(surface);
if (!InitializeExtensionBindings()) {
ReleaseCurrent(surface);
return false;
Expand All @@ -205,7 +205,7 @@ void GLContextCGL::ReleaseCurrent(GLSurface* surface) {
if (!IsCurrent(surface))
return;

SetCurrent(NULL, NULL);
SetCurrent(NULL);
CGLSetCurrentContext(NULL);
}

Expand All @@ -215,7 +215,7 @@ bool GLContextCGL::IsCurrent(GLSurface* surface) {
// If our context is current then our notion of which GLContext is
// current must be correct. On the other hand, third-party code
// using OpenGL might change the current context.
DCHECK(!native_context_is_current || (GetCurrent() == this));
DCHECK(!native_context_is_current || (GetRealCurrent() == this));

if (!native_context_is_current)
return false;
Expand Down
2 changes: 1 addition & 1 deletion ui/gl/gl_context_cgl.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace gfx {
class GLSurface;

// Encapsulates a CGL OpenGL context.
class GLContextCGL : public GLContext {
class GLContextCGL : public GLContextReal {
public:
explicit GLContextCGL(GLShareGroup* share_group);

Expand Down
8 changes: 4 additions & 4 deletions ui/gl/gl_context_egl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ using ui::GetLastEGLErrorString;
namespace gfx {

GLContextEGL::GLContextEGL(GLShareGroup* share_group)
: GLContext(share_group),
: GLContextReal(share_group),
context_(NULL),
display_(NULL),
config_(NULL),
Expand Down Expand Up @@ -112,7 +112,7 @@ bool GLContextEGL::MakeCurrent(GLSurface* surface) {
return false;
}

SetCurrent(this, surface);
SetCurrent(surface);
if (!InitializeExtensionBindings()) {
ReleaseCurrent(surface);
return false;
Expand All @@ -138,7 +138,7 @@ void GLContextEGL::ReleaseCurrent(GLSurface* surface) {
if (unbind_fbo_on_makecurrent_)
glBindFramebufferEXT(GL_FRAMEBUFFER, 0);

SetCurrent(NULL, NULL);
SetCurrent(NULL);
eglMakeCurrent(display_,
EGL_NO_SURFACE,
EGL_NO_SURFACE,
Expand All @@ -153,7 +153,7 @@ bool GLContextEGL::IsCurrent(GLSurface* surface) {
// If our context is current then our notion of which GLContext is
// current must be correct. On the other hand, third-party code
// using OpenGL might change the current context.
DCHECK(!native_context_is_current || (GetCurrent() == this));
DCHECK(!native_context_is_current || (GetRealCurrent() == this));

if (!native_context_is_current)
return false;
Expand Down
2 changes: 1 addition & 1 deletion ui/gl/gl_context_egl.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace gfx {
class GLSurface;

// Encapsulates an EGL OpenGL ES context.
class GLContextEGL : public GLContext {
class GLContextEGL : public GLContextReal {
public:
explicit GLContextEGL(GLShareGroup* share_group);

Expand Down
8 changes: 4 additions & 4 deletions ui/gl/gl_context_glx.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class ScopedPtrXFree {
} // namespace

GLContextGLX::GLContextGLX(GLShareGroup* share_group)
: GLContext(share_group),
: GLContextReal(share_group),
context_(NULL),
display_(NULL) {
}
Expand Down Expand Up @@ -123,7 +123,7 @@ bool GLContextGLX::MakeCurrent(GLSurface* surface) {
return false;
}

SetCurrent(this, surface);
SetCurrent(surface);
if (!InitializeExtensionBindings()) {
ReleaseCurrent(surface);
Destroy();
Expand All @@ -145,7 +145,7 @@ void GLContextGLX::ReleaseCurrent(GLSurface* surface) {
if (!IsCurrent(surface))
return;

SetCurrent(NULL, NULL);
SetCurrent(NULL);
if (!glXMakeContextCurrent(display_, 0, 0, 0))
LOG(ERROR) << "glXMakeCurrent failed in ReleaseCurrent";
}
Expand All @@ -157,7 +157,7 @@ bool GLContextGLX::IsCurrent(GLSurface* surface) {
// If our context is current then our notion of which GLContext is
// current must be correct. On the other hand, third-party code
// using OpenGL might change the current context.
DCHECK(!native_context_is_current || (GetCurrent() == this));
DCHECK(!native_context_is_current || (GetRealCurrent() == this));

if (!native_context_is_current)
return false;
Expand Down
2 changes: 1 addition & 1 deletion ui/gl/gl_context_glx.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace gfx {
class GLSurface;

// Encapsulates a GLX OpenGL context.
class GL_EXPORT GLContextGLX : public GLContext {
class GL_EXPORT GLContextGLX : public GLContextReal {
public:
explicit GLContextGLX(GLShareGroup* share_group);

Expand Down
2 changes: 1 addition & 1 deletion ui/gl/gl_context_nsview.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class GLSurface;

// GLContextNSView encapsulates an NSView-based GLContext. This is paired with
// the GLSurfaceNSView class.
class GLContextNSView : public GLContext {
class GLContextNSView : public GLContextReal {
public:
explicit GLContextNSView(GLShareGroup* group);
virtual ~GLContextNSView();
Expand Down
2 changes: 1 addition & 1 deletion ui/gl/gl_context_nsview.mm
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
[context_ setView:view];
[context_ makeCurrentContext];

SetCurrent(this, surface);
SetCurrent(surface);

if (!surface->OnMakeCurrent(this)) {
LOG(ERROR) << "Unable to make gl context current.";
Expand Down
8 changes: 4 additions & 4 deletions ui/gl/gl_context_osmesa.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
namespace gfx {

GLContextOSMesa::GLContextOSMesa(GLShareGroup* share_group)
: GLContext(share_group),
: GLContextReal(share_group),
context_(NULL) {
}

Expand Down Expand Up @@ -65,7 +65,7 @@ bool GLContextOSMesa::MakeCurrent(GLSurface* surface) {
// Row 0 is at the top.
OSMesaPixelStore(OSMESA_Y_UP, 0);

SetCurrent(this, surface);
SetCurrent(surface);
if (!InitializeExtensionBindings()) {
ReleaseCurrent(surface);
return false;
Expand All @@ -84,7 +84,7 @@ void GLContextOSMesa::ReleaseCurrent(GLSurface* surface) {
if (!IsCurrent(surface))
return;

SetCurrent(NULL, NULL);
SetCurrent(NULL);
OSMesaMakeCurrent(NULL, NULL, GL_UNSIGNED_BYTE, 0, 0);
}

Expand All @@ -97,7 +97,7 @@ bool GLContextOSMesa::IsCurrent(GLSurface* surface) {
// If our context is current then our notion of which GLContext is
// current must be correct. On the other hand, third-party code
// using OpenGL might change the current context.
DCHECK(!native_context_is_current || (GetCurrent() == this));
DCHECK(!native_context_is_current || (GetRealCurrent() == this));

if (!native_context_is_current)
return false;
Expand Down
2 changes: 1 addition & 1 deletion ui/gl/gl_context_osmesa.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class GLShareGroup;
class GLSurface;

// Encapsulates an OSMesa OpenGL context that uses software rendering.
class GLContextOSMesa : public GLContext {
class GLContextOSMesa : public GLContextReal {
public:
explicit GLContextOSMesa(GLShareGroup* share_group);

Expand Down
5 changes: 3 additions & 2 deletions ui/gl/gl_context_stub.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace gfx {

GLContextStub::GLContextStub() : GLContext(NULL) {}
GLContextStub::GLContextStub() : GLContextReal(NULL) {}

bool GLContextStub::Initialize(
GLSurface* compatible_surface, GpuPreference gpu_preference) {
Expand All @@ -16,12 +16,13 @@ bool GLContextStub::Initialize(
void GLContextStub::Destroy() {}

bool GLContextStub::MakeCurrent(GLSurface* surface) {
SetCurrent(this, surface);
SetCurrent(surface);
SetRealGLApi();
return true;
}

void GLContextStub::ReleaseCurrent(GLSurface* surface) {
SetCurrent(NULL);
}

bool GLContextStub::IsCurrent(GLSurface* surface) {
Expand Down
2 changes: 1 addition & 1 deletion ui/gl/gl_context_stub.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
namespace gfx {

// A GLContext that does nothing for unit tests.
class GL_EXPORT GLContextStub : public GLContext {
class GL_EXPORT GLContextStub : public GLContextReal {
public:
GLContextStub();

Expand Down
8 changes: 4 additions & 4 deletions ui/gl/gl_context_wgl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
namespace gfx {

GLContextWGL::GLContextWGL(GLShareGroup* share_group)
: GLContext(share_group),
: GLContextReal(share_group),
context_(NULL) {
}

Expand Down Expand Up @@ -81,7 +81,7 @@ bool GLContextWGL::MakeCurrent(GLSurface* surface) {
return false;
}

SetCurrent(this, surface);
SetCurrent(surface);
if (!InitializeExtensionBindings()) {
ReleaseCurrent(surface);
return false;
Expand All @@ -100,7 +100,7 @@ void GLContextWGL::ReleaseCurrent(GLSurface* surface) {
if (!IsCurrent(surface))
return;

SetCurrent(NULL, NULL);
SetCurrent(NULL);
wglMakeCurrent(NULL, NULL);
}

Expand All @@ -111,7 +111,7 @@ bool GLContextWGL::IsCurrent(GLSurface* surface) {
// If our context is current then our notion of which GLContext is
// current must be correct. On the other hand, third-party code
// using OpenGL might change the current context.
DCHECK(!native_context_is_current || (GetCurrent() == this));
DCHECK(!native_context_is_current || (GetRealCurrent() == this));

if (!native_context_is_current)
return false;
Expand Down
2 changes: 1 addition & 1 deletion ui/gl/gl_context_wgl.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace gfx {
class GLSurface;

// This class is a wrapper around a GL context.
class GLContextWGL : public GLContext {
class GLContextWGL : public GLContextReal {
public:
explicit GLContextWGL(GLShareGroup* share_group);
virtual ~GLContextWGL();
Expand Down
Loading

0 comments on commit 1e9c0c8

Please sign in to comment.