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

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: Incorporate reiew feedback 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_force_cgl_set_virtual_screen = false;
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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 discrete_pixelformat_ = NULL; 120 discrete_pixelformat_ = NULL;
119 } 121 }
120 if (context_) { 122 if (context_) {
121 CGLDestroyContext(static_cast<CGLContextObj>(context_)); 123 CGLDestroyContext(static_cast<CGLContextObj>(context_));
122 context_ = NULL; 124 context_ = NULL;
123 } 125 }
124 } 126 }
125 127
126 bool GLContextCGL::MakeCurrent(GLSurface* surface) { 128 bool GLContextCGL::MakeCurrent(GLSurface* surface) {
127 DCHECK(context_); 129 DCHECK(context_);
128 int renderer_id = share_group()->GetRendererID();
129 int screen;
130 CGLGetVirtualScreen(static_cast<CGLContextObj>(context_), &screen);
131 130
132 if (g_support_renderer_switching && 131 // The call to CGLSetVirtualScreen can hang on some AMD drivers
133 !discrete_pixelformat_ && renderer_id != -1 && 132 // http://crbug.com/227228
134 (screen != screen_ || renderer_id != renderer_id_)) { 133 if (g_force_cgl_set_virtual_screen) {
135 // Attempt to find a virtual screen that's using the requested renderer, 134 int renderer_id = share_group()->GetRendererID();
136 // and switch the context to use that screen. Don't attempt to switch if 135 int screen;
137 // the context requires the discrete GPU. 136 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 137
144 for (int i = 0; i < virtual_screen_count; ++i) { 138 if (g_support_renderer_switching &&
145 int screen_renderer_id; 139 !discrete_pixelformat_ && renderer_id != -1 &&
146 if (CGLDescribePixelFormat(format, i, kCGLPFARendererID, 140 (screen != screen_ || renderer_id != renderer_id_)) {
147 &screen_renderer_id) != kCGLNoError) 141 // Attempt to find a virtual screen that's using the requested renderer,
142 // and switch the context to use that screen. Don't attempt to switch if
143 // the context requires the discrete GPU.
144 CGLPixelFormatObj format = GetPixelFormat();
145 int virtual_screen_count;
146 if (CGLDescribePixelFormat(format, 0, kCGLPFAVirtualScreenCount,
147 &virtual_screen_count) != kCGLNoError)
148 return false; 148 return false;
149 149
150 screen_renderer_id &= kCGLRendererIDMatchingMask; 150 for (int i = 0; i < virtual_screen_count; ++i) {
151 if (screen_renderer_id == renderer_id) { 151 int screen_renderer_id;
152 CGLSetVirtualScreen(static_cast<CGLContextObj>(context_), i); 152 if (CGLDescribePixelFormat(format, i, kCGLPFARendererID,
153 screen_ = i; 153 &screen_renderer_id) != kCGLNoError)
154 break; 154 return false;
155
156 screen_renderer_id &= kCGLRendererIDMatchingMask;
157 if (screen_renderer_id == renderer_id) {
158 CGLSetVirtualScreen(static_cast<CGLContextObj>(context_), i);
159 screen_ = i;
160 break;
161 }
155 } 162 }
163 renderer_id_ = renderer_id;
156 } 164 }
157 renderer_id_ = renderer_id;
158 } 165 }
159 166
160 if (IsCurrent(surface)) 167 if (IsCurrent(surface))
161 return true; 168 return true;
162 169
163 TRACE_EVENT0("gpu", "GLContextCGL::MakeCurrent"); 170 TRACE_EVENT0("gpu", "GLContextCGL::MakeCurrent");
164 171
165 if (CGLSetCurrentContext( 172 if (CGLSetCurrentContext(
166 static_cast<CGLContextObj>(context_)) != kCGLNoError) { 173 static_cast<CGLContextObj>(context_)) != kCGLNoError) {
167 LOG(ERROR) << "Unable to make gl context current."; 174 LOG(ERROR) << "Unable to make gl context current.";
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 kCGLRPVideoMemory, 267 kCGLRPVideoMemory,
261 &video_memory) != kCGLNoError) 268 &video_memory) != kCGLNoError)
262 continue; 269 continue;
263 *bytes = video_memory; 270 *bytes = video_memory;
264 return true; 271 return true;
265 } 272 }
266 273
267 return false; 274 return false;
268 } 275 }
269 276
277 // static
278 void GLContextCGL::ForceCGLSetVirtualScreen() {
279 g_force_cgl_set_virtual_screen = true;
280 }
281
270 GLContextCGL::~GLContextCGL() { 282 GLContextCGL::~GLContextCGL() {
271 Destroy(); 283 Destroy();
272 } 284 }
273 285
274 GpuPreference GLContextCGL::GetGpuPreference() { 286 GpuPreference GLContextCGL::GetGpuPreference() {
275 return gpu_preference_; 287 return gpu_preference_;
276 } 288 }
277 289
278 void ScopedCGLDestroyRendererInfo::operator()(CGLRendererInfoObj x) const { 290 void ScopedCGLDestroyRendererInfo::operator()(CGLRendererInfoObj x) const {
279 CGLDestroyRendererInfo(x); 291 CGLDestroyRendererInfo(x);
280 } 292 }
281 293
282 } // namespace gfx 294 } // namespace gfx
OLDNEW
« gpu/command_buffer/service/gpu_driver_bug_workaround_type.h ('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