diff options
author | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-23 20:34:15 +0000 |
---|---|---|
committer | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-23 20:34:15 +0000 |
commit | f62a5abd6205c7a84a19f8b00b45b0792b767f57 (patch) | |
tree | 100e751f4e0302bbb4ecde919fb1cea272aeb7cf /ui | |
parent | 97807cbf58afe1e25b2bd014ce758e88e483d08b (diff) | |
download | chromium_src-f62a5abd6205c7a84a19f8b00b45b0792b767f57.zip chromium_src-f62a5abd6205c7a84a19f8b00b45b0792b767f57.tar.gz chromium_src-f62a5abd6205c7a84a19f8b00b45b0792b767f57.tar.bz2 |
GLContext no longer holds a pointer to a GLSurface.
This is part of an ongoing effort to treat GL contexts and GL surfaces as independent entities.
TEST=run WebGL on mac, windows and linux, trybots
BUG=none
Review URL: http://codereview.chromium.org/7021014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@86332 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
29 files changed, 298 insertions, 424 deletions
diff --git a/ui/gfx/compositor/compositor_gl.cc b/ui/gfx/compositor/compositor_gl.cc index f8fc139..f266d7c 100644 --- a/ui/gfx/compositor/compositor_gl.cc +++ b/ui/gfx/compositor/compositor_gl.cc @@ -62,6 +62,7 @@ class CompositorGL : public Compositor { virtual void NotifyEnd() OVERRIDE; // The GL context used for compositing. + scoped_ptr<gfx::GLSurface> gl_surface_; scoped_ptr<gfx::GLContext> gl_context_; gfx::Size size_; @@ -193,9 +194,8 @@ void TextureGL::Draw(const ui::Transform& transform) { CompositorGL::CompositorGL(gfx::AcceleratedWidget widget) : started_(false) { - scoped_ptr<gfx::GLSurface> surface( - gfx::GLSurface::CreateViewGLSurface(widget)); - gl_context_.reset(gfx::GLContext::CreateGLContext(surface.release(), NULL)), + gl_surface_.reset(gfx::GLSurface::CreateViewGLSurface(widget)); + gl_context_.reset(gfx::GLContext::CreateGLContext(NULL, gl_surface.get())), gl_context_->MakeCurrent(); glColorMask(true, true, true, true); glEnable(GL_BLEND); @@ -220,7 +220,7 @@ Texture* CompositorGL::CreateTexture() { void CompositorGL::NotifyStart() { started_ = true; - gl_context_->MakeCurrent(); + gl_context_->MakeCurrent(gl_surface_.get()); glViewport(0, 0, gl_context_->GetSize().width(), gl_context_->GetSize().height()); @@ -234,7 +234,7 @@ void CompositorGL::NotifyStart() { void CompositorGL::NotifyEnd() { DCHECK(started_); - gl_context_->SwapBuffers(); + gl_surface_->SwapBuffers(); started_ = false; } @@ -267,6 +267,7 @@ class CompositorGL : public Compositor { void RestoreTransform() OVERRIDE; // The GL context used for compositing. + scoped_ptr<gfx::GLSurface> gl_surface_; scoped_ptr<gfx::GLContext> gl_context_; // Keep track of whether compositing has started or not. @@ -277,19 +278,18 @@ class CompositorGL : public Compositor { CompositorGL::CompositorGL(gfx::AcceleratedWidget widget) : started_(false) { - scoped_ptr<gfx::GLSurface> surface( - gfx::GLSurface::CreateViewGLSurface(widget)); - gl_context_.reset(gfx::GLContext::CreateGLContext(surface.release(), NULL)); + gl_surface_.reset(gfx::GLSurface::CreateViewGLSurface(widget)); + gl_context_.reset(gfx::GLContext::CreateGLContext(NULL, gl_surface_.get())); } void CompositorGL::NotifyStart() { started_ = true; - gl_context_->MakeCurrent(); + gl_context_->MakeCurrent(gl_surface_.get()); } void CompositorGL::NotifyEnd() { DCHECK(started_); - gl_context_->SwapBuffers(); + gl_surface_->SwapBuffers(); started_ = false; } diff --git a/ui/gfx/gl/gl_context.cc b/ui/gfx/gl/gl_context.cc index 630925d..6391dc5 100644 --- a/ui/gfx/gl/gl_context.cc +++ b/ui/gfx/gl/gl_context.cc @@ -13,21 +13,8 @@ namespace gfx { -void GLContext::ReleaseCurrent() { - // TODO(apatrick): Implement this in GLContext derivatives. -} - -GLSurface* GLContext::GetSurface() { - // TODO(apatrick): Remove this when surfaces are split from contexts. - return NULL; -} - -unsigned int GLContext::GetBackingFrameBufferObject() { - return 0; -} - std::string GLContext::GetExtensions() { - DCHECK(IsCurrent()); + DCHECK(IsCurrent(NULL)); const char* ext = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)); return std::string(ext ? ext : ""); } @@ -42,28 +29,6 @@ bool GLContext::HasExtension(const char* name) { return extensions.find(delimited_name) != std::string::npos; } -bool GLContext::InitializeCommon() { - if (!MakeCurrent()) { - LOG(ERROR) << "MakeCurrent failed."; - return false; - } - - if (!IsOffscreen()) { - if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync)) - SetSwapInterval(0); - else - SetSwapInterval(1); - } - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - if (glGetError() != GL_NO_ERROR) { - LOG(ERROR) << "glClear failed."; - return false; - } - - return true; -} - bool GLContext::LosesAllContextsOnContextLost() { switch (GetGLImplementation()) { diff --git a/ui/gfx/gl/gl_context.h b/ui/gfx/gl/gl_context.h index 548b6ae..45b944c 100644 --- a/ui/gfx/gl/gl_context.h +++ b/ui/gfx/gl/gl_context.h @@ -8,9 +8,7 @@ #include <string> -#include "build/build_config.h" -#include "ui/gfx/native_widget_types.h" -#include "ui/gfx/size.h" +#include "base/basictypes.h" namespace gfx { @@ -22,32 +20,25 @@ class GLContext { GLContext() {} virtual ~GLContext() {} + // Initializes the GL context to be compatible with the given surface. The GL + // context can be made with other surface's of the same type. The compatible + // surface is only needed for certain platforms like WGL, OSMesa and GLX. It + // should be specific for all platforms though. + virtual bool Initialize(GLContext* shared_context, + GLSurface* compatible_surface) = 0; + // Destroys the GL context. virtual void Destroy() = 0; - // Makes the GL context current on the current thread. - virtual bool MakeCurrent() = 0; - - // Releases this GL context as current on the current thread. TODO(apatrick): - // implement this in the other GLContexts. - virtual void ReleaseCurrent(); - - // Returns true if this context is current. - virtual bool IsCurrent() = 0; - - // Returns true if this context is offscreen. - virtual bool IsOffscreen() = 0; + // Makes the GL context and a surface current on the current thread. + virtual bool MakeCurrent(GLSurface* surface) = 0; - // Swaps front and back buffers. This has no effect for off-screen - // contexts. - virtual bool SwapBuffers() = 0; + // Releases this GL context and surface as current on the current thread. + virtual void ReleaseCurrent(GLSurface* surface) = 0; - // Get the size of the back buffer. - virtual gfx::Size GetSize() = 0; - - // Get the surface. TODO(apatrick): remove this when contexts are split from - // surfaces. - virtual GLSurface* GetSurface(); + // Returns true if this context and surface is current. Pass a null surface + // if the current surface is not important. + virtual bool IsCurrent(GLSurface* surface) = 0; // Get the underlying platform specific GL context "handle". virtual void* GetHandle() = 0; @@ -55,10 +46,6 @@ class GLContext { // Set swap interval. This context must be current. virtual void SetSwapInterval(int interval) = 0; - // Returns the internal frame buffer object name if the context is backed by - // FBO. Otherwise returns 0. - virtual unsigned int GetBackingFrameBufferObject(); - // Returns space separated list of extensions. The context must be current. virtual std::string GetExtensions(); @@ -69,17 +56,11 @@ class GLContext { // Create a GL context that is compatible with the given surface. // |share_context|, if non-NULL, is a context which the // internally created OpenGL context shares textures and other resources. - // TODO(apatrick): For the time being, the context will take ownership of the - // surface and the surface will be made the current read and draw surface - // when the context is made current. - static GLContext* CreateGLContext(GLSurface* compatible_surface, - GLContext* shared_context); + static GLContext* CreateGLContext(GLContext* shared_context, + GLSurface* compatible_surface); static bool LosesAllContextsOnContextLost(); - protected: - bool InitializeCommon(); - private: DISALLOW_COPY_AND_ASSIGN(GLContext); }; diff --git a/ui/gfx/gl/gl_context_cgl.cc b/ui/gfx/gl/gl_context_cgl.cc index bee8ac2..cb2853b 100644 --- a/ui/gfx/gl/gl_context_cgl.cc +++ b/ui/gfx/gl/gl_context_cgl.cc @@ -10,16 +10,18 @@ namespace gfx { -GLContextCGL::GLContextCGL(GLSurfaceCGL* surface) - : surface_(surface), - context_(NULL) { +GLContextCGL::GLContextCGL() + : context_(NULL) { } GLContextCGL::~GLContextCGL() { Destroy(); } -bool GLContextCGL::Initialize(GLContext* shared_context) { +bool GLContextCGL::Initialize(GLContext* shared_context, + GLSurface* compatible_surface) { + DCHECK(compatible_surface); + CGLError res = CGLCreateContext( static_cast<CGLPixelFormatObj>(GLSurfaceCGL::GetPixelFormat()), shared_context ? @@ -41,12 +43,13 @@ void GLContextCGL::Destroy() { } } -bool GLContextCGL::MakeCurrent() { - if (IsCurrent()) +bool GLContextCGL::MakeCurrent(GLSurface* surface) { + DCHECK(context_); + if (IsCurrent(surface)) return true; if (CGLSetPBuffer(static_cast<CGLContextObj>(context_), - static_cast<CGLPBufferObj>(surface_->GetHandle()), + static_cast<CGLPBufferObj>(surface->GetHandle()), 0, 0, 0) != kCGLNoError) { @@ -64,23 +67,33 @@ bool GLContextCGL::MakeCurrent() { return true; } -bool GLContextCGL::IsCurrent() { - return CGLGetCurrentContext() == context_; -} +void GLContextCGL::ReleaseCurrent(GLSurface* surface) { + if (!IsCurrent(surface)) + return; -bool GLContextCGL::IsOffscreen() { - // TODO(apatrick): remove this from GLContext interface. - return surface_->IsOffscreen(); + CGLSetCurrentContext(NULL); + CGLSetPBuffer(static_cast<CGLContextObj>(context_), NULL, 0, 0, 0); } -bool GLContextCGL::SwapBuffers() { - // TODO(apatrick): remove this from GLContext interface. - return surface_->SwapBuffers(); -} +bool GLContextCGL::IsCurrent(GLSurface* surface) { + if (CGLGetCurrentContext() != context_) + return false; -gfx::Size GLContextCGL::GetSize() { - // TODO(apatrick): remove this from GLContext interface. - return surface_->GetSize(); + if (surface) { + CGLPBufferObj current_surface = NULL; + GLenum face; + GLint level; + GLint screen; + CGLGetPBuffer(static_cast<CGLContextObj>(context_), + ¤t_surface, + &face, + &level, + &screen); + if (current_surface != surface->GetHandle()) + return false; + } + + return true; } void* GLContextCGL::GetHandle() { @@ -88,7 +101,7 @@ void* GLContextCGL::GetHandle() { } void GLContextCGL::SetSwapInterval(int interval) { - DCHECK(IsCurrent()); + DCHECK(IsCurrent(NULL)); NOTREACHED() << "Attempt to call SetSwapInterval on a GLContextCGL."; } diff --git a/ui/gfx/gl/gl_context_cgl.h b/ui/gfx/gl/gl_context_cgl.h index 23c77682..0ebf558 100644 --- a/ui/gfx/gl/gl_context_cgl.h +++ b/ui/gfx/gl/gl_context_cgl.h @@ -2,37 +2,29 @@ // 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; +class GLSurface; // Encapsulates a CGL OpenGL context. class GLContextCGL : public GLContext { public: - explicit GLContextCGL(GLSurfaceCGL* surface); + GLContextCGL(); virtual ~GLContextCGL(); - // Initializes the GL context. - bool Initialize(GLContext* shared_context); - // Implement GLContext. + virtual bool Initialize(GLContext* shared_context, + GLSurface* compatible_surface); virtual void Destroy(); - virtual bool MakeCurrent(); - virtual bool IsCurrent(); - virtual bool IsOffscreen(); - virtual bool SwapBuffers(); - virtual gfx::Size GetSize(); + virtual bool MakeCurrent(GLSurface* surface); + virtual void ReleaseCurrent(GLSurface* surface); + virtual bool IsCurrent(GLSurface* surface); virtual void* GetHandle(); virtual void SetSwapInterval(int interval); private: - scoped_ptr<GLSurfaceCGL> surface_; void* context_; DISALLOW_COPY_AND_ASSIGN(GLContextCGL); diff --git a/ui/gfx/gl/gl_context_egl.cc b/ui/gfx/gl/gl_context_egl.cc index 14e9941..d15dd17 100644 --- a/ui/gfx/gl/gl_context_egl.cc +++ b/ui/gfx/gl/gl_context_egl.cc @@ -32,9 +32,8 @@ std::string GLContextEGL::GetExtensions() { return GLContext::GetExtensions() + " " + extensions; } -GLContextEGL::GLContextEGL(GLSurfaceEGL* surface) - : surface_(surface), - context_(NULL) +GLContextEGL::GLContextEGL() + : context_(NULL) { } @@ -42,7 +41,9 @@ GLContextEGL::~GLContextEGL() { Destroy(); } -bool GLContextEGL::Initialize(GLContext* shared_context) { +bool GLContextEGL::Initialize(GLContext* shared_context, + GLSurface* compatible_surface) { + DCHECK(compatible_surface); DCHECK(!context_); static const EGLint kContextAttributes[] = { @@ -62,18 +63,6 @@ bool GLContextEGL::Initialize(GLContext* shared_context) { return false; } - if (!MakeCurrent()) { - LOG(ERROR) << "MakeCurrent failed."; - Destroy(); - return false; - } - - if (!InitializeCommon()) { - LOG(ERROR) << "GLContext::InitializeCommon failed."; - Destroy(); - return false; - } - return true; } @@ -86,21 +75,16 @@ void GLContextEGL::Destroy() { context_ = NULL; } - - if (surface_.get()) { - surface_->Destroy(); - surface_.reset(); - } } -bool GLContextEGL::MakeCurrent() { +bool GLContextEGL::MakeCurrent(GLSurface* surface) { DCHECK(context_); - if (IsCurrent()) + if (IsCurrent(surface)) return true; if (!eglMakeCurrent(GLSurfaceEGL::GetDisplay(), - surface_->GetHandle(), - surface_->GetHandle(), + surface->GetHandle(), + surface->GetHandle(), context_)) { VLOG(1) << "eglMakeCurrent failed with error " << GetLastEGLErrorString(); @@ -110,8 +94,8 @@ bool GLContextEGL::MakeCurrent() { return true; } -void GLContextEGL::ReleaseCurrent() { - if (!IsCurrent()) +void GLContextEGL::ReleaseCurrent(GLSurface* surface) { + if (!IsCurrent(surface)) return; eglMakeCurrent(GLSurfaceEGL::GetDisplay(), @@ -120,30 +104,17 @@ void GLContextEGL::ReleaseCurrent() { EGL_NO_CONTEXT); } -bool GLContextEGL::IsCurrent() { +bool GLContextEGL::IsCurrent(GLSurface* surface) { DCHECK(context_); - return context_ == eglGetCurrentContext() && - surface_->GetHandle() == eglGetCurrentSurface(EGL_DRAW); -} - -bool GLContextEGL::IsOffscreen() { - // TODO(apatrick): remove this from GLContext interface. - return surface_->IsOffscreen(); -} - -bool GLContextEGL::SwapBuffers() { - // TODO(apatrick): remove this from GLContext interface. - return surface_->SwapBuffers(); -} + if (context_ != eglGetCurrentContext()) + return false; -gfx::Size GLContextEGL::GetSize() { - // TODO(apatrick): remove this from GLContext interface. - return surface_->GetSize(); -} + if (surface) { + if (surface->GetHandle() != eglGetCurrentSurface(EGL_DRAW)) + return false; + } -GLSurface* GLContextEGL::GetSurface() { - // TODO(apatrick): remove this from GLContext interface. - return surface_.get(); + return true; } void* GLContextEGL::GetHandle() { @@ -151,7 +122,7 @@ void* GLContextEGL::GetHandle() { } void GLContextEGL::SetSwapInterval(int interval) { - DCHECK(IsCurrent()); + DCHECK(IsCurrent(NULL)); if (!eglSwapInterval(GLSurfaceEGL::GetDisplay(), interval)) { LOG(ERROR) << "eglSwapInterval failed with error " << GetLastEGLErrorString(); diff --git a/ui/gfx/gl/gl_context_egl.h b/ui/gfx/gl/gl_context_egl.h index 7337d22..2e8a446 100644 --- a/ui/gfx/gl/gl_context_egl.h +++ b/ui/gfx/gl/gl_context_egl.h @@ -8,43 +8,32 @@ #include <string> -#include "base/memory/scoped_ptr.h" #include "ui/gfx/gl/gl_context.h" -#include "ui/gfx/size.h" typedef void* EGLContext; namespace gfx { -class GLSurfaceEGL; +class GLSurface; // Encapsulates an EGL OpenGL ES context. class GLContextEGL : public GLContext { public: - // Takes ownership of surface. TODO(apatrick): separate notion of surface - // from context. - explicit GLContextEGL(GLSurfaceEGL* surface); - + GLContextEGL(); virtual ~GLContextEGL(); - // Initialize an EGL context. - bool Initialize(GLContext* shared_context); - // Implement GLContext. + virtual bool Initialize(GLContext* shared_context, + GLSurface* compatible_surface); virtual void Destroy(); - virtual bool MakeCurrent(); - virtual void ReleaseCurrent(); - virtual bool IsCurrent(); - virtual bool IsOffscreen(); - virtual bool SwapBuffers(); - virtual gfx::Size GetSize(); - virtual GLSurface* GetSurface(); + virtual bool MakeCurrent(GLSurface* surface); + virtual void ReleaseCurrent(GLSurface* surface); + virtual bool IsCurrent(GLSurface* surface); virtual void* GetHandle(); virtual void SetSwapInterval(int interval); virtual std::string GetExtensions(); private: - scoped_ptr<GLSurfaceEGL> surface_; EGLContext context_; DISALLOW_COPY_AND_ASSIGN(GLContextEGL); diff --git a/ui/gfx/gl/gl_context_glx.cc b/ui/gfx/gl/gl_context_glx.cc index 87224de..12013b5 100644 --- a/ui/gfx/gl/gl_context_glx.cc +++ b/ui/gfx/gl/gl_context_glx.cc @@ -9,6 +9,7 @@ extern "C" { #include "ui/gfx/gl/gl_context_glx.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_implementation.h" @@ -33,19 +34,20 @@ bool IsCompositingWindowManagerActive(Display* display) { } // namespace anonymous -GLContextGLX::GLContextGLX(GLSurfaceGLX* surface) - : surface_(surface), - context_(NULL) { +GLContextGLX::GLContextGLX() + : context_(NULL) { } GLContextGLX::~GLContextGLX() { Destroy(); } -bool GLContextGLX::Initialize(GLContext* shared_context) { +bool GLContextGLX::Initialize(GLContext* shared_context, + GLSurface* compatible_surface) { + GLSurfaceGLX* surface_glx = static_cast<GLSurfaceGLX*>(compatible_surface); context_ = glXCreateNewContext( GLSurfaceGLX::GetDisplay(), - static_cast<GLXFBConfig>(surface_->GetConfig()), + static_cast<GLXFBConfig>(surface_glx->GetConfig()), GLX_RGBA_TYPE, static_cast<GLXContext>( shared_context ? shared_context->GetHandle() : NULL), @@ -67,15 +69,15 @@ void GLContextGLX::Destroy() { } } -bool GLContextGLX::MakeCurrent() { - if (IsCurrent()) { +bool GLContextGLX::MakeCurrent(GLSurface* surface) { + DCHECK(context_); + if (IsCurrent(surface)) return true; - } if (!glXMakeContextCurrent( GLSurfaceGLX::GetDisplay(), - reinterpret_cast<GLXDrawable>(surface_->GetHandle()), - reinterpret_cast<GLXDrawable>(surface_->GetHandle()), + reinterpret_cast<GLXDrawable>(surface->GetHandle()), + reinterpret_cast<GLXDrawable>(surface->GetHandle()), static_cast<GLXContext>(context_))) { Destroy(); LOG(ERROR) << "Couldn't make context current."; @@ -85,27 +87,25 @@ bool GLContextGLX::MakeCurrent() { return true; } -bool GLContextGLX::IsCurrent() { - // TODO(apatrick): When surface is split from context, cannot use surface_ - // here. - return glXGetCurrentDrawable() == - reinterpret_cast<GLXDrawable>(surface_->GetHandle()) && - glXGetCurrentContext() == static_cast<GLXContext>(context_); -} +void GLContextGLX::ReleaseCurrent(GLSurface* surface) { + if (!IsCurrent(surface)) + return; -bool GLContextGLX::IsOffscreen() { - // TODO(apatrick): remove this from GLContext interface. - return surface_->IsOffscreen(); + glXMakeContextCurrent(GLSurfaceGLX::GetDisplay(), 0, 0, NULL); } -bool GLContextGLX::SwapBuffers() { - // TODO(apatrick): remove this from GLContext interface. - return surface_->SwapBuffers(); -} +bool GLContextGLX::IsCurrent(GLSurface* surface) { + if (glXGetCurrentContext() != static_cast<GLXContext>(context_)) + return false; -gfx::Size GLContextGLX::GetSize() { - // TODO(apatrick): remove this from GLContext interface. - return surface_->GetSize(); + if (surface) { + if (glXGetCurrentDrawable() != + reinterpret_cast<GLXDrawable>(surface->GetHandle())) { + return false; + } + } + + return true; } void* GLContextGLX::GetHandle() { @@ -113,7 +113,7 @@ void* GLContextGLX::GetHandle() { } void GLContextGLX::SetSwapInterval(int interval) { - DCHECK(IsCurrent()); + DCHECK(IsCurrent(NULL)); if (HasExtension("GLX_EXT_swap_control") && glXSwapIntervalEXT) { // Only enable vsync if we aren't using a compositing window // manager. At the moment, compositing window managers don't @@ -122,14 +122,14 @@ void GLContextGLX::SetSwapInterval(int interval) { if (!IsCompositingWindowManagerActive(GLSurfaceGLX::GetDisplay())) { glXSwapIntervalEXT( GLSurfaceGLX::GetDisplay(), - reinterpret_cast<GLXDrawable>(surface_->GetHandle()), + glXGetCurrentDrawable(), interval); } } } std::string GLContextGLX::GetExtensions() { - DCHECK(IsCurrent()); + DCHECK(IsCurrent(NULL)); const char* extensions = glXQueryExtensionsString( GLSurfaceGLX::GetDisplay(), 0); diff --git a/ui/gfx/gl/gl_context_glx.h b/ui/gfx/gl/gl_context_glx.h index 9ebab5d..0ee6b1a 100644 --- a/ui/gfx/gl/gl_context_glx.h +++ b/ui/gfx/gl/gl_context_glx.h @@ -4,40 +4,30 @@ #include <string> -#include "base/memory/scoped_ptr.h" -#include "ui/base/x/x11_util.h" #include "ui/gfx/gl/gl_context.h" -#include "ui/gfx/size.h" namespace gfx { -class GLSurfaceGLX; +class GLSurface; // Encapsulates a GLX OpenGL context. class GLContextGLX : public GLContext { public: - // Takes ownership of surface. TODO(apatrick): separate notion of surface - // from context. - explicit GLContextGLX(GLSurfaceGLX* surface); - + GLContextGLX(); virtual ~GLContextGLX(); - // Initializes the GL context. - bool Initialize(GLContext* shared_context); - // Implement GLContext. + virtual bool Initialize(GLContext* shared_context, + GLSurface* compatible_surface); virtual void Destroy(); - virtual bool MakeCurrent(); - virtual bool IsCurrent(); - virtual bool IsOffscreen(); - virtual bool SwapBuffers(); - virtual gfx::Size GetSize(); + virtual bool MakeCurrent(GLSurface* surface); + virtual void ReleaseCurrent(GLSurface* surface); + virtual bool IsCurrent(GLSurface* surface); virtual void* GetHandle(); virtual void SetSwapInterval(int interval); virtual std::string GetExtensions(); private: - scoped_ptr<GLSurfaceGLX> surface_; void* context_; DISALLOW_COPY_AND_ASSIGN(GLContextGLX); diff --git a/ui/gfx/gl/gl_context_linux.cc b/ui/gfx/gl/gl_context_linux.cc index 3db60f3..b68ed183 100644 --- a/ui/gfx/gl/gl_context_linux.cc +++ b/ui/gfx/gl/gl_context_linux.cc @@ -20,34 +20,26 @@ namespace gfx { -GLContext* GLContext::CreateGLContext(GLSurface* compatible_surface, - GLContext* shared_context) { - scoped_ptr<GLSurface> surface(compatible_surface); - +GLContext* GLContext::CreateGLContext(GLContext* shared_context, + GLSurface* compatible_surface) { switch (GetGLImplementation()) { case kGLImplementationOSMesaGL: { - scoped_ptr<GLContextOSMesa> context( - new GLContextOSMesa(static_cast<GLSurfaceOSMesa*>( - surface.release()))); - if (!context->Initialize(OSMESA_RGBA, shared_context)) + scoped_ptr<GLContextOSMesa> context(new GLContextOSMesa); + if (!context->Initialize(shared_context, compatible_surface)) return NULL; return context.release(); } case kGLImplementationEGLGLES2: { - scoped_ptr<GLContextEGL> context( - new GLContextEGL( - static_cast<GLSurfaceEGL*>(surface.release()))); - if (!context->Initialize(shared_context)) + scoped_ptr<GLContextEGL> context(new GLContextEGL); + if (!context->Initialize(shared_context, compatible_surface)) return NULL; return context.release(); } case kGLImplementationDesktopGL: { - scoped_ptr<GLContextGLX> context( - new GLContextGLX( - static_cast<GLSurfaceGLX*>(surface.release()))); - if (!context->Initialize(shared_context)) + scoped_ptr<GLContextGLX> context(new GLContextGLX); + if (!context->Initialize(shared_context, compatible_surface)) return NULL; return context.release(); diff --git a/ui/gfx/gl/gl_context_mac.cc b/ui/gfx/gl/gl_context_mac.cc index 91ca660..5627d2c 100644 --- a/ui/gfx/gl/gl_context_mac.cc +++ b/ui/gfx/gl/gl_context_mac.cc @@ -16,25 +16,19 @@ namespace gfx { -GLContext* GLContext::CreateGLContext(GLSurface* compatible_surface, - GLContext* shared_context) { - scoped_ptr<GLSurface> surface(compatible_surface); - +GLContext* GLContext::CreateGLContext(GLContext* shared_context, + GLSurface* compatible_surface) { switch (GetGLImplementation()) { case kGLImplementationDesktopGL: { - scoped_ptr<GLContextCGL> context( - new GLContextCGL( - static_cast<GLSurfaceCGL*>(surface.release()))); - if (!context->Initialize(shared_context)) + scoped_ptr<GLContextCGL> context(new GLContextCGL); + if (!context->Initialize(shared_context, compatible_surface)) return NULL; return context.release(); } case kGLImplementationOSMesaGL: { - scoped_ptr<GLContextOSMesa> context( - new GLContextOSMesa( - static_cast<GLSurfaceOSMesa*>(surface.release()))); - if (!context->Initialize(OSMESA_RGBA, shared_context)) + scoped_ptr<GLContextOSMesa> context(new GLContextOSMesa); + if (!context->Initialize(shared_context, compatible_surface)) return NULL; return context.release(); diff --git a/ui/gfx/gl/gl_context_osmesa.cc b/ui/gfx/gl/gl_context_osmesa.cc index cc8b71f..4466fd3 100644 --- a/ui/gfx/gl/gl_context_osmesa.cc +++ b/ui/gfx/gl/gl_context_osmesa.cc @@ -4,31 +4,32 @@ #include <GL/osmesa.h> -#include <algorithm> +#include "ui/gfx/gl/gl_context_osmesa.h" #include "base/logging.h" #include "ui/gfx/gl/gl_bindings.h" -#include "ui/gfx/gl/gl_context_osmesa.h" +#include "ui/gfx/gl/gl_surface_osmesa.h" namespace gfx { -GLContextOSMesa::GLContextOSMesa(GLSurfaceOSMesa* surface) - : surface_(surface), - context_(NULL) -{ +GLContextOSMesa::GLContextOSMesa() + : context_(NULL) { } GLContextOSMesa::~GLContextOSMesa() { Destroy(); } -bool GLContextOSMesa::Initialize(GLuint format, GLContext* shared_context) { +bool GLContextOSMesa::Initialize(GLContext* shared_context, + GLSurface* compatible_surface) { DCHECK(!context_); OSMesaContext shared_handle = NULL; if (shared_context) shared_handle = static_cast<OSMesaContext>(shared_context->GetHandle()); + GLuint format = + static_cast<GLSurfaceOSMesa*>(compatible_surface)->GetFormat(); context_ = OSMesaCreateContextExt(format, 24, // depth bits 8, // stencil bits @@ -47,22 +48,20 @@ void GLContextOSMesa::Destroy() { OSMesaDestroyContext(static_cast<OSMesaContext>(context_)); context_ = NULL; } - - if (surface_.get()) { - surface_->Destroy(); - surface_.reset(); - } } -bool GLContextOSMesa::MakeCurrent() { +bool GLContextOSMesa::MakeCurrent(GLSurface* surface) { DCHECK(context_); - gfx::Size size = surface_->GetSize(); + gfx::Size size = surface->GetSize(); if (!OSMesaMakeCurrent(static_cast<OSMesaContext>(context_), - surface_->GetHandle(), + surface->GetHandle(), GL_UNSIGNED_BYTE, - size.width(), size.height())) { + size.width(), + size.height())) { + LOG(ERROR) << "OSMesaMakeCurrent failed."; + Destroy(); return false; } @@ -72,24 +71,29 @@ bool GLContextOSMesa::MakeCurrent() { return true; } -bool GLContextOSMesa::IsCurrent() { - DCHECK(context_); - return context_ == OSMesaGetCurrentContext(); -} +void GLContextOSMesa::ReleaseCurrent(GLSurface* surface) { + if (!IsCurrent(surface)) + return; -bool GLContextOSMesa::IsOffscreen() { - // TODO(apatrick): remove this from GLContext interface. - return surface_->IsOffscreen(); + OSMesaMakeCurrent(NULL, NULL, GL_UNSIGNED_BYTE, 0, 0); } -bool GLContextOSMesa::SwapBuffers() { - // TODO(apatrick): remove this from GLContext interface. - return surface_->SwapBuffers(); -} +bool GLContextOSMesa::IsCurrent(GLSurface* surface) { + DCHECK(context_); + if (context_ != OSMesaGetCurrentContext()) + return false; -gfx::Size GLContextOSMesa::GetSize() { - // TODO(apatrick): remove this from GLContext interface. - return surface_->GetSize(); + if (surface) { + GLint width; + GLint height; + GLint format; + void* buffer = NULL; + OSMesaGetColorBuffer(context_, &width, &height, &format, &buffer); + if (buffer != surface->GetHandle()) + return false; + } + + return true; } void* GLContextOSMesa::GetHandle() { @@ -97,7 +101,7 @@ void* GLContextOSMesa::GetHandle() { } void GLContextOSMesa::SetSwapInterval(int interval) { - DCHECK(IsCurrent()); + DCHECK(IsCurrent(NULL)); NOTREACHED() << "Attempt to call SetSwapInterval on an GLContextOSMesa."; } diff --git a/ui/gfx/gl/gl_context_osmesa.h b/ui/gfx/gl/gl_context_osmesa.h index 33aa21c..633c0ad 100644 --- a/ui/gfx/gl/gl_context_osmesa.h +++ b/ui/gfx/gl/gl_context_osmesa.h @@ -6,36 +6,31 @@ #define UI_GFX_GL_GL_CONTEXT_OSMESA_H_ #pragma once -#include "base/memory/scoped_ptr.h" #include "ui/gfx/gl/gl_context.h" -#include "ui/gfx/gl/gl_surface_osmesa.h" -#include "ui/gfx/size.h" typedef struct osmesa_context *OSMesaContext; namespace gfx { +class GLSurface; + // Encapsulates an OSMesa OpenGL context that uses software rendering. class GLContextOSMesa : public GLContext { public: - explicit GLContextOSMesa(GLSurfaceOSMesa* surface); + GLContextOSMesa(); virtual ~GLContextOSMesa(); - // Initialize an OSMesa GL context. - bool Initialize(GLuint format, GLContext* shared_context); - // Implement GLContext. + virtual bool Initialize(GLContext* shared_context, + GLSurface* compatible_surface); virtual void Destroy(); - virtual bool MakeCurrent(); - virtual bool IsCurrent(); - virtual bool IsOffscreen(); - virtual bool SwapBuffers(); - virtual gfx::Size GetSize(); + virtual bool MakeCurrent(GLSurface* surface); + virtual void ReleaseCurrent(GLSurface* surface); + virtual bool IsCurrent(GLSurface* surface); virtual void* GetHandle(); virtual void SetSwapInterval(int interval); private: - scoped_ptr<GLSurfaceOSMesa> surface_; OSMesaContext context_; DISALLOW_COPY_AND_ASSIGN(GLContextOSMesa); diff --git a/ui/gfx/gl/gl_context_stub.cc b/ui/gfx/gl/gl_context_stub.cc index 4154cdd..195a396 100644 --- a/ui/gfx/gl/gl_context_stub.cc +++ b/ui/gfx/gl/gl_context_stub.cc @@ -12,30 +12,32 @@ GLContextStub::GLContextStub() { GLContextStub::~GLContextStub() { } -bool GLContextStub::MakeCurrent() { +bool GLContextStub::Initialize(GLContext* shared_context, + GLSurface* compatible_surface) { return true; } -bool GLContextStub::IsCurrent() { - return true; +void GLContextStub::Destroy() { } -bool GLContextStub::IsOffscreen() { - return false; +bool GLContextStub::MakeCurrent(GLSurface* surface) { + return true; } -bool GLContextStub::SwapBuffers() { - return true; +void GLContextStub::ReleaseCurrent(GLSurface* surface) { } -gfx::Size GLContextStub::GetSize() { - return size_; +bool GLContextStub::IsCurrent(GLSurface* surface) { + return true; } void* GLContextStub::GetHandle() { return NULL; } +void GLContextStub::SetSwapInterval(int interval) { +} + std::string GLContextStub::GetExtensions() { return std::string(); } diff --git a/ui/gfx/gl/gl_context_stub.h b/ui/gfx/gl/gl_context_stub.h index 37c49d1..58c2270 100644 --- a/ui/gfx/gl/gl_context_stub.h +++ b/ui/gfx/gl/gl_context_stub.h @@ -16,21 +16,18 @@ class GLContextStub : public GLContext { GLContextStub(); virtual ~GLContextStub(); - void SetSize(const gfx::Size& size) { size_ = size; } - // Implement GLContext. - virtual void Destroy() {} - virtual bool MakeCurrent(); - virtual bool IsCurrent(); - virtual bool IsOffscreen(); - virtual bool SwapBuffers(); - virtual gfx::Size GetSize(); + virtual bool Initialize(GLContext* shared_context, + GLSurface* compatible_surface); + virtual void Destroy(); + virtual bool MakeCurrent(GLSurface* surface); + virtual void ReleaseCurrent(GLSurface* surface); + virtual bool IsCurrent(GLSurface* surface); virtual void* GetHandle(); - virtual void SetSwapInterval(int interval) {} + virtual void SetSwapInterval(int interval); virtual std::string GetExtensions(); private: - gfx::Size size_; DISALLOW_COPY_AND_ASSIGN(GLContextStub); }; diff --git a/ui/gfx/gl/gl_context_wgl.cc b/ui/gfx/gl/gl_context_wgl.cc index 361f8e9..44825c5 100644 --- a/ui/gfx/gl/gl_context_wgl.cc +++ b/ui/gfx/gl/gl_context_wgl.cc @@ -9,13 +9,12 @@ #include "base/logging.h" #include "ui/gfx/gl/gl_bindings.h" #include "ui/gfx/gl/gl_implementation.h" +#include "ui/gfx/gl/gl_surface_wgl.h" namespace gfx { -GLContextWGL::GLContextWGL(GLSurfaceWGL* surface) - : surface_(surface), - context_(NULL) { - DCHECK(surface); +GLContextWGL::GLContextWGL() + : context_(NULL) { } GLContextWGL::~GLContextWGL() { @@ -28,7 +27,7 @@ std::string GLContextWGL::GetExtensions() { // able to use surface_ here. Either use a display device context or the // surface that was passed to MakeCurrent. const char* extensions = wglGetExtensionsStringARB( - static_cast<HDC>(surface_->GetHandle())); + GLSurfaceWGL::GetDisplay()); if (extensions) { return GLContext::GetExtensions() + " " + extensions; } @@ -37,12 +36,15 @@ std::string GLContextWGL::GetExtensions() { return GLContext::GetExtensions(); } -bool GLContextWGL::Initialize(GLContext* shared_context) { +bool GLContextWGL::Initialize(GLContext* shared_context, + GLSurface* compatible_surface) { + GLSurfaceWGL* surface_wgl = static_cast<GLSurfaceWGL*>(compatible_surface); + // TODO(apatrick): When contexts and surfaces are separated, we won't be // able to use surface_ here. Either use a display device context or a // surface that the context is compatible with not necessarily limited to // rendering to. - context_ = wglCreateContext(static_cast<HDC>(surface_->GetHandle())); + context_ = wglCreateContext(static_cast<HDC>(surface_wgl->GetHandle())); if (!context_) { LOG(ERROR) << "Failed to create GL context."; Destroy(); @@ -67,20 +69,14 @@ void GLContextWGL::Destroy() { wglDeleteContext(context_); context_ = NULL; } - - if (surface_.get()) { - surface_->Destroy(); - surface_.reset(); - } } -bool GLContextWGL::MakeCurrent() { - if (IsCurrent()) { +bool GLContextWGL::MakeCurrent(GLSurface* surface) { + DCHECK(context_); + if (IsCurrent(surface)) return true; - } - if (!wglMakeCurrent(static_cast<HDC>(surface_->GetHandle()), - context_)) { + if (!wglMakeCurrent(static_cast<HDC>(surface->GetHandle()), context_)) { LOG(ERROR) << "Unable to make gl context current."; return false; } @@ -88,24 +84,23 @@ bool GLContextWGL::MakeCurrent() { return true; } -bool GLContextWGL::IsCurrent() { - return wglGetCurrentDC() == surface_->GetHandle() && - wglGetCurrentContext() == context_; -} +void GLContextWGL::ReleaseCurrent(GLSurface* surface) { + if (!IsCurrent(surface)) + return; -bool GLContextWGL::IsOffscreen() { - // TODO(apatrick): remove this from GLContext interface. - return surface_->IsOffscreen(); + wglMakeCurrent(NULL, NULL); } -bool GLContextWGL::SwapBuffers() { - // TODO(apatrick): remove this from GLContext interface. - return surface_->SwapBuffers(); -} +bool GLContextWGL::IsCurrent(GLSurface* surface) { + if (wglGetCurrentContext() != context_) + return false; -gfx::Size GLContextWGL::GetSize() { - // TODO(apatrick): remove this from GLContext interface. - return surface_->GetSize(); + if (surface) { + if (wglGetCurrentDC() != surface->GetHandle()) + return false; + } + + return true; } void* GLContextWGL::GetHandle() { @@ -113,7 +108,7 @@ void* GLContextWGL::GetHandle() { } void GLContextWGL::SetSwapInterval(int interval) { - DCHECK(IsCurrent()); + DCHECK(IsCurrent(NULL)); if (HasExtension("WGL_EXT_swap_control") && wglSwapIntervalEXT) { wglSwapIntervalEXT(interval); } diff --git a/ui/gfx/gl/gl_context_wgl.h b/ui/gfx/gl/gl_context_wgl.h index c5c5783..f48a564 100644 --- a/ui/gfx/gl/gl_context_wgl.h +++ b/ui/gfx/gl/gl_context_wgl.h @@ -7,35 +7,31 @@ #include <string> -#include "base/memory/scoped_ptr.h" #include "ui/gfx/gl/gl_context.h" -#include "ui/gfx/gl/gl_surface_wgl.h" -#include "ui/gfx/size.h" +#include "ui/gfx/native_widget_types.h" namespace gfx { +class GLSurface; + // This class is a wrapper around a GL context. class GLContextWGL : public GLContext { public: - explicit GLContextWGL(GLSurfaceWGL* surface); + GLContextWGL(); virtual ~GLContextWGL(); - // Initializes the GL context. - bool Initialize(GLContext* shared_context); - // Implement GLContext. + virtual bool Initialize(GLContext* shared_context, + GLSurface* compatible_surface); virtual void Destroy(); - virtual bool MakeCurrent(); - virtual bool IsCurrent(); - virtual bool IsOffscreen(); - virtual bool SwapBuffers(); - virtual gfx::Size GetSize(); + virtual bool MakeCurrent(GLSurface* surface); + virtual void ReleaseCurrent(GLSurface* surface); + virtual bool IsCurrent(GLSurface* surface); virtual void* GetHandle(); virtual void SetSwapInterval(int interval); virtual std::string GetExtensions(); private: - scoped_ptr<GLSurfaceWGL> surface_; HGLRC context_; DISALLOW_COPY_AND_ASSIGN(GLContextWGL); diff --git a/ui/gfx/gl/gl_context_win.cc b/ui/gfx/gl/gl_context_win.cc index ff5c142..90bca79 100644 --- a/ui/gfx/gl/gl_context_win.cc +++ b/ui/gfx/gl/gl_context_win.cc @@ -20,34 +20,26 @@ namespace gfx { -GLContext* GLContext::CreateGLContext(GLSurface* compatible_surface, - GLContext* shared_context) { - scoped_ptr<GLSurface> surface(compatible_surface); - +GLContext* GLContext::CreateGLContext(GLContext* shared_context, + GLSurface* compatible_surface) { switch (GetGLImplementation()) { case kGLImplementationOSMesaGL: { - scoped_ptr<GLContextOSMesa> context( - new GLContextOSMesa(static_cast<GLSurfaceOSMesa*>( - surface.release()))); - if (!context->Initialize(OSMESA_RGBA, shared_context)) + scoped_ptr<GLContextOSMesa> context(new GLContextOSMesa); + if (!context->Initialize(shared_context, compatible_surface)) return NULL; return context.release(); } case kGLImplementationEGLGLES2: { - scoped_ptr<GLContextEGL> context( - new GLContextEGL(static_cast<GLSurfaceEGL*>( - surface.release()))); - if (!context->Initialize(shared_context)) + scoped_ptr<GLContextEGL> context(new GLContextEGL); + if (!context->Initialize(shared_context, compatible_surface)) return NULL; return context.release(); } case kGLImplementationDesktopGL: { - scoped_ptr<GLContextWGL> context( - new GLContextWGL(static_cast<GLSurfaceWGL*>( - surface.release()))); - if (!context->Initialize(shared_context)) + scoped_ptr<GLContextWGL> context(new GLContextWGL); + if (!context->Initialize(shared_context, compatible_surface)) return NULL; return context.release(); diff --git a/ui/gfx/gl/gl_surface_egl.cc b/ui/gfx/gl/gl_surface_egl.cc index 2973dd0..55cbc55 100644 --- a/ui/gfx/gl/gl_surface_egl.cc +++ b/ui/gfx/gl/gl_surface_egl.cc @@ -59,6 +59,7 @@ bool GLSurfaceEGL::InitializeOneOff() { EGL_BUFFER_SIZE, 32, EGL_ALPHA_SIZE, 8, EGL_BLUE_SIZE, 8, + EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_DEPTH_SIZE, 16, EGL_STENCIL_SIZE, 8, diff --git a/ui/gfx/gl/gl_surface_glx.cc b/ui/gfx/gl/gl_surface_glx.cc index 1969583..ed36642 100644 --- a/ui/gfx/gl/gl_surface_glx.cc +++ b/ui/gfx/gl/gl_surface_glx.cc @@ -270,6 +270,7 @@ bool PbufferGLSurfaceGLX::Initialize() { GLX_BUFFER_SIZE, 32, GLX_ALPHA_SIZE, 8, GLX_BLUE_SIZE, 8, + GLX_GREEN_SIZE, 8, GLX_RED_SIZE, 8, GLX_DEPTH_SIZE, 16, // TODO(apatrick): support optional depth buffer GLX_STENCIL_SIZE, 8, diff --git a/ui/gfx/gl/gl_surface_linux.cc b/ui/gfx/gl/gl_surface_linux.cc index d564c2f..26c1631 100644 --- a/ui/gfx/gl/gl_surface_linux.cc +++ b/ui/gfx/gl/gl_surface_linux.cc @@ -96,7 +96,7 @@ bool GLSurface::InitializeOneOff() { NativeViewGLSurfaceOSMesa::NativeViewGLSurfaceOSMesa( gfx::PluginWindowHandle window) - : GLSurfaceOSMesa(gfx::Size()), + : GLSurfaceOSMesa(OSMESA_BGRA, gfx::Size()), window_graphics_context_(0), window_(window), pixmap_graphics_context_(0), @@ -280,7 +280,8 @@ GLSurface* GLSurface::CreateViewGLSurface(gfx::PluginWindowHandle window) { GLSurface* GLSurface::CreateOffscreenGLSurface(const gfx::Size& size) { switch (GetGLImplementation()) { case kGLImplementationOSMesaGL: { - scoped_ptr<GLSurfaceOSMesa> surface(new GLSurfaceOSMesa(size)); + scoped_ptr<GLSurfaceOSMesa> surface(new GLSurfaceOSMesa(OSMESA_RGBA, + size)); if (!surface->Initialize()) return NULL; diff --git a/ui/gfx/gl/gl_surface_mac.cc b/ui/gfx/gl/gl_surface_mac.cc index 4af014a..bb08ef8 100644 --- a/ui/gfx/gl/gl_surface_mac.cc +++ b/ui/gfx/gl/gl_surface_mac.cc @@ -80,7 +80,8 @@ GLSurface* GLSurface::CreateViewGLSurface(gfx::PluginWindowHandle window) { GLSurface* GLSurface::CreateOffscreenGLSurface(const gfx::Size& size) { switch (GetGLImplementation()) { case kGLImplementationOSMesaGL: { - scoped_ptr<GLSurfaceOSMesa> surface(new GLSurfaceOSMesa(size)); + scoped_ptr<GLSurfaceOSMesa> surface(new GLSurfaceOSMesa(OSMESA_RGBA, + size)); if (!surface->Initialize()) return NULL; diff --git a/ui/gfx/gl/gl_surface_osmesa.cc b/ui/gfx/gl/gl_surface_osmesa.cc index caff295..3fdf8fb 100644 --- a/ui/gfx/gl/gl_surface_osmesa.cc +++ b/ui/gfx/gl/gl_surface_osmesa.cc @@ -8,7 +8,9 @@ namespace gfx { -GLSurfaceOSMesa::GLSurfaceOSMesa(const gfx::Size& size) : size_(size) { +GLSurfaceOSMesa::GLSurfaceOSMesa(unsigned format, const gfx::Size& size) + : format_(format), + size_(size) { } GLSurfaceOSMesa::~GLSurfaceOSMesa() { @@ -63,6 +65,10 @@ void* GLSurfaceOSMesa::GetHandle() { return buffer_.get(); } +unsigned GLSurfaceOSMesa::GetFormat() { + return format_; +} + void GLSurfaceOSMesa::AllocateBuffer(const Size& size) { buffer_.reset(new int32[size.GetArea()]); memset(buffer_.get(), 0, size.GetArea() * sizeof(buffer_[0])); diff --git a/ui/gfx/gl/gl_surface_osmesa.h b/ui/gfx/gl/gl_surface_osmesa.h index 5ad618d..2ea9c88 100644 --- a/ui/gfx/gl/gl_surface_osmesa.h +++ b/ui/gfx/gl/gl_surface_osmesa.h @@ -17,7 +17,7 @@ namespace gfx { // surfaces can be resized and resizing preserves the contents. class GLSurfaceOSMesa : public GLSurface { public: - explicit GLSurfaceOSMesa(const gfx::Size& size); + explicit GLSurfaceOSMesa(unsigned format, const gfx::Size& size); virtual ~GLSurfaceOSMesa(); // Resize the back buffer, preserving the old content. Does nothing if the @@ -32,9 +32,13 @@ class GLSurfaceOSMesa : public GLSurface { virtual gfx::Size GetSize(); virtual void* GetHandle(); + // Get the surface's format. + unsigned GetFormat(); + private: void AllocateBuffer(const Size& size); + unsigned format_; gfx::Size size_; scoped_array<int32> buffer_; diff --git a/ui/gfx/gl/gl_surface_wgl.cc b/ui/gfx/gl/gl_surface_wgl.cc index 73ff12e..c2d72b6 100644 --- a/ui/gfx/gl/gl_surface_wgl.cc +++ b/ui/gfx/gl/gl_surface_wgl.cc @@ -2,7 +2,7 @@ // 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_wgl.h" +#include "ui/gfx/gl/gl_surface_wgl.h" #include "base/logging.h" #include "ui/gfx/gl/gl_bindings.h" @@ -12,6 +12,7 @@ namespace gfx { static ATOM g_class_registration; static HWND g_window; +HDC g_display_dc; static int g_pixel_format = 0; const PIXELFORMATDESCRIPTOR kPixelFormatDescriptor = { @@ -111,43 +112,39 @@ bool GLSurfaceWGL::InitializeOneOff() { return false; } - HDC temporary_dc = GetDC(g_window); + g_display_dc = GetDC(g_window); - g_pixel_format = ChoosePixelFormat(temporary_dc, + g_pixel_format = ChoosePixelFormat(g_display_dc, &kPixelFormatDescriptor); if (g_pixel_format == 0) { LOG(ERROR) << "Unable to get the pixel format for GL context."; - ReleaseDC(g_window, temporary_dc); UnregisterClass(reinterpret_cast<wchar_t*>(g_class_registration), module_handle); return false; } - if (!SetPixelFormat(temporary_dc, + if (!SetPixelFormat(g_display_dc, g_pixel_format, &kPixelFormatDescriptor)) { LOG(ERROR) << "Unable to set the pixel format for temporary GL context."; - ReleaseDC(g_window, temporary_dc); UnregisterClass(reinterpret_cast<wchar_t*>(g_class_registration), module_handle); return false; } // Create a temporary GL context to bind to extension entry points. - HGLRC gl_context = wglCreateContext(temporary_dc); + HGLRC gl_context = wglCreateContext(g_display_dc); if (!gl_context) { LOG(ERROR) << "Failed to create temporary context."; - ReleaseDC(g_window, temporary_dc); UnregisterClass(reinterpret_cast<wchar_t*>(g_class_registration), module_handle); return false; } - if (!wglMakeCurrent(temporary_dc, gl_context)) { + if (!wglMakeCurrent(g_display_dc, gl_context)) { LOG(ERROR) << "Failed to make temporary GL context current."; wglDeleteContext(gl_context); - ReleaseDC(g_window, temporary_dc); UnregisterClass(reinterpret_cast<wchar_t*>(g_class_registration), module_handle); return false; @@ -160,12 +157,15 @@ bool GLSurfaceWGL::InitializeOneOff() { wglMakeCurrent(NULL, NULL); wglDeleteContext(gl_context); - ReleaseDC(g_window, temporary_dc); initialized = true; return true; } +HDC GLSurfaceWGL::GetDisplay() { + return g_display_dc; +} + NativeViewGLSurfaceWGL::NativeViewGLSurfaceWGL(gfx::PluginWindowHandle window) : window_(window), child_window_(NULL), @@ -287,22 +287,12 @@ bool PbufferGLSurfaceWGL::Initialize() { return false; } - // Create a temporary device context for the display. The pbuffer will be - // compatible with it. - HDC temporary_dc = GetDC(g_window); - if (!temporary_dc) { - LOG(ERROR) << "Unable to get device context."; - return false; - } - const int kNoAttributes[] = { 0 }; - pbuffer_ = wglCreatePbufferARB(temporary_dc, + pbuffer_ = wglCreatePbufferARB(g_display_dc, g_pixel_format, size_.width(), size_.height(), kNoAttributes); - ReleaseDC(g_window, temporary_dc); - if (!pbuffer_) { LOG(ERROR) << "Unable to create pbuffer."; Destroy(); diff --git a/ui/gfx/gl/gl_surface_wgl.h b/ui/gfx/gl/gl_surface_wgl.h index 1684fdb..bb4b71b 100644 --- a/ui/gfx/gl/gl_surface_wgl.h +++ b/ui/gfx/gl/gl_surface_wgl.h @@ -17,6 +17,8 @@ class GLSurfaceWGL : public GLSurface { virtual ~GLSurfaceWGL(); static bool InitializeOneOff(); + static HDC GetDisplay(); + private: DISALLOW_COPY_AND_ASSIGN(GLSurfaceWGL); }; diff --git a/ui/gfx/gl/gl_surface_win.cc b/ui/gfx/gl/gl_surface_win.cc index 8c35540..594a263 100644 --- a/ui/gfx/gl/gl_surface_win.cc +++ b/ui/gfx/gl/gl_surface_win.cc @@ -82,7 +82,7 @@ bool GLSurface::InitializeOneOff() { NativeViewGLSurfaceOSMesa::NativeViewGLSurfaceOSMesa( gfx::PluginWindowHandle window) - : GLSurfaceOSMesa(gfx::Size()), + : GLSurfaceOSMesa(OSMESA_RGBA, gfx::Size()), window_(window), device_context_(NULL) { DCHECK(window); @@ -105,7 +105,6 @@ void NativeViewGLSurfaceOSMesa::Destroy() { if (window_ && device_context_) ReleaseDC(window_, device_context_); - window_ = NULL; device_context_ = NULL; GLSurfaceOSMesa::Destroy(); @@ -205,7 +204,8 @@ GLSurface* GLSurface::CreateViewGLSurface(gfx::PluginWindowHandle window) { GLSurface* GLSurface::CreateOffscreenGLSurface(const gfx::Size& size) { switch (GetGLImplementation()) { case kGLImplementationOSMesaGL: { - scoped_ptr<GLSurfaceOSMesa> surface(new GLSurfaceOSMesa(size)); + scoped_ptr<GLSurfaceOSMesa> surface(new GLSurfaceOSMesa(OSMESA_RGBA, + size)); if (!surface->Initialize()) return NULL; diff --git a/ui/gfx/surface/accelerated_surface_mac.cc b/ui/gfx/surface/accelerated_surface_mac.cc index 2210a6f..a749c46 100644 --- a/ui/gfx/surface/accelerated_surface_mac.cc +++ b/ui/gfx/surface/accelerated_surface_mac.cc @@ -35,15 +35,14 @@ bool AcceleratedSurface::Initialize(gfx::GLContext* share_context, if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) return false; - scoped_ptr<gfx::GLSurface> surface(gfx::GLSurface::CreateOffscreenGLSurface( - gfx::Size(1, 1))); - if (!surface.get()) { + gl_surface_.reset(gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1))); + if (!gl_surface_.get()) { Destroy(); return false; } - gl_context_.reset(gfx::GLContext::CreateGLContext(surface.release(), - share_context)); + gl_context_.reset(gfx::GLContext::CreateGLContext(share_context, + gl_surface_.get())); if (!gl_context_.get()) { Destroy(); return false; @@ -67,9 +66,8 @@ void AcceleratedSurface::Destroy() { } transport_dib_.reset(); - if (gl_context_.get()) - gl_context_->Destroy(); gl_context_.reset(); + gl_surface_.reset(); } // Call after making changes to the surface which require a visual update. @@ -199,11 +197,11 @@ bool AcceleratedSurface::SetupFrameBufferObject(GLenum target) { bool AcceleratedSurface::MakeCurrent() { if (!gl_context_.get()) return false; - return gl_context_->MakeCurrent(); + return gl_context_->MakeCurrent(gl_surface_.get()); } void AcceleratedSurface::Clear(const gfx::Rect& rect) { - DCHECK(gl_context_->IsCurrent()); + DCHECK(gl_context_->IsCurrent(gl_surface_.get())); glClearColor(0, 0, 0, 0); glViewport(0, 0, rect.width(), rect.height()); glMatrixMode(GL_PROJECTION); @@ -334,7 +332,7 @@ TransportDIB::Handle AcceleratedSurface::SetTransportDIBSize( } if (allocate_fbo_) { - DCHECK(gl_context_->IsCurrent()); + DCHECK(gl_context_->IsCurrent(gl_surface_.get())); // Set up the render buffers and reserve enough space on the card for the // framebuffer texture. GLenum target = GL_TEXTURE_RECTANGLE_ARB; diff --git a/ui/gfx/surface/accelerated_surface_mac.h b/ui/gfx/surface/accelerated_surface_mac.h index 0c780ab..13bec9b 100644 --- a/ui/gfx/surface/accelerated_surface_mac.h +++ b/ui/gfx/surface/accelerated_surface_mac.h @@ -14,6 +14,7 @@ #include "ui/gfx/rect.h" #include "ui/gfx/size.h" #include "ui/gfx/gl/gl_context.h" +#include "ui/gfx/gl/gl_surface.h" #include "ui/gfx/surface/transport_dib.h" // Should not include GL headers in a header file. Forward declare these types @@ -128,6 +129,7 @@ class AcceleratedSurface { // speaking, we do not need to allocate a GL context all of the // time. We only need one if (a) we are using the IOSurface code // path, or (b) if we are allocating an FBO internally. + scoped_ptr<gfx::GLSurface> gl_surface_; scoped_ptr<gfx::GLContext> gl_context_; // Either |io_surface_| or |transport_dib_| is a valid pointer, but not both. // |io_surface_| is non-NULL if the IOSurface APIs are supported (Mac OS X |