summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-05 22:21:01 +0000
committerapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-05 22:21:01 +0000
commitf96c7c517f99b8ed7490b1883fec672fcf2c2f2c (patch)
treea36dd1d257f4a25ba4f57d79de5bfef9a3b4247b
parent42cde658b2ffe6f3a31750d47986922afc48aa47 (diff)
downloadchromium_src-f96c7c517f99b8ed7490b1883fec672fcf2c2f2c.zip
chromium_src-f96c7c517f99b8ed7490b1883fec672fcf2c2f2c.tar.gz
chromium_src-f96c7c517f99b8ed7490b1883fec672fcf2c2f2c.tar.bz2
Split CGL implementations of *GLContext into GLContextCGL and *GLSurfaceCGL.
Surfaces are independent of contexts in GL. To facilitate sharing of surfaces between processes, I have separated them from the notion of contexts because contexts cannot be shared between processes. I started with EGL in r81512, WGL in r81807, OSMesa in r81998 and GLX in r84090. This is the same thing for CGL. GLContextCGL still has a pointer to a surface and still has some surface specific operations that just forward through to it. Once I have refactored all the GLContext implementations in this way, I will remove these pointers and the surface specific opertations. There will not be "view" and "offscreen" GL contexts. Rather there will be a single context type for each backend which can be made current with a surface that directs output either to a view or offscreen surface. TEST=WebGL locally, try BUG=none Review URL: http://codereview.chromium.org/6933020 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@84334 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ui/gfx/gl/gl.gyp6
-rw-r--r--ui/gfx/gl/gl_context_cgl.cc95
-rw-r--r--ui/gfx/gl/gl_context_cgl.h41
-rw-r--r--ui/gfx/gl/gl_context_mac.cc168
-rw-r--r--ui/gfx/gl/gl_surface_cgl.cc106
-rw-r--r--ui/gfx/gl/gl_surface_cgl.h49
6 files changed, 317 insertions, 148 deletions
diff --git a/ui/gfx/gl/gl.gyp b/ui/gfx/gl/gl.gyp
index e70ccae..4e45a72 100644
--- a/ui/gfx/gl/gl.gyp
+++ b/ui/gfx/gl/gl.gyp
@@ -159,6 +159,12 @@
],
}],
['OS=="mac"', {
+ 'sources': [
+ 'gl_context_cgl.cc',
+ 'gl_context_cgl.h',
+ 'gl_surface_cgl.cc',
+ 'gl_surface_cgl.h',
+ ],
'link_settings': {
'libraries': [
'$(SDKROOT)/System/Library/Frameworks/OpenGL.framework',
diff --git a/ui/gfx/gl/gl_context_cgl.cc b/ui/gfx/gl/gl_context_cgl.cc
new file mode 100644
index 0000000..bee8ac2
--- /dev/null
+++ b/ui/gfx/gl/gl_context_cgl.cc
@@ -0,0 +1,95 @@
+// 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/gl_context_cgl.h"
+
+#include "base/logging.h"
+#include "ui/gfx/gl/gl_bindings.h"
+#include "ui/gfx/gl/gl_surface_cgl.h"
+
+namespace gfx {
+
+GLContextCGL::GLContextCGL(GLSurfaceCGL* surface)
+ : surface_(surface),
+ context_(NULL) {
+}
+
+GLContextCGL::~GLContextCGL() {
+ Destroy();
+}
+
+bool GLContextCGL::Initialize(GLContext* shared_context) {
+ CGLError res = CGLCreateContext(
+ static_cast<CGLPixelFormatObj>(GLSurfaceCGL::GetPixelFormat()),
+ shared_context ?
+ static_cast<CGLContextObj>(shared_context->GetHandle()) : NULL,
+ reinterpret_cast<CGLContextObj*>(&context_));
+ if (res != kCGLNoError) {
+ LOG(ERROR) << "Error creating context.";
+ Destroy();
+ return false;
+ }
+
+ return true;
+}
+
+void GLContextCGL::Destroy() {
+ if (context_) {
+ CGLDestroyContext(static_cast<CGLContextObj>(context_));
+ context_ = NULL;
+ }
+}
+
+bool GLContextCGL::MakeCurrent() {
+ if (IsCurrent())
+ return true;
+
+ if (CGLSetPBuffer(static_cast<CGLContextObj>(context_),
+ static_cast<CGLPBufferObj>(surface_->GetHandle()),
+ 0,
+ 0,
+ 0) != kCGLNoError) {
+ LOG(ERROR) << "Error attaching pbuffer to context.";
+ Destroy();
+ return false;
+ }
+
+ if (CGLSetCurrentContext(
+ static_cast<CGLContextObj>(context_)) != kCGLNoError) {
+ LOG(ERROR) << "Unable to make gl context current.";
+ return false;
+ }
+
+ return true;
+}
+
+bool GLContextCGL::IsCurrent() {
+ return CGLGetCurrentContext() == context_;
+}
+
+bool GLContextCGL::IsOffscreen() {
+ // TODO(apatrick): remove this from GLContext interface.
+ return surface_->IsOffscreen();
+}
+
+bool GLContextCGL::SwapBuffers() {
+ // TODO(apatrick): remove this from GLContext interface.
+ return surface_->SwapBuffers();
+}
+
+gfx::Size GLContextCGL::GetSize() {
+ // TODO(apatrick): remove this from GLContext interface.
+ return surface_->GetSize();
+}
+
+void* GLContextCGL::GetHandle() {
+ return context_;
+}
+
+void GLContextCGL::SetSwapInterval(int interval) {
+ DCHECK(IsCurrent());
+ NOTREACHED() << "Attempt to call SetSwapInterval on a GLContextCGL.";
+}
+
+} // namespace gfx
diff --git a/ui/gfx/gl/gl_context_cgl.h b/ui/gfx/gl/gl_context_cgl.h
new file mode 100644
index 0000000..23c77682
--- /dev/null
+++ b/ui/gfx/gl/gl_context_cgl.h
@@ -0,0 +1,41 @@
+// 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 <string>
+
+#include "base/memory/scoped_ptr.h"
+#include "ui/gfx/gl/gl_context.h"
+#include "ui/gfx/size.h"
+
+namespace gfx {
+
+class GLSurfaceCGL;
+
+// Encapsulates a CGL OpenGL context.
+class GLContextCGL : public GLContext {
+ public:
+ explicit GLContextCGL(GLSurfaceCGL* surface);
+ virtual ~GLContextCGL();
+
+ // Initializes the GL context.
+ bool Initialize(GLContext* shared_context);
+
+ // Implement GLContext.
+ virtual void Destroy();
+ virtual bool MakeCurrent();
+ virtual bool IsCurrent();
+ virtual bool IsOffscreen();
+ virtual bool SwapBuffers();
+ virtual gfx::Size GetSize();
+ virtual void* GetHandle();
+ virtual void SetSwapInterval(int interval);
+
+ private:
+ scoped_ptr<GLSurfaceCGL> surface_;
+ void* context_;
+
+ DISALLOW_COPY_AND_ASSIGN(GLContextCGL);
+};
+
+} // namespace gfx
diff --git a/ui/gfx/gl/gl_context_mac.cc b/ui/gfx/gl/gl_context_mac.cc
index 21b0403..fbb18b0 100644
--- a/ui/gfx/gl/gl_context_mac.cc
+++ b/ui/gfx/gl/gl_context_mac.cc
@@ -2,55 +2,20 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// This file implements the ViewGLContext and PbufferGLContext classes.
-
-#include "ui/gfx/gl/gl_context.h"
-
-#include <GL/osmesa.h>
-#include <OpenGL/OpenGL.h>
-
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
+#include "third_party/mesa/MesaLib/include/GL/osmesa.h"
#include "ui/gfx/gl/gl_bindings.h"
+#include "ui/gfx/gl/gl_context_cgl.h"
#include "ui/gfx/gl/gl_context_osmesa.h"
#include "ui/gfx/gl/gl_context_stub.h"
#include "ui/gfx/gl/gl_implementation.h"
+#include "ui/gfx/gl/gl_surface_cgl.h"
+#include "ui/gfx/gl/gl_surface_osmesa.h"
namespace gfx {
-typedef CGLContextObj GLContextHandle;
-typedef CGLPBufferObj PbufferHandle;
-
-// This class is a wrapper around a GL context used for offscreen rendering.
-// It is initially backed by a 1x1 pbuffer. Use it to create an FBO to do useful
-// rendering.
-class PbufferGLContext : public GLContext {
- public:
- PbufferGLContext()
- : context_(NULL),
- pbuffer_(NULL) {
- }
-
- // Initializes the GL context.
- bool Initialize(GLContext* shared_context);
-
- virtual void Destroy();
- virtual bool MakeCurrent();
- virtual bool IsCurrent();
- virtual bool IsOffscreen();
- virtual bool SwapBuffers();
- virtual gfx::Size GetSize();
- virtual void* GetHandle();
- virtual void SetSwapInterval(int interval);
-
- private:
- GLContextHandle context_;
- PbufferHandle pbuffer_;
-
- DISALLOW_COPY_AND_ASSIGN(PbufferGLContext);
-};
-
bool GLContext::InitializeOneOff() {
static bool initialized = false;
if (initialized)
@@ -69,123 +34,30 @@ bool GLContext::InitializeOneOff() {
return false;
}
- initialized = true;
- return true;
-}
-
-bool PbufferGLContext::Initialize(GLContext* shared_context) {
- // Create a 1x1 pbuffer and associated context to bootstrap things.
- static const CGLPixelFormatAttribute attribs[] = {
- (CGLPixelFormatAttribute) kCGLPFAPBuffer,
- (CGLPixelFormatAttribute) 0
- };
- CGLPixelFormatObj pixel_format;
- GLint num_pixel_formats;
- if (CGLChoosePixelFormat(attribs,
- &pixel_format,
- &num_pixel_formats) != kCGLNoError) {
- LOG(ERROR) << "Error choosing pixel format.";
- Destroy();
- return false;
- }
- if (!pixel_format) {
- LOG(ERROR) << "pixel_format == 0.";
- return false;
- }
-
- GLContextHandle shared_handle = NULL;
- if (shared_context)
- shared_handle = static_cast<GLContextHandle>(shared_context->GetHandle());
-
- CGLError res = CGLCreateContext(pixel_format, shared_handle, &context_);
- CGLDestroyPixelFormat(pixel_format);
- if (res != kCGLNoError) {
- LOG(ERROR) << "Error creating context.";
- Destroy();
- return false;
- }
- if (CGLCreatePBuffer(1, 1,
- GL_TEXTURE_2D, GL_RGBA,
- 0, &pbuffer_) != kCGLNoError) {
- LOG(ERROR) << "Error creating pbuffer.";
- Destroy();
- return false;
- }
- if (CGLSetPBuffer(context_, pbuffer_, 0, 0, 0) != kCGLNoError) {
- LOG(ERROR) << "Error attaching pbuffer to context.";
- Destroy();
- return false;
- }
-
- if (!MakeCurrent()) {
- Destroy();
- LOG(ERROR) << "Couldn't make context current for initialization.";
- return false;
- }
-
- if (!InitializeCommon()) {
- LOG(ERROR) << "GLContext::InitializeCommon failed.";
- Destroy();
- return false;
- }
-
- return true;
-}
-
-void PbufferGLContext::Destroy() {
- if (context_) {
- CGLDestroyContext(context_);
- context_ = NULL;
- }
-
- if (pbuffer_) {
- CGLDestroyPBuffer(pbuffer_);
- pbuffer_ = NULL;
- }
-}
-
-bool PbufferGLContext::MakeCurrent() {
- if (!IsCurrent()) {
- if (CGLSetCurrentContext(context_) != kCGLNoError) {
- LOG(ERROR) << "Unable to make gl context current.";
- return false;
- }
+ switch (GetGLImplementation()) {
+ case kGLImplementationDesktopGL:
+ if (!GLSurfaceCGL::InitializeOneOff()) {
+ LOG(ERROR) << "GLSurfaceCGL::InitializeOneOff failed.";
+ return false;
+ }
+ break;
+ default:
+ break;
}
+ initialized = true;
return true;
}
-bool PbufferGLContext::IsCurrent() {
- return CGLGetCurrentContext() == context_;
-}
-
-bool PbufferGLContext::IsOffscreen() {
- return true;
-}
-
-bool PbufferGLContext::SwapBuffers() {
- NOTREACHED() << "Cannot call SwapBuffers on a PbufferGLContext.";
- return false;
-}
-
-gfx::Size PbufferGLContext::GetSize() {
- NOTREACHED() << "Should not be requesting size of a PbufferGLContext.";
- return gfx::Size(1, 1);
-}
-
-void* PbufferGLContext::GetHandle() {
- return context_;
-}
-
-void PbufferGLContext::SetSwapInterval(int interval) {
- DCHECK(IsCurrent());
- NOTREACHED() << "Attempt to call SetSwapInterval on a PbufferGLContext.";
-}
-
GLContext* GLContext::CreateOffscreenGLContext(GLContext* shared_context) {
switch (GetGLImplementation()) {
case kGLImplementationDesktopGL: {
- scoped_ptr<PbufferGLContext> context(new PbufferGLContext);
+ scoped_ptr<PbufferGLSurfaceCGL> surface(new PbufferGLSurfaceCGL(
+ gfx::Size(1, 1)));
+ if (!surface->Initialize())
+ return false;
+
+ scoped_ptr<GLContextCGL> context(new GLContextCGL(surface.release()));
if (!context->Initialize(shared_context))
return NULL;
diff --git a/ui/gfx/gl/gl_surface_cgl.cc b/ui/gfx/gl/gl_surface_cgl.cc
new file mode 100644
index 0000000..7b6b89c
--- /dev/null
+++ b/ui/gfx/gl/gl_surface_cgl.cc
@@ -0,0 +1,106 @@
+// 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/gl_surface_cgl.h"
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "ui/gfx/gl/gl_bindings.h"
+
+namespace gfx {
+
+namespace {
+CGLPixelFormatObj g_pixel_format;
+}
+
+GLSurfaceCGL::GLSurfaceCGL() {
+}
+
+GLSurfaceCGL::~GLSurfaceCGL() {
+}
+
+bool GLSurfaceCGL::InitializeOneOff() {
+ static bool initialized = false;
+ if (initialized)
+ return true;
+
+ static const CGLPixelFormatAttribute attribs[] = {
+ (CGLPixelFormatAttribute) kCGLPFAPBuffer,
+ (CGLPixelFormatAttribute) 0
+ };
+ CGLPixelFormatObj pixel_format;
+ GLint num_pixel_formats;
+ if (CGLChoosePixelFormat(attribs,
+ &g_pixel_format,
+ &num_pixel_formats) != kCGLNoError) {
+ LOG(ERROR) << "Error choosing pixel format.";
+ return false;
+ }
+ if (num_pixel_formats == 0) {
+ LOG(ERROR) << "num_pixel_formats == 0.";
+ return false;
+ }
+ if (!g_pixel_format) {
+ LOG(ERROR) << "pixel_format == 0.";
+ return false;
+ }
+
+ initialized = true;
+ return true;
+}
+
+void* GLSurfaceCGL::GetPixelFormat() {
+ return g_pixel_format;
+}
+
+PbufferGLSurfaceCGL::PbufferGLSurfaceCGL(const gfx::Size& size)
+ : size_(size),
+ pbuffer_(NULL) {
+}
+
+PbufferGLSurfaceCGL::~PbufferGLSurfaceCGL() {
+ Destroy();
+}
+
+bool PbufferGLSurfaceCGL::Initialize() {
+ if (CGLCreatePBuffer(size_.width(),
+ size_.height(),
+ GL_TEXTURE_2D,
+ GL_RGBA,
+ 0,
+ reinterpret_cast<CGLPBufferObj*>(&pbuffer_))
+ != kCGLNoError) {
+ LOG(ERROR) << "Error creating pbuffer.";
+ Destroy();
+ return false;
+ }
+
+ return true;
+}
+
+void PbufferGLSurfaceCGL::Destroy() {
+ if (pbuffer_) {
+ CGLDestroyPBuffer(static_cast<CGLPBufferObj>(pbuffer_));
+ pbuffer_ = NULL;
+ }
+}
+
+bool PbufferGLSurfaceCGL::IsOffscreen() {
+ return true;
+}
+
+bool PbufferGLSurfaceCGL::SwapBuffers() {
+ NOTREACHED() << "Cannot call SwapBuffers on a PbufferGLSurfaceCGL.";
+ return false;
+}
+
+gfx::Size PbufferGLSurfaceCGL::GetSize() {
+ return size_;
+}
+
+void* PbufferGLSurfaceCGL::GetHandle() {
+ return pbuffer_;
+}
+
+} // namespace gfx
diff --git a/ui/gfx/gl/gl_surface_cgl.h b/ui/gfx/gl/gl_surface_cgl.h
new file mode 100644
index 0000000..98775c6
--- /dev/null
+++ b/ui/gfx/gl/gl_surface_cgl.h
@@ -0,0 +1,49 @@
+// 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_GL_SURFACE_CGL_H_
+#define UI_GFX_GL_GL_SURFACE_CGL_H_
+
+#include "ui/gfx/gl/gl_surface.h"
+#include "ui/gfx/size.h"
+
+namespace gfx {
+
+// Base class for CGL surfaces.
+class GLSurfaceCGL : public GLSurface {
+ public:
+ GLSurfaceCGL();
+ virtual ~GLSurfaceCGL();
+
+ static bool InitializeOneOff();
+ static void* GetPixelFormat();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(GLSurfaceCGL);
+};
+
+// A surface used to render to an offscreen pbuffer.
+class PbufferGLSurfaceCGL : public GLSurfaceCGL {
+ public:
+ explicit PbufferGLSurfaceCGL(const gfx::Size& size);
+ virtual ~PbufferGLSurfaceCGL();
+
+ // Implement GLSurface.
+ virtual bool Initialize();
+ virtual void Destroy();
+ virtual bool IsOffscreen();
+ virtual bool SwapBuffers();
+ virtual gfx::Size GetSize();
+ virtual void* GetHandle();
+
+ private:
+ gfx::Size size_;
+ void* pbuffer_;
+
+ DISALLOW_COPY_AND_ASSIGN(PbufferGLSurfaceCGL);
+};
+
+} // namespace gfx
+
+#endif // UI_GFX_GL_GL_SURFACE_CGL_H_