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

Side by Side Diff: content/browser/renderer_host/compositing_iosurface_context_mac.mm

Issue 147493011: Use base::ScopedTypeRef for CGL types (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase again Created 6 years, 10 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) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 "content/browser/renderer_host/compositing_iosurface_context_mac.h" 5 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h"
6 6
7 #include <OpenGL/gl.h> 7 #include <OpenGL/gl.h>
8 #include <OpenGL/OpenGL.h> 8 #include <OpenGL/OpenGL.h>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/debug/trace_event.h" 12 #include "base/debug/trace_event.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "content/browser/renderer_host/compositing_iosurface_shader_programs_ma c.h" 14 #include "content/browser/renderer_host/compositing_iosurface_shader_programs_ma c.h"
15 #include "content/public/common/content_switches.h" 15 #include "content/public/common/content_switches.h"
16 #include "ui/gl/gl_switches.h" 16 #include "ui/gl/gl_switches.h"
17 #include "ui/gl/gpu_switching_manager.h" 17 #include "ui/gl/gpu_switching_manager.h"
18 18
19 namespace {
20
21 template<typename T, void Release(T)>
22 class ScopedCGLTypeRef {
23 public:
24 ScopedCGLTypeRef() : object_(NULL) {}
25
26 ~ScopedCGLTypeRef() {
27 if (object_)
28 Release(object_);
29 object_ = NULL;
30 }
31
32 // Only to be used for pass-by-pointer initialization. The object must have
33 // been reset to NULL prior to calling.
34 T* operator&() {
35 DCHECK(object_ == NULL);
36 return &object_;
37 }
38
39 operator T() const {
40 return object_;
41 }
42
43 T release() WARN_UNUSED_RESULT {
44 T object = object_;
45 object_ = NULL;
46 return object;
47 }
48
49 private:
50 T object_;
51 DISALLOW_COPY_AND_ASSIGN(ScopedCGLTypeRef);
52 };
53
54 }
55
56 namespace content { 19 namespace content {
57 20
58 CoreAnimationStatus GetCoreAnimationStatus() { 21 CoreAnimationStatus GetCoreAnimationStatus() {
59 static CoreAnimationStatus status = 22 static CoreAnimationStatus status =
60 CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseCoreAnimation) ? 23 CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseCoreAnimation) ?
61 CORE_ANIMATION_ENABLED : CORE_ANIMATION_DISABLED; 24 CORE_ANIMATION_ENABLED : CORE_ANIMATION_DISABLED;
62 return status; 25 return status;
63 } 26 }
64 27
65 // static 28 // static
66 scoped_refptr<CompositingIOSurfaceContext> 29 scoped_refptr<CompositingIOSurfaceContext>
67 CompositingIOSurfaceContext::Get(int window_number) { 30 CompositingIOSurfaceContext::Get(int window_number) {
68 TRACE_EVENT0("browser", "CompositingIOSurfaceContext::Get"); 31 TRACE_EVENT0("browser", "CompositingIOSurfaceContext::Get");
69 32
70 // Return the context for this window_number, if it exists. 33 // Return the context for this window_number, if it exists.
71 WindowMap::iterator found = window_map()->find(window_number); 34 WindowMap::iterator found = window_map()->find(window_number);
72 if (found != window_map()->end()) { 35 if (found != window_map()->end()) {
73 DCHECK(found->second->can_be_shared_); 36 DCHECK(found->second->can_be_shared_);
74 return found->second; 37 return found->second;
75 } 38 }
76 39
77 bool is_vsync_disabled = 40 bool is_vsync_disabled =
78 CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync); 41 CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync);
79 42
80 base::scoped_nsobject<NSOpenGLContext> nsgl_context; 43 base::scoped_nsobject<NSOpenGLContext> nsgl_context;
81 ScopedCGLTypeRef<CGLContextObj, CGLReleaseContext> cgl_context_strong; 44 base::ScopedTypeRef<CGLContextObj> cgl_context_strong;
82 CGLContextObj cgl_context = NULL; 45 CGLContextObj cgl_context = NULL;
83 if (GetCoreAnimationStatus() == CORE_ANIMATION_DISABLED) { 46 if (GetCoreAnimationStatus() == CORE_ANIMATION_DISABLED) {
84 std::vector<NSOpenGLPixelFormatAttribute> attributes; 47 std::vector<NSOpenGLPixelFormatAttribute> attributes;
85 attributes.push_back(NSOpenGLPFADoubleBuffer); 48 attributes.push_back(NSOpenGLPFADoubleBuffer);
86 // We don't need a depth buffer - try setting its size to 0... 49 // We don't need a depth buffer - try setting its size to 0...
87 attributes.push_back(NSOpenGLPFADepthSize); attributes.push_back(0); 50 attributes.push_back(NSOpenGLPFADepthSize); attributes.push_back(0);
88 if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus()) 51 if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus())
89 attributes.push_back(NSOpenGLPFAAllowOfflineRenderers); 52 attributes.push_back(NSOpenGLPFAAllowOfflineRenderers);
90 attributes.push_back(0); 53 attributes.push_back(0);
91 54
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 // Create the pixel format object for the context. 90 // Create the pixel format object for the context.
128 std::vector<CGLPixelFormatAttribute> attribs; 91 std::vector<CGLPixelFormatAttribute> attribs;
129 attribs.push_back(kCGLPFADepthSize); 92 attribs.push_back(kCGLPFADepthSize);
130 attribs.push_back(static_cast<CGLPixelFormatAttribute>(0)); 93 attribs.push_back(static_cast<CGLPixelFormatAttribute>(0));
131 if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus()) { 94 if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus()) {
132 attribs.push_back(kCGLPFAAllowOfflineRenderers); 95 attribs.push_back(kCGLPFAAllowOfflineRenderers);
133 attribs.push_back(static_cast<CGLPixelFormatAttribute>(1)); 96 attribs.push_back(static_cast<CGLPixelFormatAttribute>(1));
134 } 97 }
135 attribs.push_back(static_cast<CGLPixelFormatAttribute>(0)); 98 attribs.push_back(static_cast<CGLPixelFormatAttribute>(0));
136 GLint number_virtual_screens = 0; 99 GLint number_virtual_screens = 0;
137 ScopedCGLTypeRef<CGLPixelFormatObj, CGLReleasePixelFormat> pixel_format; 100 base::ScopedTypeRef<CGLPixelFormatObj> pixel_format;
138 error = CGLChoosePixelFormat( 101 error = CGLChoosePixelFormat(&attribs.front(),
139 &attribs.front(), &pixel_format, &number_virtual_screens); 102 pixel_format.InitializeInto(),
103 &number_virtual_screens);
140 if (error != kCGLNoError) { 104 if (error != kCGLNoError) {
141 LOG(ERROR) << "Failed to create pixel format object."; 105 LOG(ERROR) << "Failed to create pixel format object.";
142 return NULL; 106 return NULL;
143 } 107 }
144 108
145 // Create all contexts in the same share group so that the textures don't 109 // Create all contexts in the same share group so that the textures don't
146 // need to be recreated when transitioning contexts. 110 // need to be recreated when transitioning contexts.
147 CGLContextObj share_context = NULL; 111 CGLContextObj share_context = NULL;
148 if (!window_map()->empty()) 112 if (!window_map()->empty())
149 share_context = window_map()->begin()->second->cgl_context(); 113 share_context = window_map()->begin()->second->cgl_context();
150 error = CGLCreateContext( 114 error = CGLCreateContext(
151 pixel_format, share_context, &cgl_context_strong); 115 pixel_format, share_context, cgl_context_strong.InitializeInto());
152 if (error != kCGLNoError) { 116 if (error != kCGLNoError) {
153 LOG(ERROR) << "Failed to create context object."; 117 LOG(ERROR) << "Failed to create context object.";
154 return NULL; 118 return NULL;
155 } 119 }
156 cgl_context = cgl_context_strong; 120 cgl_context = cgl_context_strong;
157 121
158 // Note that VSync is ignored because CoreAnimation will automatically 122 // Note that VSync is ignored because CoreAnimation will automatically
159 // rate limit draws. 123 // rate limit draws.
160 } 124 }
161 125
162 // Prepare the shader program cache. Precompile the shader programs 126 // Prepare the shader program cache. Precompile the shader programs
163 // needed to draw the IO Surface for non-offscreen contexts. 127 // needed to draw the IO Surface for non-offscreen contexts.
164 CGLSetCurrentContext(cgl_context);
165 scoped_ptr<CompositingIOSurfaceShaderPrograms> shader_program_cache(
166 new CompositingIOSurfaceShaderPrograms());
167 bool prepared = false; 128 bool prepared = false;
168 if (window_number == kOffscreenContextWindowNumber) { 129 scoped_ptr<CompositingIOSurfaceShaderPrograms> shader_program_cache;
169 prepared = true; 130 {
170 } else { 131 gfx::ScopedCGLSetCurrentContext scoped_set_current_context(cgl_context);
171 prepared = ( 132 shader_program_cache.reset(new CompositingIOSurfaceShaderPrograms());
172 shader_program_cache->UseBlitProgram() && 133 if (window_number == kOffscreenContextWindowNumber) {
173 shader_program_cache->UseSolidWhiteProgram()); 134 prepared = true;
135 } else {
136 prepared = (
137 shader_program_cache->UseBlitProgram() &&
138 shader_program_cache->UseSolidWhiteProgram());
139 }
140 glUseProgram(0u);
174 } 141 }
175 glUseProgram(0u);
176 CGLSetCurrentContext(0);
177 if (!prepared) { 142 if (!prepared) {
178 LOG(ERROR) << "IOSurface failed to compile/link required shader programs."; 143 LOG(ERROR) << "IOSurface failed to compile/link required shader programs.";
179 return NULL; 144 return NULL;
180 } 145 }
181 146
182 scoped_refptr<DisplayLinkMac> display_link = DisplayLinkMac::Create(); 147 scoped_refptr<DisplayLinkMac> display_link = DisplayLinkMac::Create();
183 if (!display_link) { 148 if (!display_link) {
184 LOG(ERROR) << "Failed to create display link for GL context."; 149 LOG(ERROR) << "Failed to create display link for GL context.";
185 return NULL; 150 return NULL;
186 } 151 }
187 152
188 return new CompositingIOSurfaceContext( 153 return new CompositingIOSurfaceContext(
189 window_number, 154 window_number,
190 nsgl_context.release(), 155 nsgl_context.release(),
191 cgl_context_strong.release(), 156 cgl_context_strong,
192 cgl_context, 157 cgl_context,
193 is_vsync_disabled, 158 is_vsync_disabled,
194 display_link, 159 display_link,
195 shader_program_cache.Pass()); 160 shader_program_cache.Pass());
196 } 161 }
197 162
198 // static 163 // static
199 void CompositingIOSurfaceContext::MarkExistingContextsAsNotShareable() { 164 void CompositingIOSurfaceContext::MarkExistingContextsAsNotShareable() {
200 for (WindowMap::iterator it = window_map()->begin(); 165 for (WindowMap::iterator it = window_map()->begin();
201 it != window_map()->end(); 166 it != window_map()->end();
202 ++it) { 167 ++it) {
203 it->second->can_be_shared_ = false; 168 it->second->can_be_shared_ = false;
204 } 169 }
205 window_map()->clear(); 170 window_map()->clear();
206 } 171 }
207 172
208 CompositingIOSurfaceContext::CompositingIOSurfaceContext( 173 CompositingIOSurfaceContext::CompositingIOSurfaceContext(
209 int window_number, 174 int window_number,
210 NSOpenGLContext* nsgl_context, 175 NSOpenGLContext* nsgl_context,
211 CGLContextObj cgl_context_strong, 176 base::ScopedTypeRef<CGLContextObj> cgl_context_strong,
212 CGLContextObj cgl_context, 177 CGLContextObj cgl_context,
213 bool is_vsync_disabled, 178 bool is_vsync_disabled,
214 scoped_refptr<DisplayLinkMac> display_link, 179 scoped_refptr<DisplayLinkMac> display_link,
215 scoped_ptr<CompositingIOSurfaceShaderPrograms> shader_program_cache) 180 scoped_ptr<CompositingIOSurfaceShaderPrograms> shader_program_cache)
216 : window_number_(window_number), 181 : window_number_(window_number),
217 nsgl_context_(nsgl_context), 182 nsgl_context_(nsgl_context),
218 cgl_context_strong_(cgl_context_strong), 183 cgl_context_strong_(cgl_context_strong),
219 cgl_context_(cgl_context), 184 cgl_context_(cgl_context),
220 is_vsync_disabled_(is_vsync_disabled), 185 is_vsync_disabled_(is_vsync_disabled),
221 shader_program_cache_(shader_program_cache.Pass()), 186 shader_program_cache_(shader_program_cache.Pass()),
222 can_be_shared_(true), 187 can_be_shared_(true),
223 initialized_is_intel_(false), 188 initialized_is_intel_(false),
224 is_intel_(false), 189 is_intel_(false),
225 screen_(0), 190 screen_(0),
226 display_link_(display_link) { 191 display_link_(display_link) {
227 DCHECK(window_map()->find(window_number_) == window_map()->end()); 192 DCHECK(window_map()->find(window_number_) == window_map()->end());
228 window_map()->insert(std::make_pair(window_number_, this)); 193 window_map()->insert(std::make_pair(window_number_, this));
229 } 194 }
230 195
231 CompositingIOSurfaceContext::~CompositingIOSurfaceContext() { 196 CompositingIOSurfaceContext::~CompositingIOSurfaceContext() {
232 CGLSetCurrentContext(cgl_context_); 197 {
233 shader_program_cache_->Reset(); 198 gfx::ScopedCGLSetCurrentContext scoped_set_current_context(cgl_context_);
234 CGLSetCurrentContext(0); 199 shader_program_cache_->Reset();
200 }
235 if (can_be_shared_) { 201 if (can_be_shared_) {
236 DCHECK(window_map()->find(window_number_) != window_map()->end()); 202 DCHECK(window_map()->find(window_number_) != window_map()->end());
237 DCHECK(window_map()->find(window_number_)->second == this); 203 DCHECK(window_map()->find(window_number_)->second == this);
238 window_map()->erase(window_number_); 204 window_map()->erase(window_number_);
239 } else { 205 } else {
240 WindowMap::const_iterator found = window_map()->find(window_number_); 206 WindowMap::const_iterator found = window_map()->find(window_number_);
241 if (found != window_map()->end()) 207 if (found != window_map()->end())
242 DCHECK(found->second != this); 208 DCHECK(found->second != this);
243 } 209 }
244 if (cgl_context_strong_)
245 CGLReleaseContext(cgl_context_strong_);
246 } 210 }
247 211
248 NSOpenGLContext* CompositingIOSurfaceContext::nsgl_context() const { 212 NSOpenGLContext* CompositingIOSurfaceContext::nsgl_context() const {
249 // This should not be called from any CoreAnimation paths. 213 // This should not be called from any CoreAnimation paths.
250 CHECK(GetCoreAnimationStatus() == CORE_ANIMATION_DISABLED); 214 CHECK(GetCoreAnimationStatus() == CORE_ANIMATION_DISABLED);
251 return nsgl_context_; 215 return nsgl_context_;
252 } 216 }
253 217
254 bool CompositingIOSurfaceContext::IsVendorIntel() { 218 bool CompositingIOSurfaceContext::IsVendorIntel() {
255 GLint screen; 219 GLint screen;
(...skipping 13 matching lines...) Expand all
269 CompositingIOSurfaceContext::WindowMap* 233 CompositingIOSurfaceContext::WindowMap*
270 CompositingIOSurfaceContext::window_map() { 234 CompositingIOSurfaceContext::window_map() {
271 return window_map_.Pointer(); 235 return window_map_.Pointer();
272 } 236 }
273 237
274 // static 238 // static
275 base::LazyInstance<CompositingIOSurfaceContext::WindowMap> 239 base::LazyInstance<CompositingIOSurfaceContext::WindowMap>
276 CompositingIOSurfaceContext::window_map_; 240 CompositingIOSurfaceContext::window_map_;
277 241
278 } // namespace content 242 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698