| Index: ui/gl/gl_context_cgl.cc
|
| diff --git a/ui/gl/gl_context_cgl.cc b/ui/gl/gl_context_cgl.cc
|
| index cdd84ba50697a8731802e18bed67ae065a854560..beda8075ca5404da6988d3c691299c28208869a6 100644
|
| --- a/ui/gl/gl_context_cgl.cc
|
| +++ b/ui/gl/gl_context_cgl.cc
|
| @@ -17,47 +17,63 @@
|
|
|
| namespace gfx {
|
|
|
| -GLContextCGL::GLContextCGL(GLShareGroup* share_group)
|
| - : GLContext(share_group),
|
| - context_(NULL),
|
| - gpu_preference_(PreferIntegratedGpu),
|
| - discrete_pixelformat_(NULL) {
|
| -}
|
| -
|
| -bool GLContextCGL::Initialize(GLSurface* compatible_surface,
|
| - GpuPreference gpu_preference) {
|
| - DCHECK(compatible_surface);
|
| -
|
| - gpu_preference = ui::GpuSwitchingManager::GetInstance()->AdjustGpuPreference(
|
| - gpu_preference);
|
| -
|
| - GLContextCGL* share_context = share_group() ?
|
| - static_cast<GLContextCGL*>(share_group()->GetContext()) : NULL;
|
| +bool g_support_renderer_switching;
|
|
|
| +static CGLPixelFormatObj GetPixelFormat() {
|
| + static CGLPixelFormatObj format;
|
| + if (format)
|
| + return format;
|
| std::vector<CGLPixelFormatAttribute> attribs;
|
| // If the system supports dual gpus then allow offline renderers for every
|
| // context, so that they can all be in the same share group.
|
| - if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus())
|
| + if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus()) {
|
| attribs.push_back(kCGLPFAAllowOfflineRenderers);
|
| + g_support_renderer_switching = true;
|
| + }
|
| if (GetGLImplementation() == kGLImplementationAppleGL) {
|
| attribs.push_back(kCGLPFARendererID);
|
| attribs.push_back((CGLPixelFormatAttribute) kCGLRendererGenericFloatID);
|
| + g_support_renderer_switching = false;
|
| }
|
| attribs.push_back((CGLPixelFormatAttribute) 0);
|
|
|
| - CGLPixelFormatObj format;
|
| - GLint num_pixel_formats;
|
| + GLint num_virtual_screens;
|
| if (CGLChoosePixelFormat(&attribs.front(),
|
| &format,
|
| - &num_pixel_formats) != kCGLNoError) {
|
| + &num_virtual_screens) != kCGLNoError) {
|
| LOG(ERROR) << "Error choosing pixel format.";
|
| - return false;
|
| + return NULL;
|
| }
|
| if (!format) {
|
| LOG(ERROR) << "format == 0.";
|
| - return false;
|
| + return NULL;
|
| }
|
| - DCHECK_NE(num_pixel_formats, 0);
|
| + DCHECK_NE(num_virtual_screens, 0);
|
| + return format;
|
| +}
|
| +
|
| +GLContextCGL::GLContextCGL(GLShareGroup* share_group)
|
| + : GLContext(share_group),
|
| + context_(NULL),
|
| + gpu_preference_(PreferIntegratedGpu),
|
| + discrete_pixelformat_(NULL),
|
| + screen_(-1),
|
| + renderer_id_(-1) {
|
| +}
|
| +
|
| +bool GLContextCGL::Initialize(GLSurface* compatible_surface,
|
| + GpuPreference gpu_preference) {
|
| + DCHECK(compatible_surface);
|
| +
|
| + gpu_preference = ui::GpuSwitchingManager::GetInstance()->AdjustGpuPreference(
|
| + gpu_preference);
|
| +
|
| + GLContextCGL* share_context = share_group() ?
|
| + static_cast<GLContextCGL*>(share_group()->GetContext()) : NULL;
|
| +
|
| + CGLPixelFormatObj format = GetPixelFormat();
|
| + if (!format)
|
| + return false;
|
|
|
| // If using the discrete gpu, create a pixel format requiring it before we
|
| // create the context.
|
| @@ -79,7 +95,6 @@ bool GLContextCGL::Initialize(GLSurface* compatible_surface,
|
| share_context ?
|
| static_cast<CGLContextObj>(share_context->GetHandle()) : NULL,
|
| reinterpret_cast<CGLContextObj*>(&context_));
|
| - CGLReleasePixelFormat(format);
|
| if (res != kCGLNoError) {
|
| LOG(ERROR) << "Error creating context.";
|
| Destroy();
|
| @@ -103,6 +118,36 @@ void GLContextCGL::Destroy() {
|
|
|
| bool GLContextCGL::MakeCurrent(GLSurface* surface) {
|
| DCHECK(context_);
|
| + int renderer_id = share_group()->GetRendererID();
|
| + int screen;
|
| + CGLGetVirtualScreen(static_cast<CGLContextObj>(context_), &screen);
|
| +
|
| + if (g_support_renderer_switching &&
|
| + (screen != screen_ || renderer_id != renderer_id_)) {
|
| + CGLPixelFormatObj format = GetPixelFormat();
|
| + // Attempt to find a virtual screen that's using the requested renderer,
|
| + // and switch the context to use that screen.
|
| + int virtual_screen_count;
|
| + if (CGLDescribePixelFormat(format, 0, kCGLPFAVirtualScreenCount,
|
| + &virtual_screen_count) != kCGLNoError)
|
| + return false;
|
| +
|
| + for (int i = 0; i < virtual_screen_count; ++i) {
|
| + int screen_renderer_id;
|
| + if (CGLDescribePixelFormat(format, i, kCGLPFARendererID,
|
| + &screen_renderer_id) != kCGLNoError)
|
| + return false;
|
| +
|
| + screen_renderer_id &= kCGLRendererIDMatchingMask;
|
| + if (screen_renderer_id == renderer_id) {
|
| + CGLSetVirtualScreen(static_cast<CGLContextObj>(context_), i);
|
| + screen_ = i;
|
| + break;
|
| + }
|
| + }
|
| + renderer_id_ = renderer_id;
|
| + }
|
| +
|
| if (IsCurrent(surface))
|
| return true;
|
|
|
|
|