Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: ui/gl/gl_context_cgl.cc

Issue 13746002: Force GPU switch with CGLSetVirtualScreen only for compositor (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Only transition compositor contexts Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
11 #include "base/debug/trace_event.h" 11 #include "base/debug/trace_event.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "ui/gl/gl_bindings.h" 13 #include "ui/gl/gl_bindings.h"
14 #include "ui/gl/gl_implementation.h" 14 #include "ui/gl/gl_implementation.h"
15 #include "ui/gl/gl_surface_cgl.h" 15 #include "ui/gl/gl_surface_cgl.h"
16 #include "ui/gl/gpu_switching_manager.h" 16 #include "ui/gl/gpu_switching_manager.h"
17 17
18 namespace gfx { 18 namespace gfx {
19 19
20 bool g_support_renderer_switching; 20 bool g_support_renderer_switching;
21 21
22 bool g_safe_to_force_gpu_switch = false;
jbauman 2013/04/09 00:47:13 Not necessary anymore.
Ken Russell (switch to Gerrit) 2013/04/09 00:48:58 This is left over from a previous version of the p
ccameron 2013/04/09 17:28:55 Done.
23
22 static CGLPixelFormatObj GetPixelFormat() { 24 static CGLPixelFormatObj GetPixelFormat() {
23 static CGLPixelFormatObj format; 25 static CGLPixelFormatObj format;
24 if (format) 26 if (format)
25 return format; 27 return format;
26 std::vector<CGLPixelFormatAttribute> attribs; 28 std::vector<CGLPixelFormatAttribute> attribs;
27 // If the system supports dual gpus then allow offline renderers for every 29 // If the system supports dual gpus then allow offline renderers for every
28 // context, so that they can all be in the same share group. 30 // context, so that they can all be in the same share group.
29 if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus()) { 31 if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus()) {
30 attribs.push_back(kCGLPFAAllowOfflineRenderers); 32 attribs.push_back(kCGLPFAAllowOfflineRenderers);
31 g_support_renderer_switching = true; 33 g_support_renderer_switching = true;
(...skipping 19 matching lines...) Expand all
51 DCHECK_NE(num_virtual_screens, 0); 53 DCHECK_NE(num_virtual_screens, 0);
52 return format; 54 return format;
53 } 55 }
54 56
55 GLContextCGL::GLContextCGL(GLShareGroup* share_group) 57 GLContextCGL::GLContextCGL(GLShareGroup* share_group)
56 : GLContext(share_group), 58 : GLContext(share_group),
57 context_(NULL), 59 context_(NULL),
58 gpu_preference_(PreferIntegratedGpu), 60 gpu_preference_(PreferIntegratedGpu),
59 discrete_pixelformat_(NULL), 61 discrete_pixelformat_(NULL),
60 screen_(-1), 62 screen_(-1),
61 renderer_id_(-1) { 63 renderer_id_(-1),
64 safe_to_force_gpu_switch_(false) {
62 } 65 }
63 66
64 bool GLContextCGL::Initialize(GLSurface* compatible_surface, 67 bool GLContextCGL::Initialize(GLSurface* compatible_surface,
65 GpuPreference gpu_preference) { 68 GpuPreference gpu_preference) {
66 DCHECK(compatible_surface); 69 DCHECK(compatible_surface);
67 70
68 gpu_preference = ui::GpuSwitchingManager::GetInstance()->AdjustGpuPreference( 71 gpu_preference = ui::GpuSwitchingManager::GetInstance()->AdjustGpuPreference(
69 gpu_preference); 72 gpu_preference);
70 73
71 GLContextCGL* share_context = share_group() ? 74 GLContextCGL* share_context = share_group() ?
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 discrete_pixelformat_ = NULL; 121 discrete_pixelformat_ = NULL;
119 } 122 }
120 if (context_) { 123 if (context_) {
121 CGLDestroyContext(static_cast<CGLContextObj>(context_)); 124 CGLDestroyContext(static_cast<CGLContextObj>(context_));
122 context_ = NULL; 125 context_ = NULL;
123 } 126 }
124 } 127 }
125 128
126 bool GLContextCGL::MakeCurrent(GLSurface* surface) { 129 bool GLContextCGL::MakeCurrent(GLSurface* surface) {
127 DCHECK(context_); 130 DCHECK(context_);
128 int renderer_id = share_group()->GetRendererID();
129 int screen;
130 CGLGetVirtualScreen(static_cast<CGLContextObj>(context_), &screen);
131 131
132 if (g_support_renderer_switching && 132 // The call to CGLSetVirtualScreen can hang on some AMD drivers
133 !discrete_pixelformat_ && renderer_id != -1 && 133 // http://crbug.com/227228
134 (screen != screen_ || renderer_id != renderer_id_)) { 134 if (safe_to_force_gpu_switch_) {
135 // Attempt to find a virtual screen that's using the requested renderer, 135 int renderer_id = share_group()->GetRendererID();
136 // and switch the context to use that screen. Don't attempt to switch if 136 int screen;
137 // the context requires the discrete GPU. 137 CGLGetVirtualScreen(static_cast<CGLContextObj>(context_), &screen);
138 CGLPixelFormatObj format = GetPixelFormat();
139 int virtual_screen_count;
140 if (CGLDescribePixelFormat(format, 0, kCGLPFAVirtualScreenCount,
141 &virtual_screen_count) != kCGLNoError)
142 return false;
143 138
144 for (int i = 0; i < virtual_screen_count; ++i) { 139 if (g_support_renderer_switching &&
145 int screen_renderer_id; 140 !discrete_pixelformat_ && renderer_id != -1 &&
146 if (CGLDescribePixelFormat(format, i, kCGLPFARendererID, 141 (screen != screen_ || renderer_id != renderer_id_)) {
147 &screen_renderer_id) != kCGLNoError) 142 // Attempt to find a virtual screen that's using the requested renderer,
143 // and switch the context to use that screen. Don't attempt to switch if
144 // the context requires the discrete GPU.
145 CGLPixelFormatObj format = GetPixelFormat();
146 int virtual_screen_count;
147 if (CGLDescribePixelFormat(format, 0, kCGLPFAVirtualScreenCount,
148 &virtual_screen_count) != kCGLNoError)
148 return false; 149 return false;
149 150
150 screen_renderer_id &= kCGLRendererIDMatchingMask; 151 for (int i = 0; i < virtual_screen_count; ++i) {
151 if (screen_renderer_id == renderer_id) { 152 int screen_renderer_id;
152 CGLSetVirtualScreen(static_cast<CGLContextObj>(context_), i); 153 if (CGLDescribePixelFormat(format, i, kCGLPFARendererID,
153 screen_ = i; 154 &screen_renderer_id) != kCGLNoError)
154 break; 155 return false;
156
157 screen_renderer_id &= kCGLRendererIDMatchingMask;
158 if (screen_renderer_id == renderer_id) {
159 CGLSetVirtualScreen(static_cast<CGLContextObj>(context_), i);
160 screen_ = i;
161 break;
162 }
155 } 163 }
164 renderer_id_ = renderer_id;
156 } 165 }
157 renderer_id_ = renderer_id;
158 } 166 }
159 167
160 if (IsCurrent(surface)) 168 if (IsCurrent(surface))
161 return true; 169 return true;
162 170
163 TRACE_EVENT0("gpu", "GLContextCGL::MakeCurrent"); 171 TRACE_EVENT0("gpu", "GLContextCGL::MakeCurrent");
164 172
165 if (CGLSetCurrentContext( 173 if (CGLSetCurrentContext(
166 static_cast<CGLContextObj>(context_)) != kCGLNoError) { 174 static_cast<CGLContextObj>(context_)) != kCGLNoError) {
167 LOG(ERROR) << "Unable to make gl context current."; 175 LOG(ERROR) << "Unable to make gl context current.";
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 kCGLRPVideoMemory, 268 kCGLRPVideoMemory,
261 &video_memory) != kCGLNoError) 269 &video_memory) != kCGLNoError)
262 continue; 270 continue;
263 *bytes = video_memory; 271 *bytes = video_memory;
264 return true; 272 return true;
265 } 273 }
266 274
267 return false; 275 return false;
268 } 276 }
269 277
278 void GLContextCGL::SetSafeToForceGpuSwitch() {
279 safe_to_force_gpu_switch_ = true;
280 }
281
282
270 GLContextCGL::~GLContextCGL() { 283 GLContextCGL::~GLContextCGL() {
271 Destroy(); 284 Destroy();
272 } 285 }
273 286
274 GpuPreference GLContextCGL::GetGpuPreference() { 287 GpuPreference GLContextCGL::GetGpuPreference() {
275 return gpu_preference_; 288 return gpu_preference_;
276 } 289 }
277 290
278 void ScopedCGLDestroyRendererInfo::operator()(CGLRendererInfoObj x) const { 291 void ScopedCGLDestroyRendererInfo::operator()(CGLRendererInfoObj x) const {
279 CGLDestroyRendererInfo(x); 292 CGLDestroyRendererInfo(x);
280 } 293 }
281 294
282 } // namespace gfx 295 } // namespace gfx
OLDNEW
« gpu/command_buffer/service/gles2_cmd_decoder.cc ('K') | « ui/gl/gl_context_cgl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698