| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/gl/gl_context_cgl.h" | 5 #include "ui/gl/gl_context_cgl.h" |
| 6 | 6 |
| 7 #include <OpenGL/CGLRenderers.h> | 7 #include <OpenGL/CGLRenderers.h> |
| 8 #include <OpenGL/CGLTypes.h> | 8 #include <OpenGL/CGLTypes.h> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 | 24 |
| 25 struct CGLRendererInfoObjDeleter { | 25 struct CGLRendererInfoObjDeleter { |
| 26 void operator()(CGLRendererInfoObj* x) { | 26 void operator()(CGLRendererInfoObj* x) { |
| 27 if (x) | 27 if (x) |
| 28 CGLDestroyRendererInfo(*x); | 28 CGLDestroyRendererInfo(*x); |
| 29 } | 29 } |
| 30 }; | 30 }; |
| 31 | 31 |
| 32 } // namespace | 32 } // namespace |
| 33 | 33 |
| 34 static CGLPixelFormatObj GetPixelFormat() { | 34 static CGLPixelFormatObj GetPixelFormat(bool prevent_switchable) { |
| 35 static CGLPixelFormatObj format; | 35 static CGLPixelFormatObj format; |
| 36 if (format) | 36 if (format) |
| 37 return format; | 37 return format; |
| 38 std::vector<CGLPixelFormatAttribute> attribs; | 38 std::vector<CGLPixelFormatAttribute> attribs; |
| 39 // If the system supports dual gpus then allow offline renderers for every | 39 // If the system supports dual gpus then allow offline renderers for every |
| 40 // context, so that they can all be in the same share group. | 40 // context, so that they can all be in the same share group. Don't do this for |
| 41 if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus()) { | 41 // discrete GPUs to avoid being offloaded to an idle GPU by OSX. |
| 42 if (!prevent_switchable) { |
| 42 attribs.push_back(kCGLPFAAllowOfflineRenderers); | 43 attribs.push_back(kCGLPFAAllowOfflineRenderers); |
| 43 g_support_renderer_switching = true; | 44 g_support_renderer_switching = true; |
| 44 } | 45 } |
| 45 if (GetGLImplementation() == kGLImplementationAppleGL) { | 46 if (GetGLImplementation() == kGLImplementationAppleGL) { |
| 46 attribs.push_back(kCGLPFARendererID); | 47 attribs.push_back(kCGLPFARendererID); |
| 47 attribs.push_back((CGLPixelFormatAttribute) kCGLRendererGenericFloatID); | 48 attribs.push_back((CGLPixelFormatAttribute) kCGLRendererGenericFloatID); |
| 48 g_support_renderer_switching = false; | 49 g_support_renderer_switching = false; |
| 49 } | 50 } |
| 50 if (GetGLImplementation() == kGLImplementationDesktopGLCoreProfile) { | 51 if (GetGLImplementation() == kGLImplementationDesktopGLCoreProfile) { |
| 51 // These constants don't exist in the 10.6 SDK against which | 52 // These constants don't exist in the 10.6 SDK against which |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 bool GLContextCGL::Initialize(GLSurface* compatible_surface, | 87 bool GLContextCGL::Initialize(GLSurface* compatible_surface, |
| 87 GpuPreference gpu_preference) { | 88 GpuPreference gpu_preference) { |
| 88 DCHECK(compatible_surface); | 89 DCHECK(compatible_surface); |
| 89 | 90 |
| 90 gpu_preference = ui::GpuSwitchingManager::GetInstance()->AdjustGpuPreference( | 91 gpu_preference = ui::GpuSwitchingManager::GetInstance()->AdjustGpuPreference( |
| 91 gpu_preference); | 92 gpu_preference); |
| 92 | 93 |
| 93 GLContextCGL* share_context = share_group() ? | 94 GLContextCGL* share_context = share_group() ? |
| 94 static_cast<GLContextCGL*>(share_group()->GetContext()) : NULL; | 95 static_cast<GLContextCGL*>(share_group()->GetContext()) : NULL; |
| 95 | 96 |
| 96 CGLPixelFormatObj format = GetPixelFormat(); | 97 const bool prevent_switchable = gpu_preference == PreferDiscreteGpu || |
| 98 !ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus(); |
| 99 |
| 100 CGLPixelFormatObj format = GetPixelFormat(prevent_switchable); |
| 97 if (!format) | 101 if (!format) |
| 98 return false; | 102 return false; |
| 99 | 103 |
| 100 // If using the discrete gpu, create a pixel format requiring it before we | 104 // If using the discrete gpu, create a pixel format requiring it before we |
| 101 // create the context. | 105 // create the context. |
| 102 if (!ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus() || | 106 if (prevent_switchable) { |
| 103 gpu_preference == PreferDiscreteGpu) { | |
| 104 std::vector<CGLPixelFormatAttribute> discrete_attribs; | 107 std::vector<CGLPixelFormatAttribute> discrete_attribs; |
| 105 discrete_attribs.push_back((CGLPixelFormatAttribute) 0); | 108 discrete_attribs.push_back((CGLPixelFormatAttribute) 0); |
| 106 GLint num_pixel_formats; | 109 GLint num_pixel_formats; |
| 107 if (CGLChoosePixelFormat(&discrete_attribs.front(), | 110 if (CGLChoosePixelFormat(&discrete_attribs.front(), |
| 108 &discrete_pixelformat_, | 111 &discrete_pixelformat_, |
| 109 &num_pixel_formats) != kCGLNoError) { | 112 &num_pixel_formats) != kCGLNoError) { |
| 110 LOG(ERROR) << "Error choosing pixel format."; | 113 LOG(ERROR) << "Error choosing pixel format."; |
| 111 return false; | 114 return false; |
| 112 } | 115 } |
| 113 // The renderer might be switched after this, so ignore the saved ID. | 116 // The renderer might be switched after this, so ignore the saved ID. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 int renderer_id = share_group()->GetRendererID(); | 160 int renderer_id = share_group()->GetRendererID(); |
| 158 int screen; | 161 int screen; |
| 159 CGLGetVirtualScreen(static_cast<CGLContextObj>(context_), &screen); | 162 CGLGetVirtualScreen(static_cast<CGLContextObj>(context_), &screen); |
| 160 | 163 |
| 161 if (g_support_renderer_switching && | 164 if (g_support_renderer_switching && |
| 162 !discrete_pixelformat_ && renderer_id != -1 && | 165 !discrete_pixelformat_ && renderer_id != -1 && |
| 163 (screen != screen_ || renderer_id != renderer_id_)) { | 166 (screen != screen_ || renderer_id != renderer_id_)) { |
| 164 // Attempt to find a virtual screen that's using the requested renderer, | 167 // Attempt to find a virtual screen that's using the requested renderer, |
| 165 // and switch the context to use that screen. Don't attempt to switch if | 168 // and switch the context to use that screen. Don't attempt to switch if |
| 166 // the context requires the discrete GPU. | 169 // the context requires the discrete GPU. |
| 167 CGLPixelFormatObj format = GetPixelFormat(); | 170 CGLPixelFormatObj format = GetPixelFormat(false); |
| 168 int virtual_screen_count; | 171 int virtual_screen_count; |
| 169 if (CGLDescribePixelFormat(format, 0, kCGLPFAVirtualScreenCount, | 172 if (CGLDescribePixelFormat(format, 0, kCGLPFAVirtualScreenCount, |
| 170 &virtual_screen_count) != kCGLNoError) | 173 &virtual_screen_count) != kCGLNoError) |
| 171 return false; | 174 return false; |
| 172 | 175 |
| 173 for (int i = 0; i < virtual_screen_count; ++i) { | 176 for (int i = 0; i < virtual_screen_count; ++i) { |
| 174 int screen_renderer_id; | 177 int screen_renderer_id; |
| 175 if (CGLDescribePixelFormat(format, i, kCGLPFARendererID, | 178 if (CGLDescribePixelFormat(format, i, kCGLPFARendererID, |
| 176 &screen_renderer_id) != kCGLNoError) | 179 &screen_renderer_id) != kCGLNoError) |
| 177 return false; | 180 return false; |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 | 317 |
| 315 GLContextCGL::~GLContextCGL() { | 318 GLContextCGL::~GLContextCGL() { |
| 316 Destroy(); | 319 Destroy(); |
| 317 } | 320 } |
| 318 | 321 |
| 319 GpuPreference GLContextCGL::GetGpuPreference() { | 322 GpuPreference GLContextCGL::GetGpuPreference() { |
| 320 return gpu_preference_; | 323 return gpu_preference_; |
| 321 } | 324 } |
| 322 | 325 |
| 323 } // namespace gfx | 326 } // namespace gfx |
| OLD | NEW |