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

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

Issue 12383042: Switch all contexts in a share group to be on the same screen as the window they present to. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 9 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
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;
21
22 static CGLPixelFormatObj GetPixelFormat() {
23 static CGLPixelFormatObj format;
Ken Russell (switch to Gerrit) 2013/03/01 22:00:58 Does this need to be initialized to NULL?
jbauman 2013/03/02 03:52:23 No, static variables are always initialized to 0 (
24 if (format)
25 return format;
26 std::vector<CGLPixelFormatAttribute> attribs;
27 // 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.
29 if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus()) {
30 attribs.push_back(kCGLPFAAllowOfflineRenderers);
31 g_support_renderer_switching = true;
32 }
33 if (GetGLImplementation() == kGLImplementationAppleGL) {
34 attribs.push_back(kCGLPFARendererID);
35 attribs.push_back((CGLPixelFormatAttribute) kCGLRendererGenericFloatID);
36 g_support_renderer_switching = false;
37 }
38 attribs.push_back((CGLPixelFormatAttribute) 0);
39
40 GLint num_virtual_screens;
41 if (CGLChoosePixelFormat(&attribs.front(),
42 &format,
43 &num_virtual_screens) != kCGLNoError) {
44 LOG(ERROR) << "Error choosing pixel format.";
45 return NULL;
46 }
47 if (!format) {
48 LOG(ERROR) << "format == 0.";
49 return NULL;
50 }
51 DCHECK_NE(num_virtual_screens, 0);
52 return format;
53 }
54
20 GLContextCGL::GLContextCGL(GLShareGroup* share_group) 55 GLContextCGL::GLContextCGL(GLShareGroup* share_group)
21 : GLContext(share_group), 56 : GLContext(share_group),
22 context_(NULL), 57 context_(NULL),
23 gpu_preference_(PreferIntegratedGpu), 58 gpu_preference_(PreferIntegratedGpu),
24 discrete_pixelformat_(NULL) { 59 discrete_pixelformat_(NULL),
60 screen_(-1),
61 renderer_(-1) {
25 } 62 }
26 63
27 bool GLContextCGL::Initialize(GLSurface* compatible_surface, 64 bool GLContextCGL::Initialize(GLSurface* compatible_surface,
28 GpuPreference gpu_preference) { 65 GpuPreference gpu_preference) {
29 DCHECK(compatible_surface); 66 DCHECK(compatible_surface);
30 67
31 gpu_preference = ui::GpuSwitchingManager::GetInstance()->AdjustGpuPreference( 68 gpu_preference = ui::GpuSwitchingManager::GetInstance()->AdjustGpuPreference(
32 gpu_preference); 69 gpu_preference);
33 70
34 GLContextCGL* share_context = share_group() ? 71 GLContextCGL* share_context = share_group() ?
35 static_cast<GLContextCGL*>(share_group()->GetContext()) : NULL; 72 static_cast<GLContextCGL*>(share_group()->GetContext()) : NULL;
36 73
37 std::vector<CGLPixelFormatAttribute> attribs; 74 CGLPixelFormatObj format = GetPixelFormat();
38 // If the system supports dual gpus then allow offline renderers for every 75 if (!format)
39 // context, so that they can all be in the same share group.
40 if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus())
41 attribs.push_back(kCGLPFAAllowOfflineRenderers);
42 if (GetGLImplementation() == kGLImplementationAppleGL) {
43 attribs.push_back(kCGLPFARendererID);
44 attribs.push_back((CGLPixelFormatAttribute) kCGLRendererGenericFloatID);
45 }
46 attribs.push_back((CGLPixelFormatAttribute) 0);
47
48 CGLPixelFormatObj format;
49 GLint num_pixel_formats;
50 if (CGLChoosePixelFormat(&attribs.front(),
51 &format,
52 &num_pixel_formats) != kCGLNoError) {
53 LOG(ERROR) << "Error choosing pixel format.";
54 return false; 76 return false;
55 }
56 if (!format) {
57 LOG(ERROR) << "format == 0.";
58 return false;
59 }
60 DCHECK_NE(num_pixel_formats, 0);
61 77
62 // If using the discrete gpu, create a pixel format requiring it before we 78 // If using the discrete gpu, create a pixel format requiring it before we
63 // create the context. 79 // create the context.
64 if (!ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus() || 80 if (!ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus() ||
65 gpu_preference == PreferDiscreteGpu) { 81 gpu_preference == PreferDiscreteGpu) {
66 std::vector<CGLPixelFormatAttribute> discrete_attribs; 82 std::vector<CGLPixelFormatAttribute> discrete_attribs;
67 discrete_attribs.push_back((CGLPixelFormatAttribute) 0); 83 discrete_attribs.push_back((CGLPixelFormatAttribute) 0);
68 GLint num_pixel_formats; 84 GLint num_pixel_formats;
69 if (CGLChoosePixelFormat(&discrete_attribs.front(), 85 if (CGLChoosePixelFormat(&discrete_attribs.front(),
70 &discrete_pixelformat_, 86 &discrete_pixelformat_,
71 &num_pixel_formats) != kCGLNoError) { 87 &num_pixel_formats) != kCGLNoError) {
72 LOG(ERROR) << "Error choosing pixel format."; 88 LOG(ERROR) << "Error choosing pixel format.";
73 return false; 89 return false;
74 } 90 }
75 } 91 }
76 92
77 CGLError res = CGLCreateContext( 93 CGLError res = CGLCreateContext(
78 format, 94 format,
79 share_context ? 95 share_context ?
80 static_cast<CGLContextObj>(share_context->GetHandle()) : NULL, 96 static_cast<CGLContextObj>(share_context->GetHandle()) : NULL,
81 reinterpret_cast<CGLContextObj*>(&context_)); 97 reinterpret_cast<CGLContextObj*>(&context_));
82 CGLReleasePixelFormat(format);
83 if (res != kCGLNoError) { 98 if (res != kCGLNoError) {
84 LOG(ERROR) << "Error creating context."; 99 LOG(ERROR) << "Error creating context.";
85 Destroy(); 100 Destroy();
86 return false; 101 return false;
87 } 102 }
88 103
89 gpu_preference_ = gpu_preference; 104 gpu_preference_ = gpu_preference;
90 return true; 105 return true;
91 } 106 }
92 107
93 void GLContextCGL::Destroy() { 108 void GLContextCGL::Destroy() {
94 if (discrete_pixelformat_) { 109 if (discrete_pixelformat_) {
95 CGLReleasePixelFormat(discrete_pixelformat_); 110 CGLReleasePixelFormat(discrete_pixelformat_);
96 discrete_pixelformat_ = NULL; 111 discrete_pixelformat_ = NULL;
97 } 112 }
98 if (context_) { 113 if (context_) {
99 CGLDestroyContext(static_cast<CGLContextObj>(context_)); 114 CGLDestroyContext(static_cast<CGLContextObj>(context_));
100 context_ = NULL; 115 context_ = NULL;
101 } 116 }
102 } 117 }
103 118
104 bool GLContextCGL::MakeCurrent(GLSurface* surface) { 119 bool GLContextCGL::MakeCurrent(GLSurface* surface) {
105 DCHECK(context_); 120 DCHECK(context_);
121 int renderer = share_group()->GetRenderer();
122 int screen;
123 CGLGetVirtualScreen(static_cast<CGLContextObj>(context_), &screen);
124
125 if (g_support_renderer_switching &&
126 (screen != screen_ || renderer != renderer_)) {
127 CGLPixelFormatObj format = GetPixelFormat();
128 // Attempt to find a virtual screen that's using the requested renderer,
129 // and switch the context to use that screen.
130 int virtual_screen_count;
131 if (CGLDescribePixelFormat(format, 0, kCGLPFAVirtualScreenCount,
132 &virtual_screen_count) != kCGLNoError)
133 return false;
134
135 for (int i = 0; i < virtual_screen_count; ++i) {
136 int screen_renderer;
137 if (CGLDescribePixelFormat(format, i, kCGLPFARendererID,
138 &screen_renderer) != kCGLNoError)
139 return false;
140
141 screen_renderer &= kCGLRendererIDMatchingMask;
142 if (screen_renderer == renderer) {
143 CGLSetVirtualScreen(static_cast<CGLContextObj>(context_), i);
144 screen_ = i;
145 break;
146 }
147 }
148 renderer_ = renderer;
149 }
150
106 if (IsCurrent(surface)) 151 if (IsCurrent(surface))
107 return true; 152 return true;
108 153
109 TRACE_EVENT0("gpu", "GLContextCGL::MakeCurrent"); 154 TRACE_EVENT0("gpu", "GLContextCGL::MakeCurrent");
110 155
111 if (CGLSetCurrentContext( 156 if (CGLSetCurrentContext(
112 static_cast<CGLContextObj>(context_)) != kCGLNoError) { 157 static_cast<CGLContextObj>(context_)) != kCGLNoError) {
113 LOG(ERROR) << "Unable to make gl context current."; 158 LOG(ERROR) << "Unable to make gl context current.";
114 return false; 159 return false;
115 } 160 }
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 264
220 GpuPreference GLContextCGL::GetGpuPreference() { 265 GpuPreference GLContextCGL::GetGpuPreference() {
221 return gpu_preference_; 266 return gpu_preference_;
222 } 267 }
223 268
224 void ScopedCGLDestroyRendererInfo::operator()(CGLRendererInfoObj x) const { 269 void ScopedCGLDestroyRendererInfo::operator()(CGLRendererInfoObj x) const {
225 CGLDestroyRendererInfo(x); 270 CGLDestroyRendererInfo(x);
226 } 271 }
227 272
228 } // namespace gfx 273 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698