diff options
Diffstat (limited to 'ui/gfx/gl/gl_context_mac.cc')
-rw-r--r-- | ui/gfx/gl/gl_context_mac.cc | 102 |
1 files changed, 99 insertions, 3 deletions
diff --git a/ui/gfx/gl/gl_context_mac.cc b/ui/gfx/gl/gl_context_mac.cc index cdfc6f4..0c870e2 100644 --- a/ui/gfx/gl/gl_context_mac.cc +++ b/ui/gfx/gl/gl_context_mac.cc @@ -4,6 +4,8 @@ #include "base/basictypes.h" #include "base/logging.h" +#include "base/mac/mac_util.h" +#include "base/memory/scoped_generic_obj.h" #include "base/memory/scoped_ptr.h" #include "third_party/mesa/MesaLib/include/GL/osmesa.h" #include "ui/gfx/gl/gl_bindings.h" @@ -14,24 +16,37 @@ #include "ui/gfx/gl/gl_surface_cgl.h" #include "ui/gfx/gl/gl_surface_osmesa.h" +namespace { + +// ScopedGenericObj functor for CGLDestroyRendererInfo(). +class ScopedDestroyRendererInfo { + public: + void operator()(CGLRendererInfoObj x) const { + CGLDestroyRendererInfo(x); + } +}; + +} // namespace + namespace gfx { class GLShareGroup; scoped_refptr<GLContext> GLContext::CreateGLContext( GLShareGroup* share_group, - GLSurface* compatible_surface) { + GLSurface* compatible_surface, + GpuPreference gpu_preference) { switch (GetGLImplementation()) { case kGLImplementationDesktopGL: { scoped_refptr<GLContext> context(new GLContextCGL(share_group)); - if (!context->Initialize(compatible_surface)) + if (!context->Initialize(compatible_surface, gpu_preference)) return NULL; return context; } case kGLImplementationOSMesaGL: { scoped_refptr<GLContext> context(new GLContextOSMesa(share_group)); - if (!context->Initialize(compatible_surface)) + if (!context->Initialize(compatible_surface, gpu_preference)) return NULL; return context; @@ -44,4 +59,85 @@ scoped_refptr<GLContext> GLContext::CreateGLContext( } } +bool GLContext::SupportsDualGpus() { + // We need to know the GL implementation in order to correctly + // answer whether dual GPUs are supported. This introduces an + // initialization cycle with GLSurface::InitializeOneOff() which we + // need to break. + static bool initialized = false; + static bool initializing = false; + static bool supports_dual_gpus = false; + + if (initialized) { + return supports_dual_gpus; + } else { + if (!initializing) { + initializing = true; + if (!GLSurface::InitializeOneOff()) { + return false; + } + } + initialized = true; + } + + if (!base::mac::IsOSLionOrLater()) { + return false; + } + + if (GetGLImplementation() != kGLImplementationDesktopGL) { + return false; + } + + // Enumerate all hardware-accelerated renderers. If we find one + // online and one offline, assume we're on a dual-GPU system. + GLuint display_mask = static_cast<GLuint>(-1); + CGLRendererInfoObj renderer_info = NULL; + GLint num_renderers = 0; + + bool found_online = false; + bool found_offline = false; + + if (CGLQueryRendererInfo(display_mask, + &renderer_info, + &num_renderers) != kCGLNoError) { + return false; + } + + ScopedGenericObj<CGLRendererInfoObj, ScopedDestroyRendererInfo> + scoper(renderer_info); + + for (GLint i = 0; i < num_renderers; ++i) { + GLint accelerated = 0; + if (CGLDescribeRenderer(renderer_info, + i, + kCGLRPAccelerated, + &accelerated) != kCGLNoError) { + return false; + } + + if (!accelerated) + continue; + + GLint online = 0; + if (CGLDescribeRenderer(renderer_info, + i, + kCGLRPOnline, + &online) != kCGLNoError) { + return false; + } + + if (online) { + found_online = true; + } else { + found_offline = true; + } + } + + if (found_online && found_offline) { + supports_dual_gpus = true; + } + + return supports_dual_gpus; +} + } // namespace gfx |