diff options
author | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-21 21:31:53 +0000 |
---|---|---|
committer | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-21 21:31:53 +0000 |
commit | 96f8063420f0170207f8b8fad211c70d3ad66db6 (patch) | |
tree | ecd625784f6ccf6a699f51a888e7e70056ab4bc0 /gfx | |
parent | d3d0ef9739170a270dcb2f070f2364aa003aea9c (diff) | |
download | chromium_src-96f8063420f0170207f8b8fad211c70d3ad66db6.zip chromium_src-96f8063420f0170207f8b8fad211c70d3ad66db6.tar.gz chromium_src-96f8063420f0170207f8b8fad211c70d3ad66db6.tar.bz2 |
Revert 45240 - Moved GLContext class to gfx/gl.
Now it can be used by code outside of the gpu project, for example AcceleratedSurface.
TEST=trybots
BUG=none
Review URL: http://codereview.chromium.org/1694003
TBR=jamesr@chromium.org
Review URL: http://codereview.chromium.org/1747007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@45244 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gfx')
-rw-r--r-- | gfx/gfx.gyp | 24 | ||||
-rw-r--r-- | gfx/gl/gl_context.cc | 86 | ||||
-rw-r--r-- | gfx/gl/gl_context.h | 64 | ||||
-rw-r--r-- | gfx/gl/gl_context_linux.cc | 402 | ||||
-rw-r--r-- | gfx/gl/gl_context_mac.cc | 183 | ||||
-rw-r--r-- | gfx/gl/gl_context_osmesa.cc | 109 | ||||
-rw-r--r-- | gfx/gl/gl_context_osmesa.h | 57 | ||||
-rw-r--r-- | gfx/gl/gl_context_win.cc | 625 |
8 files changed, 0 insertions, 1550 deletions
diff --git a/gfx/gfx.gyp b/gfx/gfx.gyp index d5a06aa..4b7d612 100644 --- a/gfx/gfx.gyp +++ b/gfx/gfx.gyp @@ -130,30 +130,6 @@ }], ], }, - { - 'target_name': 'gfx_gl', - 'type': 'static_library', - 'include_dirs': [ - '..', - '../third_party/glew/include', - ], - 'defines': [ - 'GLEW_STATIC', - ], - 'sources': [ - 'gl/gl_context.cc', - 'gl/gl_context.h', - 'gl/gl_context_osmesa.cc', - 'gl/gl_context_osmesa.h', - 'gl/gl_context_linux.cc', - 'gl/gl_context_linux.h', - 'gl/gl_context_mac.cc', - 'gl/gl_context_mac.h', - 'gl/gl_context_win.cc', - 'gl/gl_context_win.h', - '../third_party/glew/src/glew.c', - ], - }, ], } diff --git a/gfx/gl/gl_context.cc b/gfx/gl/gl_context.cc deleted file mode 100644 index cf9b111..0000000 --- a/gfx/gl/gl_context.cc +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (c) 2009 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 <GL/glew.h> - -#include "gfx/gl/gl_context.h" -#include "base/logging.h" - -namespace gfx { - -// GLEW initialization is extremely expensive because it looks up -// hundreds of function pointers. Realistically we are not going to -// switch between GL implementations on the fly, so for the time being -// we only do the context-dependent GLEW initialization once. -bool InitializeGLEW() { -#if defined(UNIT_TEST) - return true; -#else - static bool initialized = false; - if (initialized) - return true; - - // Initializes context-dependent parts of GLEW. - if (glewInit() != GLEW_OK) { - LOG(ERROR) << "GLEW failed initialization"; - return false; - } - - // Check to see that we can use the OpenGL vertex attribute APIs - // TODO(petersont): Return false if this check fails, but because some - // Intel hardware does not support OpenGL 2.0, yet does support all of the - // extensions we require, we only log an error. A future CL should change - // this check to ensure that all of the extension strings we require are - // present. - if (!GLEW_VERSION_2_0) { - DLOG(ERROR) << "GL drivers do not have OpenGL 2.0 functionality."; - } - - // Check for necessary extensions. - bool extensions_found = true; - if (!GLEW_ARB_vertex_buffer_object) { - // NOTE: Linux NVidia drivers claim to support OpenGL 2.0 when using - // indirect rendering (e.g. remote X), but it is actually lying. The - // ARB_vertex_buffer_object functions silently no-op (!) when using - // indirect rendering, leading to crashes. Fortunately, in that case, the - // driver claims to not support ARB_vertex_buffer_object, so fail in that - // case. - DLOG(ERROR) << "GL drivers do not support vertex buffer objects."; - extensions_found = false; - } - if (!GLEW_EXT_framebuffer_object) { - DLOG(ERROR) << "GL drivers do not support framebuffer objects."; - extensions_found = false; - } - if (!GLEW_VERSION_2_0 && !GLEW_EXT_stencil_two_side) { - DLOG(ERROR) << "Two sided stencil extension missing."; - extensions_found = false; - } - if (!GLEW_VERSION_1_4 && !GLEW_EXT_blend_func_separate) { - DLOG(ERROR) <<"Separate blend func extension missing."; - extensions_found = false; - } - if (!GLEW_VERSION_2_0 && !GLEW_EXT_blend_equation_separate) { - DLOG(ERROR) << "Separate blend function extension missing."; - extensions_found = false; - } - if (!extensions_found) - return false; - - initialized = true; - return true; -#endif -} - -bool GLContext::InitializeCommon() { - if (!MakeCurrent()) - return false; - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - if (glGetError() != GL_NO_ERROR) - return false; - - return true; -} -} // namespace gfx diff --git a/gfx/gl/gl_context.h b/gfx/gl/gl_context.h deleted file mode 100644 index a115f28..0000000 --- a/gfx/gl/gl_context.h +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) 2010 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 GFX_GL_GL_CONTEXT_H_ -#define GFX_GL_GL_CONTEXT_H_ - -#include "build/build_config.h" -#include "gfx/native_widget_types.h" -#include "gfx/size.h" -#include "gpu/command_buffer/common/logging.h" - -namespace gfx { - -bool InitializeGLEW(); - -// Encapsulates an OpenGL context, hiding platform specific management. -class GLContext { - public: - GLContext() {} - virtual ~GLContext() {} - - // Destroys the GL context. - virtual void Destroy() = 0; - - // Makes the GL context current on the current thread. - virtual bool MakeCurrent() = 0; - - // Returns true if this context is current. - virtual bool IsCurrent() = 0; - - // Returns true if this context is offscreen. - virtual bool IsOffscreen() = 0; - - // Swaps front and back buffers. This has no effect for off-screen - // contexts. - virtual void SwapBuffers() = 0; - - // Get the size of the back buffer. - virtual gfx::Size GetSize() = 0; - - // Get the underlying platform specific GL context "handle". - virtual void* GetHandle() = 0; - -#if !defined(OS_MACOSX) - // Create a GL context that renders directly to a view. - static GLContext* CreateViewGLContext(gfx::PluginWindowHandle window, - bool multisampled); -#endif - - // Create 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. - static GLContext* CreateOffscreenGLContext(void* shared_handle); - - protected: - bool InitializeCommon(); - - private: - DISALLOW_COPY_AND_ASSIGN(GLContext); -}; - -} // namespace gfx - -#endif // GFX_GL_GL_CONTEXT_H_ diff --git a/gfx/gl/gl_context_linux.cc b/gfx/gl/gl_context_linux.cc deleted file mode 100644 index 42bdc37e..0000000 --- a/gfx/gl/gl_context_linux.cc +++ /dev/null @@ -1,402 +0,0 @@ -// Copyright (c) 2010 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. - -// This file implements the ViewGLContext and PbufferGLContext classes. - -#include <dlfcn.h> -#include <GL/glew.h> -#include <GL/glxew.h> -#include <GL/glx.h> -#include <GL/osmew.h> -#include <X11/Xlib.h> -#include <X11/Xutil.h> - -#include "app/x11_util.h" -#include "base/logging.h" -#include "base/scoped_ptr.h" -#include "gfx/gl/gl_context.h" -#include "gfx/gl/gl_context_osmesa.h" - -namespace gfx { - -typedef GLXContext GLContextHandle; -typedef GLXPbuffer PbufferHandle; - -// This class is a wrapper around a GL context that renders directly to a -// window. -class ViewGLContext : public GLContext { - public: - explicit ViewGLContext(gfx::PluginWindowHandle window) - : window_(window), - context_(NULL) { - DCHECK(window); - } - - // Initializes the GL context. - bool Initialize(bool multisampled); - - virtual void Destroy(); - virtual bool MakeCurrent(); - virtual bool IsCurrent(); - virtual bool IsOffscreen(); - virtual void SwapBuffers(); - virtual gfx::Size GetSize(); - virtual void* GetHandle(); - - private: - gfx::PluginWindowHandle window_; - GLContextHandle context_; - - DISALLOW_COPY_AND_ASSIGN(ViewGLContext); -}; - -// 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: - explicit PbufferGLContext() - : context_(NULL), - pbuffer_(NULL) { - } - - // Initializes the GL context. - bool Initialize(void* shared_handle); - - virtual void Destroy(); - virtual bool MakeCurrent(); - virtual bool IsCurrent(); - virtual bool IsOffscreen(); - virtual void SwapBuffers(); - virtual gfx::Size GetSize(); - virtual void* GetHandle(); - - private: - GLContextHandle context_; - PbufferHandle pbuffer_; - - DISALLOW_COPY_AND_ASSIGN(PbufferGLContext); -}; - -// scoped_ptr functor for XFree(). Use as follows: -// scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> foo(...); -// where "XVisualInfo" is any X type that is freed with XFree. -class ScopedPtrXFree { - public: - void operator()(void* x) const { - ::XFree(x); - } -}; - -// Some versions of NVIDIA's GL libGL.so include a broken version of -// dlopen/dlsym, and so linking it into chrome breaks it. So we dynamically -// load it, and use glew to dynamically resolve symbols. -// See http://code.google.com/p/chromium/issues/detail?id=16800 - -static bool InitializeOneOff() { - static bool initialized = false; - if (initialized) - return true; - - osmewInit(); - if (!OSMesaCreateContext) { - void* handle = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL); - if (!handle) { - LOG(ERROR) << "Could not find libGL.so.1"; - return false; - } - - // Initializes context-independent parts of GLEW - if (glxewInit() != GLEW_OK) { - LOG(ERROR) << "glxewInit failed"; - return false; - } - // glxewContextInit really only needs a display connection to - // complete, and we don't want to have to create an OpenGL context - // just to get access to GLX 1.3 entry points to create pbuffers. - // We therefore added a glxewContextInitWithDisplay entry point. - Display* display = x11_util::GetXDisplay(); - if (glxewContextInitWithDisplay(display) != GLEW_OK) { - LOG(ERROR) << "glxewContextInit failed"; - return false; - } - } - - initialized = true; - return true; -} - -bool ViewGLContext::Initialize(bool multisampled) { - if (multisampled) { - DLOG(WARNING) << "Multisampling not implemented."; - } - - Display* display = x11_util::GetXDisplay(); - XWindowAttributes attributes; - XGetWindowAttributes(display, window_, &attributes); - XVisualInfo visual_info_template; - visual_info_template.visualid = XVisualIDFromVisual(attributes.visual); - int visual_info_count = 0; - scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> visual_info_list( - XGetVisualInfo(display, VisualIDMask, - &visual_info_template, - &visual_info_count)); - DCHECK(visual_info_list.get()); - DCHECK_GT(visual_info_count, 0); - context_ = NULL; - for (int i = 0; i < visual_info_count; ++i) { - context_ = glXCreateContext(display, visual_info_list.get() + i, 0, True); - if (context_) - break; - } - if (!context_) { - DLOG(ERROR) << "Couldn't create GL context."; - return false; - } - - if (!MakeCurrent()) { - Destroy(); - DLOG(ERROR) << "Couldn't make context current for initialization."; - return false; - } - - if (!InitializeGLEW()) { - Destroy(); - return false; - } - - if (!InitializeCommon()) { - Destroy(); - return false; - } - - return true; -} - -void ViewGLContext::Destroy() { - Display* display = x11_util::GetXDisplay(); - Bool result = glXMakeCurrent(display, 0, 0); - - // glXMakeCurrent isn't supposed to fail when unsetting the context, unless - // we have pending draws on an invalid window - which shouldn't be the case - // here. - DCHECK(result); - if (context_) { - glXDestroyContext(display, context_); - context_ = NULL; - } -} - -bool ViewGLContext::MakeCurrent() { - if (IsCurrent()) { - return true; - } - - Display* display = x11_util::GetXDisplay(); - if (glXMakeCurrent(display, window_, context_) != True) { - glXDestroyContext(display, context_); - context_ = 0; - DLOG(ERROR) << "Couldn't make context current."; - return false; - } - - return true; -} - -bool ViewGLContext::IsCurrent() { - return glXGetCurrentDrawable() == window_ && - glXGetCurrentContext() == context_; -} - -bool ViewGLContext::IsOffscreen() { - return false; -} - -void ViewGLContext::SwapBuffers() { - Display* display = x11_util::GetXDisplay(); - glXSwapBuffers(display, window_); -} - -gfx::Size ViewGLContext::GetSize() { - XWindowAttributes attributes; - Display* display = x11_util::GetXDisplay(); - XGetWindowAttributes(display, window_, &attributes); - return gfx::Size(attributes.width, attributes.height); -} - -void* ViewGLContext::GetHandle() { - return context_; -} - -GLContext* GLContext::CreateViewGLContext(gfx::PluginWindowHandle window, - bool multisampled) { - if (!InitializeOneOff()) - return NULL; - - if (OSMesaCreateContext) { - // TODO(apatrick): Support OSMesa rendering to a window on Linux. - NOTREACHED() << "OSMesa rendering to a window is not yet implemented."; - return NULL; - } else { - scoped_ptr<ViewGLContext> context(new ViewGLContext(window)); - - if (!context->Initialize(multisampled)) - return NULL; - - return context.release(); - } -} - -bool PbufferGLContext::Initialize(void* shared_handle) { - if (!glXChooseFBConfig || - !glXCreateNewContext || - !glXCreatePbuffer || - !glXDestroyPbuffer) { - DLOG(ERROR) << "Pbuffer support not available."; - return false; - } - - static const int config_attributes[] = { - GLX_DRAWABLE_TYPE, - GLX_PBUFFER_BIT, - GLX_RENDER_TYPE, - GLX_RGBA_BIT, - GLX_DOUBLEBUFFER, - 0, - 0 - }; - - Display* display = x11_util::GetXDisplay(); - - int nelements = 0; - // TODO(kbr): figure out whether hardcoding screen to 0 is sufficient. - scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> config( - glXChooseFBConfig(display, 0, config_attributes, &nelements)); - if (!config.get()) { - DLOG(ERROR) << "glXChooseFBConfig failed."; - return false; - } - if (!nelements) { - DLOG(ERROR) << "glXChooseFBConfig returned 0 elements."; - return false; - } - context_ = glXCreateNewContext(display, - config.get()[0], - GLX_RGBA_TYPE, - static_cast<GLContextHandle>(shared_handle), - True); - if (!context_) { - DLOG(ERROR) << "glXCreateNewContext failed."; - return false; - } - static const int pbuffer_attributes[] = { - GLX_PBUFFER_WIDTH, - 1, - GLX_PBUFFER_HEIGHT, - 1, - 0 - }; - pbuffer_ = glXCreatePbuffer(display, - config.get()[0], pbuffer_attributes); - if (!pbuffer_) { - Destroy(); - DLOG(ERROR) << "glXCreatePbuffer failed."; - return false; - } - - if (!MakeCurrent()) { - Destroy(); - DLOG(ERROR) << "Couldn't make context current for initialization."; - return false; - } - - if (!InitializeGLEW()) { - Destroy(); - return false; - } - - if (!InitializeCommon()) { - Destroy(); - return false; - } - - return true; -} - -void PbufferGLContext::Destroy() { - Display* display = x11_util::GetXDisplay(); - Bool result = glXMakeCurrent(display, 0, 0); - // glXMakeCurrent isn't supposed to fail when unsetting the context, unless - // we have pending draws on an invalid window - which shouldn't be the case - // here. - DCHECK(result); - if (context_) { - glXDestroyContext(display, context_); - context_ = NULL; - } - - if (pbuffer_) { - glXDestroyPbuffer(display, pbuffer_); - pbuffer_ = NULL; - } -} - -bool PbufferGLContext::MakeCurrent() { - if (IsCurrent()) { - return true; - } - Display* display = x11_util::GetXDisplay(); - if (glXMakeCurrent(display, pbuffer_, context_) != True) { - glXDestroyContext(display, context_); - context_ = NULL; - DLOG(ERROR) << "Couldn't make context current."; - return false; - } - - return true; -} - -bool PbufferGLContext::IsCurrent() { - return glXGetCurrentDrawable() == pbuffer_ && - glXGetCurrentContext() == context_; -} - -bool PbufferGLContext::IsOffscreen() { - return true; -} - -void PbufferGLContext::SwapBuffers() { - NOTREACHED() << "Attempted to call SwapBuffers on a pbuffer."; -} - -gfx::Size PbufferGLContext::GetSize() { - NOTREACHED() << "Should not be requesting size of this pbuffer."; - return gfx::Size(1, 1); -} - -void* PbufferGLContext::GetHandle() { - return context_; -} - -GLContext* GLContext::CreateOffscreenGLContext(void* shared_handle) { - if (!InitializeOneOff()) - return NULL; - - if (OSMesaCreateContext) { - scoped_ptr<OSMesaGLContext> context(new OSMesaGLContext); - - if (!context->Initialize(shared_handle)) - return NULL; - - return context.release(); - } else { - scoped_ptr<PbufferGLContext> context(new PbufferGLContext); - if (!context->Initialize(shared_handle)) - return NULL; - - return context.release(); - } -} - -} // namespace gfx diff --git a/gfx/gl/gl_context_mac.cc b/gfx/gl/gl_context_mac.cc deleted file mode 100644 index 65121ca..0000000 --- a/gfx/gl/gl_context_mac.cc +++ /dev/null @@ -1,183 +0,0 @@ -// Copyright (c) 2010 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. - -// This file implements the ViewGLContext and PbufferGLContext classes. - -#include <GL/glew.h> -#include <GL/osmew.h> -#include <OpenGL/OpenGL.h> - -#include "app/surface/accelerated_surface_mac.h" -#include "base/logging.h" -#include "base/scoped_ptr.h" -#include "gfx/gl/gl_context.h" -#include "gfx/gl/gl_context_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(void* shared_handle); - - virtual void Destroy(); - virtual bool MakeCurrent(); - virtual bool IsCurrent(); - virtual bool IsOffscreen(); - virtual void SwapBuffers(); - virtual gfx::Size GetSize(); - virtual void* GetHandle(); - - private: - GLContextHandle context_; - PbufferHandle pbuffer_; - - DISALLOW_COPY_AND_ASSIGN(PbufferGLContext); -}; - -static bool InitializeOneOff() { - static bool initialized = false; - if (initialized) - return true; - - osmewInit(); - initialized = true; - return true; -} - -bool PbufferGLContext::Initialize(void* shared_handle) { - // 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) { - DLOG(ERROR) << "Error choosing pixel format."; - Destroy(); - return false; - } - if (!pixel_format) { - return false; - } - CGLError res = CGLCreateContext(pixel_format, - static_cast<GLContextHandle>(shared_handle), - &context_); - CGLDestroyPixelFormat(pixel_format); - if (res != kCGLNoError) { - DLOG(ERROR) << "Error creating context."; - Destroy(); - return false; - } - if (CGLCreatePBuffer(1, 1, - GL_TEXTURE_2D, GL_RGBA, - 0, &pbuffer_) != kCGLNoError) { - DLOG(ERROR) << "Error creating pbuffer."; - Destroy(); - return false; - } - if (CGLSetPBuffer(context_, pbuffer_, 0, 0, 0) != kCGLNoError) { - DLOG(ERROR) << "Error attaching pbuffer to context."; - Destroy(); - return false; - } - - if (!MakeCurrent()) { - Destroy(); - DLOG(ERROR) << "Couldn't make context current for initialization."; - return false; - } - - if (!InitializeGLEW()) { - Destroy(); - return false; - } - - if (!InitializeCommon()) { - 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) { - DLOG(ERROR) << "Unable to make gl context current."; - return false; - } - } - - return true; -} - -bool PbufferGLContext::IsCurrent() { - return CGLGetCurrentContext() == context_; -} - -bool PbufferGLContext::IsOffscreen() { - return true; -} - -void PbufferGLContext::SwapBuffers() { - NOTREACHED() << "Cannot call SwapBuffers on a PbufferGLContext."; -} - -gfx::Size PbufferGLContext::GetSize() { - NOTREACHED() << "Should not be requesting size of a PbufferGLContext."; - return gfx::Size(1, 1); -} - -void* PbufferGLContext::GetHandle() { - return context_; -} - -GLContext* GLContext::CreateOffscreenGLContext(void* shared_handle) { - if (!InitializeOneOff()) - return NULL; - - if (OSMesaCreateContext) { - scoped_ptr<OSMesaGLContext> context(new OSMesaGLContext); - - if (!context->Initialize(shared_handle)) - return NULL; - - return context.release(); - } else { - scoped_ptr<PbufferGLContext> context(new PbufferGLContext); - if (!context->Initialize(shared_handle)) - return NULL; - - return context.release(); - } -} - -} // namespace gfx diff --git a/gfx/gl/gl_context_osmesa.cc b/gfx/gl/gl_context_osmesa.cc deleted file mode 100644 index 80b1cc9..0000000 --- a/gfx/gl/gl_context_osmesa.cc +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (c) 2009 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 <GL/glew.h> -#include <GL/osmew.h> - -#include <algorithm> - -#include "gfx/gl/gl_context_osmesa.h" - -namespace gfx { - -OSMesaGLContext::OSMesaGLContext() -#if !defined(UNIT_TEST) - : context_(NULL) -#endif -{ -} - -OSMesaGLContext::~OSMesaGLContext() { -} - -bool OSMesaGLContext::Initialize(void* shared_handle) { -#if !defined(UNIT_TEST) - DCHECK(!context_); - - size_ = gfx::Size(1, 1); - buffer_.reset(new int32[1]); - - context_ = OSMesaCreateContext(GL_RGBA, - static_cast<OSMesaContext>(shared_handle)); - return context_ != NULL; -#else - return true; -#endif -} - -void OSMesaGLContext::Destroy() { -#if !defined(UNIT_TEST) - if (context_) { - OSMesaDestroyContext(static_cast<OSMesaContext>(context_)); - context_ = NULL; - } -#endif -} - -bool OSMesaGLContext::MakeCurrent() { -#if !defined(UNIT_TEST) - DCHECK(context_); - return OSMesaMakeCurrent(static_cast<OSMesaContext>(context_), - buffer_.get(), - GL_UNSIGNED_BYTE, - size_.width(), size_.height()) == GL_TRUE; -#endif - return true; -} - -bool OSMesaGLContext::IsCurrent() { -#if !defined(UNIT_TEST) - DCHECK(context_); - return context_ == OSMesaGetCurrentContext(); -#endif - return true; -} - -bool OSMesaGLContext::IsOffscreen() { - return true; -} - -void OSMesaGLContext::SwapBuffers() { - NOTREACHED() << "Should not call SwapBuffers on an OSMesaGLContext."; -} - -gfx::Size OSMesaGLContext::GetSize() { - return size_; -} - -void* OSMesaGLContext::GetHandle() { - return context_; -} - -void OSMesaGLContext::Resize(const gfx::Size& new_size) { - if (new_size == size_) - return; - - // Allocate a new back buffer. - scoped_array<int32> new_buffer(new int32[new_size.GetArea()]); - memset(new_buffer.get(), 0, new_size.GetArea() * sizeof(new_buffer[0])); - - // Copy the current back buffer into the new buffer. - int copy_width = std::min(size_.width(), new_size.width()); - int copy_height = std::min(size_.height(), new_size.height()); - for (int y = 0; y < copy_height; ++y) { - for (int x = 0; x < copy_width; ++x) { - new_buffer[y * new_size.width() + x] = buffer_[y * size_.width() + x]; - } - } - - buffer_.reset(new_buffer.release()); - size_ = new_size; - - // If this context is current, need to call MakeCurrent again so OSMesa uses - // the new buffer. - if (IsCurrent()) - MakeCurrent(); -} - -} // namespace gfx diff --git a/gfx/gl/gl_context_osmesa.h b/gfx/gl/gl_context_osmesa.h deleted file mode 100644 index 1c60433..0000000 --- a/gfx/gl/gl_context_osmesa.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2010 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 GFX_GL_GL_CONTEXT_OSMESA_H_ -#define GFX_GL_GL_CONTEXT_OSMESA_H_ - -#include "base/scoped_ptr.h" -#include "gfx/size.h" -#include "gfx/gl/gl_context.h" - -typedef struct osmesa_context *OSMesaContext; - -namespace gfx { - -// Encapsulates an OSMesa OpenGL context that uses software rendering. -class OSMesaGLContext : public GLContext { - public: - OSMesaGLContext(); - virtual ~OSMesaGLContext(); - - // Initialize an OSMesa GL context with the default 1 x 1 initial size. - bool Initialize(void* shared_handle); - - // Implement GLContext. - virtual void Destroy(); - virtual bool MakeCurrent(); - virtual bool IsCurrent(); - virtual bool IsOffscreen(); - virtual void SwapBuffers(); - virtual gfx::Size GetSize(); - virtual void* GetHandle(); - - // Resize the back buffer, preserving the old content. Does nothing if the - // size is unchanged. - void Resize(const gfx::Size& new_size); - - const void* buffer() const { - return buffer_.get(); - } - - protected: - bool InitializeCommon(); - - private: -#if !defined(UNIT_TEST) - gfx::Size size_; - scoped_array<int32> buffer_; - OSMesaContext context_; -#endif - - DISALLOW_COPY_AND_ASSIGN(OSMesaGLContext); -}; - -} // namespace gfx - -#endif // GFX_GL_GL_CONTEXT_OSMESA_H_ diff --git a/gfx/gl/gl_context_win.cc b/gfx/gl/gl_context_win.cc deleted file mode 100644 index 2a1d6d0..0000000 --- a/gfx/gl/gl_context_win.cc +++ /dev/null @@ -1,625 +0,0 @@ -// Copyright (c) 2010 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. - -// This file implements the NativeViewGLContext and PbufferGLContext classes. - -#include <GL/glew.h> -#include <GL/osmew.h> -#include <GL/wglew.h> -#include <windows.h> - -#include <algorithm> - -#include "base/logging.h" -#include "base/scoped_ptr.h" -#include "gfx/gl/gl_context.h" -#include "gfx/gl/gl_context_osmesa.h" - -namespace gfx { - -typedef HGLRC GLContextHandle; -typedef HPBUFFERARB PbufferHandle; - -// This class is a wrapper around a GL context that renders directly to a -// window. -class NativeViewGLContext : public GLContext { - public: - explicit NativeViewGLContext(gfx::PluginWindowHandle window) - : window_(window), - device_context_(NULL), - context_(NULL) { - DCHECK(window); - } - - // Initializes the GL context. - bool Initialize(bool multisampled); - - virtual void Destroy(); - virtual bool MakeCurrent(); - virtual bool IsCurrent(); - virtual bool IsOffscreen(); - virtual void SwapBuffers(); - virtual gfx::Size GetSize(); - virtual void* GetHandle(); - - private: - gfx::PluginWindowHandle window_; - HDC device_context_; - GLContextHandle context_; - - DISALLOW_COPY_AND_ASSIGN(NativeViewGLContext); -}; - -// This class is a wrapper around a GL context that uses OSMesa to render -// to an offscreen buffer and then blits it to a window. -class OSMesaViewGLContext : public GLContext { - public: - explicit OSMesaViewGLContext(gfx::PluginWindowHandle window) - : window_(window), - device_context_(NULL) { - DCHECK(window); - } - - // Initializes the GL context. - bool Initialize(); - - virtual void Destroy(); - virtual bool MakeCurrent(); - virtual bool IsCurrent(); - virtual bool IsOffscreen(); - virtual void SwapBuffers(); - virtual gfx::Size GetSize(); - virtual void* GetHandle(); - - private: - void UpdateSize(); - - gfx::PluginWindowHandle window_; - HDC device_context_; - OSMesaGLContext osmesa_context_; - - DISALLOW_COPY_AND_ASSIGN(OSMesaViewGLContext); -}; - -// 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), - device_context_(NULL), - pbuffer_(NULL) { - } - - // Initializes the GL context. - bool Initialize(void* shared_handle); - - virtual void Destroy(); - virtual bool MakeCurrent(); - virtual bool IsCurrent(); - virtual bool IsOffscreen(); - virtual void SwapBuffers(); - virtual gfx::Size GetSize(); - virtual void* GetHandle(); - - private: - GLContextHandle context_; - HDC device_context_; - PbufferHandle pbuffer_; - - DISALLOW_COPY_AND_ASSIGN(PbufferGLContext); -}; - -static int g_regular_pixel_format = 0; -static int g_multisampled_pixel_format = 0; - -const PIXELFORMATDESCRIPTOR kPixelFormatDescriptor = { - sizeof(kPixelFormatDescriptor), // Size of structure. - 1, // Default version. - PFD_DRAW_TO_WINDOW | // Window drawing support. - PFD_SUPPORT_OPENGL | // OpenGL support. - PFD_DOUBLEBUFFER, // Double buffering support (not stereo). - PFD_TYPE_RGBA, // RGBA color mode (not indexed). - 24, // 24 bit color mode. - 0, 0, 0, 0, 0, 0, // Don't set RGB bits & shifts. - 8, 0, // 8 bit alpha - 0, // No accumulation buffer. - 0, 0, 0, 0, // Ignore accumulation bits. - 24, // 24 bit z-buffer size. - 8, // 8-bit stencil buffer. - 0, // No aux buffer. - PFD_MAIN_PLANE, // Main drawing plane (not overlay). - 0, // Reserved. - 0, 0, 0, // Layer masks ignored. -}; - -LRESULT CALLBACK IntermediateWindowProc(HWND window, - UINT message, - WPARAM w_param, - LPARAM l_param) { - return ::DefWindowProc(window, message, w_param, l_param); -} - -// Helper routine that does one-off initialization like determining the -// pixel format and initializing glew. -static bool InitializeOneOff() { - static bool initialized = false; - if (initialized) - return true; - - osmewInit(); - if (!OSMesaCreateContext) { - // We must initialize a GL context before we can determine the multi- - // sampling supported on the current hardware, so we create an intermediate - // window and context here. - HINSTANCE module_handle; - if (!::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | - GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, - reinterpret_cast<wchar_t*>(IntermediateWindowProc), - &module_handle)) { - return false; - } - - WNDCLASS intermediate_class; - intermediate_class.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; - intermediate_class.lpfnWndProc = IntermediateWindowProc; - intermediate_class.cbClsExtra = 0; - intermediate_class.cbWndExtra = 0; - intermediate_class.hInstance = module_handle; - intermediate_class.hIcon = LoadIcon(NULL, IDI_APPLICATION); - intermediate_class.hCursor = LoadCursor(NULL, IDC_ARROW); - intermediate_class.hbrBackground = NULL; - intermediate_class.lpszMenuName = NULL; - intermediate_class.lpszClassName = L"Intermediate GL Window"; - - ATOM class_registration = ::RegisterClass(&intermediate_class); - if (!class_registration) { - return false; - } - - HWND intermediate_window = ::CreateWindow( - reinterpret_cast<wchar_t*>(class_registration), - L"", - WS_OVERLAPPEDWINDOW, - 0, 0, - CW_USEDEFAULT, CW_USEDEFAULT, - NULL, - NULL, - NULL, - NULL); - - if (!intermediate_window) { - ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), - module_handle); - return false; - } - - HDC intermediate_dc = ::GetDC(intermediate_window); - g_regular_pixel_format = ::ChoosePixelFormat(intermediate_dc, - &kPixelFormatDescriptor); - if (g_regular_pixel_format == 0) { - DLOG(ERROR) << "Unable to get the pixel format for GL context."; - ::ReleaseDC(intermediate_window, intermediate_dc); - ::DestroyWindow(intermediate_window); - ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), - module_handle); - return false; - } - if (!::SetPixelFormat(intermediate_dc, g_regular_pixel_format, - &kPixelFormatDescriptor)) { - DLOG(ERROR) << "Unable to set the pixel format for GL context."; - ::ReleaseDC(intermediate_window, intermediate_dc); - ::DestroyWindow(intermediate_window); - ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), - module_handle); - return false; - } - - // Create a temporary GL context to query for multisampled pixel formats. - HGLRC gl_context = ::wglCreateContext(intermediate_dc); - if (::wglMakeCurrent(intermediate_dc, gl_context)) { - // GL context was successfully created and applied to the window's DC. - // Startup GLEW, the GL extensions wrangler. - if (InitializeGLEW()) { - DLOG(INFO) << "Initialized GLEW " << glewGetString(GLEW_VERSION); - } else { - ::wglMakeCurrent(intermediate_dc, NULL); - ::wglDeleteContext(gl_context); - ::ReleaseDC(intermediate_window, intermediate_dc); - ::DestroyWindow(intermediate_window); - ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), - module_handle); - return false; - } - - // If the multi-sample extensions are present, query the api to determine - // the pixel format. - if (WGLEW_ARB_pixel_format && WGLEW_ARB_multisample) { - int pixel_attributes[] = { - WGL_SAMPLES_ARB, 4, - WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, - WGL_SUPPORT_OPENGL_ARB, GL_TRUE, - WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, - WGL_COLOR_BITS_ARB, 24, - WGL_ALPHA_BITS_ARB, 8, - WGL_DEPTH_BITS_ARB, 24, - WGL_STENCIL_BITS_ARB, 8, - WGL_DOUBLE_BUFFER_ARB, GL_TRUE, - WGL_SAMPLE_BUFFERS_ARB, GL_TRUE, - 0, 0}; - - float pixel_attributes_f[] = {0, 0}; - unsigned int num_formats; - - // Query for the highest sampling rate supported, starting at 4x. - static const int kSampleCount[] = {4, 2}; - static const int kNumSamples = 2; - for (int sample = 0; sample < kNumSamples; ++sample) { - pixel_attributes[1] = kSampleCount[sample]; - if (GL_TRUE == ::wglChoosePixelFormatARB(intermediate_dc, - pixel_attributes, - pixel_attributes_f, - 1, - &g_multisampled_pixel_format, - &num_formats)) { - break; - } - } - } - } - - ::wglMakeCurrent(intermediate_dc, NULL); - ::wglDeleteContext(gl_context); - ::ReleaseDC(intermediate_window, intermediate_dc); - ::DestroyWindow(intermediate_window); - ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), - module_handle); - } - - initialized = true; - - return true; -} - -bool NativeViewGLContext::Initialize(bool multisampled) { - // The GL context will render to this window. - device_context_ = GetDC(window_); - - int pixel_format = - multisampled ? g_multisampled_pixel_format : g_regular_pixel_format; - if (!SetPixelFormat(device_context_, - pixel_format, - &kPixelFormatDescriptor)) { - DLOG(ERROR) << "Unable to set the pixel format for GL context."; - Destroy(); - return false; - } - - context_ = wglCreateContext(device_context_); - if (!context_) { - DLOG(ERROR) << "Failed to create GL context."; - Destroy(); - return false; - } - - if (!MakeCurrent()) { - Destroy(); - return false; - } - - if (!InitializeGLEW()) { - Destroy(); - return false; - } - - if (!InitializeCommon()) { - Destroy(); - return false; - } - - return true; -} - -void NativeViewGLContext::Destroy() { - if (context_) { - wglDeleteContext(context_); - context_ = NULL; - } - - if (window_ && device_context_) - ReleaseDC(window_, device_context_); - - window_ = NULL; - device_context_ = NULL; -} - -bool NativeViewGLContext::MakeCurrent() { - if (IsCurrent()) { - return true; - } - if (!wglMakeCurrent(device_context_, context_)) { - DLOG(ERROR) << "Unable to make gl context current."; - return false; - } - - return true; -} - -bool NativeViewGLContext::IsCurrent() { - return wglGetCurrentDC() == device_context_ && - wglGetCurrentContext() == context_; -} - -bool NativeViewGLContext::IsOffscreen() { - return false; -} - -void NativeViewGLContext::SwapBuffers() { - DCHECK(device_context_); - ::SwapBuffers(device_context_); -} - -gfx::Size NativeViewGLContext::GetSize() { - RECT rect; - CHECK(GetClientRect(window_, &rect)); - return gfx::Size(rect.right - rect.left, rect.bottom - rect.top); -} - -void* NativeViewGLContext::GetHandle() { - return context_; -} - -bool OSMesaViewGLContext::Initialize() { - // The GL context will render to this window. - device_context_ = GetDC(window_); - - if (!osmesa_context_.Initialize(NULL)) { - Destroy(); - return false; - } - - if (!MakeCurrent()) { - Destroy(); - return false; - } - - if (!InitializeGLEW()) { - Destroy(); - return false; - } - - if (!InitializeCommon()) { - Destroy(); - return false; - } - - UpdateSize(); - - return true; -} - -void OSMesaViewGLContext::Destroy() { - osmesa_context_.Destroy(); - - if (window_ && device_context_) - ReleaseDC(window_, device_context_); - - window_ = NULL; - device_context_ = NULL; -} - -bool OSMesaViewGLContext::MakeCurrent() { - return osmesa_context_.MakeCurrent(); -} - -bool OSMesaViewGLContext::IsCurrent() { - return osmesa_context_.IsCurrent(); -} - -bool OSMesaViewGLContext::IsOffscreen() { - return false; -} - -void OSMesaViewGLContext::SwapBuffers() { - DCHECK(device_context_); - - // Update the size before blitting so that the blit size is exactly the same - // as the window. - UpdateSize(); - - gfx::Size size = osmesa_context_.GetSize(); - - BITMAPV4HEADER info = { sizeof(BITMAPV4HEADER) }; - info.bV4Width = size.width(); - info.bV4Height = size.height(); - info.bV4Planes = 1; - info.bV4BitCount = 32; - info.bV4V4Compression = BI_BITFIELDS; - info.bV4RedMask = 0xFF000000; - info.bV4GreenMask = 0x00FF0000; - info.bV4BlueMask = 0x0000FF00; - info.bV4AlphaMask = 0x000000FF; - - // Copy the back buffer to the window's device context. - StretchDIBits(device_context_, - 0, 0, size.width(), size.height(), - 0, 0, size.width(), size.height(), - osmesa_context_.buffer(), - reinterpret_cast<BITMAPINFO*>(&info), - DIB_RGB_COLORS, - SRCCOPY); -} - -gfx::Size OSMesaViewGLContext::GetSize() { - return osmesa_context_.GetSize(); -} - -void* OSMesaViewGLContext::GetHandle() { - return osmesa_context_.GetHandle(); -} - -void OSMesaViewGLContext::UpdateSize() { - // Change back buffer size to that of window. - RECT rect; - GetWindowRect(window_, &rect); - gfx::Size window_size = gfx::Size( - std::max(1, static_cast<int>(rect.right - rect.left)), - std::max(1, static_cast<int>(rect.bottom - rect.top))); - osmesa_context_.Resize(window_size); -} - -GLContext* GLContext::CreateViewGLContext(gfx::PluginWindowHandle window, - bool multisampled) { - if (!InitializeOneOff()) - return NULL; - - if (OSMesaCreateContext) { - scoped_ptr<OSMesaViewGLContext> context(new OSMesaViewGLContext(window)); - - if (!context->Initialize()) - return NULL; - - return context.release(); - } else { - scoped_ptr<NativeViewGLContext> context(new NativeViewGLContext(window)); - - if (!context->Initialize(multisampled)) - return NULL; - - return context.release(); - } -} - -bool PbufferGLContext::Initialize(void* shared_handle) { - // Create a device context compatible with the primary display. - HDC display_device_context = ::CreateDC(L"DISPLAY", NULL, NULL, NULL); - - // Create a 1 x 1 pbuffer suitable for use with the device. This is just - // a stepping stone towards creating a frame buffer object. It doesn't - // matter what size it is. - const int kNoAttributes[] = { 0 }; - pbuffer_ = ::wglCreatePbufferARB(display_device_context, - g_regular_pixel_format, - 1, 1, - kNoAttributes); - ::DeleteDC(display_device_context); - if (!pbuffer_) { - DLOG(ERROR) << "Unable to create pbuffer."; - Destroy(); - return false; - } - - device_context_ = ::wglGetPbufferDCARB(pbuffer_); - if (!device_context_) { - DLOG(ERROR) << "Unable to get pbuffer device context."; - Destroy(); - return false; - } - - context_ = ::wglCreateContext(device_context_); - if (!context_) { - DLOG(ERROR) << "Failed to create GL context."; - Destroy(); - return false; - } - - if (shared_handle) { - if (!wglShareLists(static_cast<GLContextHandle>(shared_handle), context_)) { - DLOG(ERROR) << "Could not share GL contexts."; - Destroy(); - return false; - } - } - - if (!MakeCurrent()) { - Destroy(); - return false; - } - - if (!InitializeGLEW()) { - Destroy(); - return false; - } - - if (!InitializeCommon()) { - Destroy(); - return false; - } - - return true; -} - -void PbufferGLContext::Destroy() { - if (context_) { - wglDeleteContext(context_); - context_ = NULL; - } - - if (pbuffer_ && device_context_) - wglReleasePbufferDCARB(pbuffer_, device_context_); - - device_context_ = NULL; - - if (pbuffer_) { - wglDestroyPbufferARB(pbuffer_); - pbuffer_ = NULL; - } -} - -bool PbufferGLContext::MakeCurrent() { - if (IsCurrent()) { - return true; - } - if (!wglMakeCurrent(device_context_, context_)) { - DLOG(ERROR) << "Unable to make gl context current."; - return false; - } - - return true; -} - -bool PbufferGLContext::IsCurrent() { - return wglGetCurrentDC() == device_context_ && - wglGetCurrentContext() == context_; -} - -bool PbufferGLContext::IsOffscreen() { - return true; -} - -void PbufferGLContext::SwapBuffers() { - NOTREACHED() << "Attempted to call SwapBuffers on a pbuffer."; -} - -gfx::Size PbufferGLContext::GetSize() { - NOTREACHED() << "Should not be requesting size of this pbuffer."; - return gfx::Size(1, 1); -} - -void* PbufferGLContext::GetHandle() { - return context_; -} - -GLContext* GLContext::CreateOffscreenGLContext(void* shared_handle) { - if (!InitializeOneOff()) - return NULL; - - if (OSMesaCreateContext) { - scoped_ptr<OSMesaGLContext> context(new OSMesaGLContext); - - if (!context->Initialize(shared_handle)) - return NULL; - - return context.release(); - } else { - scoped_ptr<PbufferGLContext> context(new PbufferGLContext); - if (!context->Initialize(shared_handle)) - return NULL; - - return context.release(); - } -} - -} // namespace gfx |