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

Side by Side Diff: chrome/browser/renderer_host/accelerated_plugin_view_mac.mm

Issue 6993043: Fix the mac hangup when force-compositing-mode is enabled (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: DisplayLink back in, hopefully found root cause of bug Created 9 years, 6 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 #import "chrome/browser/renderer_host/accelerated_plugin_view_mac.h" 5 #import "chrome/browser/renderer_host/accelerated_plugin_view_mac.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/debug/trace_event.h" 8 #include "base/debug/trace_event.h"
9 #import "base/mac/scoped_nsautorelease_pool.h" 9 #import "base/mac/scoped_nsautorelease_pool.h"
10 #include "chrome/browser/renderer_host/render_widget_host_view_mac.h" 10 #include "chrome/browser/renderer_host/render_widget_host_view_mac.h"
11 #include "chrome/common/chrome_switches.h" 11 #include "chrome/common/chrome_switches.h"
12 #include "ui/gfx/gl/gl_switches.h" 12 #include "ui/gfx/gl/gl_switches.h"
13 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" 13 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
14 14
15 @implementation AcceleratedPluginView 15 @implementation AcceleratedPluginView
16 @synthesize cachedSize = cachedSize_; 16 @synthesize cachedSize = cachedSize_;
17 17
18 - (CVReturn)getFrameForTime:(const CVTimeStamp*)outputTime { 18 - (CVReturn)getFrameForTime:(const CVTimeStamp*)outputTime {
19 TRACE_EVENT0("browser", "AcceleratedPluginView::getFrameForTime");
19 // There is no autorelease pool when this method is called because it will be 20 // There is no autorelease pool when this method is called because it will be
20 // called from a background thread. 21 // called from a background thread.
21 base::mac::ScopedNSAutoreleasePool pool; 22 base::mac::ScopedNSAutoreleasePool pool;
22 23
23 bool sendAck = (rendererId_ != 0 || routeId_ != 0); 24 bool sendAck = (rendererId_ != 0 || routeId_ != 0);
24 uint64 currentSwapBuffersCount = swapBuffersCount_; 25 uint64 currentSwapBuffersCount = swapBuffersCount_;
25 if (currentSwapBuffersCount == acknowledgedSwapBuffersCount_) { 26 if (currentSwapBuffersCount == acknowledgedSwapBuffersCount_) {
26 return kCVReturnSuccess; 27 return kCVReturnSuccess;
27 } 28 }
28 29
30 CGLLockContext(cglContext_);
31
29 [self drawView]; 32 [self drawView];
30 33
31 acknowledgedSwapBuffersCount_ = currentSwapBuffersCount; 34 acknowledgedSwapBuffersCount_ = currentSwapBuffersCount;
35 // Locked here because renderWidgetHostView_ is set to NULL on another thread.
Ken Russell (switch to Gerrit) 2011/06/10 01:30:12 Maybe move this comment next to the call to CGLLoc
jbates 2011/06/11 02:00:44 Done.
32 if (sendAck && renderWidgetHostView_) { 36 if (sendAck && renderWidgetHostView_) {
33 renderWidgetHostView_->AcknowledgeSwapBuffers( 37 renderWidgetHostView_->AcknowledgeSwapBuffers(
34 rendererId_, 38 rendererId_,
35 routeId_, 39 routeId_,
36 gpuHostId_, 40 gpuHostId_,
37 acknowledgedSwapBuffersCount_); 41 acknowledgedSwapBuffersCount_);
38 } 42 }
39 43
44 CGLUnlockContext(cglContext_);
45
40 return kCVReturnSuccess; 46 return kCVReturnSuccess;
41 } 47 }
42 48
43 // This is the renderer output callback function 49 // This is the renderer output callback function
44 static CVReturn DrawOneAcceleratedPluginCallback( 50 static CVReturn DrawOneAcceleratedPluginCallback(
45 CVDisplayLinkRef displayLink, 51 CVDisplayLinkRef displayLink,
46 const CVTimeStamp* now, 52 const CVTimeStamp* now,
47 const CVTimeStamp* outputTime, 53 const CVTimeStamp* outputTime,
48 CVOptionFlags flagsIn, 54 CVOptionFlags flagsIn,
49 CVOptionFlags* flagsOut, 55 CVOptionFlags* flagsOut,
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 return; 154 return;
149 155
150 CGLLockContext(cglContext_); 156 CGLLockContext(cglContext_);
151 // Deallocate the plugin handle while we still can. 157 // Deallocate the plugin handle while we still can.
152 renderWidgetHostView_->DeallocFakePluginWindowHandle(pluginHandle_); 158 renderWidgetHostView_->DeallocFakePluginWindowHandle(pluginHandle_);
153 renderWidgetHostView_ = NULL; 159 renderWidgetHostView_ = NULL;
154 CGLUnlockContext(cglContext_); 160 CGLUnlockContext(cglContext_);
155 } 161 }
156 162
157 - (void)drawRect:(NSRect)rect { 163 - (void)drawRect:(NSRect)rect {
164 TRACE_EVENT0("browser", "AcceleratedPluginView::drawRect");
158 const NSRect* dirtyRects; 165 const NSRect* dirtyRects;
159 int dirtyRectCount; 166 int dirtyRectCount;
160 [self getRectsBeingDrawn:&dirtyRects count:&dirtyRectCount]; 167 [self getRectsBeingDrawn:&dirtyRects count:&dirtyRectCount];
161 168
162 { 169 {
163 gfx::ScopedNSGraphicsContextSaveGState scopedGState; 170 gfx::ScopedNSGraphicsContextSaveGState scopedGState;
164 171
165 // Mask out any cutout rects--somewhat counterintuitively cutout rects are 172 // Mask out any cutout rects--somewhat counterintuitively cutout rects are
166 // places where clearColor is *not* drawn. The trick is that drawing nothing 173 // places where clearColor is *not* drawn. The trick is that drawing nothing
167 // lets the parent view (i.e., the web page) show through, whereas drawing 174 // lets the parent view (i.e., the web page) show through, whereas drawing
(...skipping 15 matching lines...) Expand all
183 } 190 }
184 191
185 [path addClip]; 192 [path addClip];
186 } 193 }
187 194
188 // Punch a hole so that the OpenGL view shows through. 195 // Punch a hole so that the OpenGL view shows through.
189 [[NSColor clearColor] set]; 196 [[NSColor clearColor] set];
190 NSRectFillList(dirtyRects, dirtyRectCount); 197 NSRectFillList(dirtyRects, dirtyRectCount);
191 } 198 }
192 199
200 CGLLockContext(cglContext_);
Ken Russell (switch to Gerrit) 2011/06/10 01:30:12 This is unnecessary. The first thing drawView does
jbates 2011/06/11 02:00:44 I meant to remove the drawView mutex locking, sinc
193 [self drawView]; 201 [self drawView];
202 CGLUnlockContext(cglContext_);
Ken Russell (switch to Gerrit) 2011/06/10 01:30:12 Unnecessary.
194 } 203 }
195 204
196 - (void)rightMouseDown:(NSEvent*)event { 205 - (void)rightMouseDown:(NSEvent*)event {
197 // The NSResponder documentation: "Note: The NSView implementation of this 206 // The NSResponder documentation: "Note: The NSView implementation of this
198 // method does not pass the message up the responder chain, it handles it 207 // method does not pass the message up the responder chain, it handles it
199 // directly." 208 // directly."
200 // That's bad, we want the next responder (RWHVMac) to handle this event to 209 // That's bad, we want the next responder (RWHVMac) to handle this event to
201 // dispatch it to the renderer. 210 // dispatch it to the renderer.
202 [[self nextResponder] rightMouseDown:event]; 211 [[self nextResponder] rightMouseDown:event];
203 } 212 }
(...skipping 21 matching lines...) Expand all
225 } 234 }
226 } 235 }
227 236
228 - (void)renewGState { 237 - (void)renewGState {
229 // Synchronize with window server to avoid flashes or corrupt drawing. 238 // Synchronize with window server to avoid flashes or corrupt drawing.
230 [[self window] disableScreenUpdatesUntilFlush]; 239 [[self window] disableScreenUpdatesUntilFlush];
231 [self globalFrameDidChange:nil]; 240 [self globalFrameDidChange:nil];
232 [super renewGState]; 241 [super renewGState];
233 } 242 }
234 243
235 - (void)lockFocus { 244 - (void)setViewForGL {
236 [super lockFocus]; 245 TRACE_EVENT0("browser", "AcceleratedPluginView::setViewForGL");
237 246
238 // If we're using OpenGL, make sure it is connected and that the display link 247 // If we're using OpenGL, make sure it is connected and that the display link
239 // is running. 248 // is running.
240 if ([glContext_ view] != self) { 249 if ([glContext_ view] != self) {
241 [glContext_ setView:self]; 250 [glContext_ setView:self];
242 251
243 [[NSNotificationCenter defaultCenter] 252 [[NSNotificationCenter defaultCenter]
244 addObserver:self 253 addObserver:self
245 selector:@selector(globalFrameDidChange:) 254 selector:@selector(globalFrameDidChange:)
246 name:NSViewGlobalFrameDidChangeNotification 255 name:NSViewGlobalFrameDidChangeNotification
247 object:self]; 256 object:self];
248 CVDisplayLinkSetOutputCallback( 257 CVDisplayLinkSetOutputCallback(
249 displayLink_, &DrawOneAcceleratedPluginCallback, self); 258 displayLink_, &DrawOneAcceleratedPluginCallback, self);
250 CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext( 259 CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(
251 displayLink_, cglContext_, cglPixelFormat_); 260 displayLink_, cglContext_, cglPixelFormat_);
252 CVDisplayLinkStart(displayLink_); 261 CVDisplayLinkStart(displayLink_);
253 } 262 }
263 }
264
265 - (void)lockFocus {
266 TRACE_EVENT0("browser", "AcceleratedPluginView::lockFocus");
267 [super lockFocus];
268 [self setViewForGL];
254 [glContext_ makeCurrentContext]; 269 [glContext_ makeCurrentContext];
255 } 270 }
256 271
257 - (void)viewWillMoveToWindow:(NSWindow*)newWindow { 272 - (void)viewWillMoveToWindow:(NSWindow*)newWindow {
273 TRACE_EVENT1("browser", "AcceleratedPluginView::viewWillMoveToWindow",
274 "newWindow", newWindow);
258 // Stop the display link thread while the view is not visible. 275 // Stop the display link thread while the view is not visible.
259 if (newWindow) { 276 if (newWindow) {
260 if (displayLink_ && !CVDisplayLinkIsRunning(displayLink_)) 277 if (displayLink_ && !CVDisplayLinkIsRunning(displayLink_))
261 CVDisplayLinkStart(displayLink_); 278 CVDisplayLinkStart(displayLink_);
262 } else { 279 } else {
263 if (displayLink_ && CVDisplayLinkIsRunning(displayLink_)) 280 if (displayLink_ && CVDisplayLinkIsRunning(displayLink_))
264 CVDisplayLinkStop(displayLink_); 281 CVDisplayLinkStop(displayLink_);
265 } 282 }
266 283
267 // Inform the window hosting this accelerated view that it needs to be 284 // Inform the window hosting this accelerated view that it needs to be
268 // transparent. 285 // transparent.
269 if (![self isHiddenOrHasHiddenAncestor]) { 286 if (![self isHiddenOrHasHiddenAncestor]) {
270 if ([[self window] respondsToSelector:@selector(underlaySurfaceRemoved)]) 287 if ([[self window] respondsToSelector:@selector(underlaySurfaceRemoved)])
271 [static_cast<id>([self window]) underlaySurfaceRemoved]; 288 [static_cast<id>([self window]) underlaySurfaceRemoved];
272 if ([newWindow respondsToSelector:@selector(underlaySurfaceAdded)]) 289 if ([newWindow respondsToSelector:@selector(underlaySurfaceAdded)])
273 [static_cast<id>(newWindow) underlaySurfaceAdded]; 290 [static_cast<id>(newWindow) underlaySurfaceAdded];
274 } 291 }
275 } 292 }
276 293
277 - (void)viewDidHide { 294 - (void)viewDidHide {
295 TRACE_EVENT0("browser", "AcceleratedPluginView::viewDidHide");
278 [super viewDidHide]; 296 [super viewDidHide];
279 297
280 if ([[self window] respondsToSelector:@selector(underlaySurfaceRemoved)]) { 298 if ([[self window] respondsToSelector:@selector(underlaySurfaceRemoved)]) {
281 [static_cast<id>([self window]) underlaySurfaceRemoved]; 299 [static_cast<id>([self window]) underlaySurfaceRemoved];
282 } 300 }
283 } 301 }
284 302
285 - (void)viewDidUnhide { 303 - (void)viewDidUnhide {
304 TRACE_EVENT0("browser", "AcceleratedPluginView::viewDidUnhide");
286 [super viewDidUnhide]; 305 [super viewDidUnhide];
287 306
288 if ([[self window] respondsToSelector:@selector(underlaySurfaceRemoved)]) { 307 if ([[self window] respondsToSelector:@selector(underlaySurfaceRemoved)]) {
289 [static_cast<id>([self window]) underlaySurfaceAdded]; 308 [static_cast<id>([self window]) underlaySurfaceAdded];
290 } 309 }
291 } 310 }
292 311
293 - (void)setFrame:(NSRect)frameRect { 312 - (void)setFrame:(NSRect)frameRect {
294 TRACE_EVENT0("browser", "AcceleratedPluginViewMac::setFrame"); 313 TRACE_EVENT0("browser", "AcceleratedPluginViewMac::setFrame");
295 [self setCachedSize:frameRect.size]; 314 [self setCachedSize:frameRect.size];
296 [super setFrame:frameRect]; 315 [super setFrame:frameRect];
297 } 316 }
298 317
299 - (void)setFrameSize:(NSSize)newSize { 318 - (void)setFrameSize:(NSSize)newSize {
319 TRACE_EVENT0("browser", "AcceleratedPluginView::newSize");
300 [self setCachedSize:newSize]; 320 [self setCachedSize:newSize];
301 [super setFrameSize:newSize]; 321 [super setFrameSize:newSize];
302 } 322 }
303 323
304 - (BOOL)acceptsFirstResponder { 324 - (BOOL)acceptsFirstResponder {
305 // Accept first responder if the first responder isn't the RWHVMac, and if the 325 // Accept first responder if the first responder isn't the RWHVMac, and if the
306 // RWHVMac accepts first responder. If the RWHVMac does not accept first 326 // RWHVMac accepts first responder. If the RWHVMac does not accept first
307 // responder, do not accept on its behalf. 327 // responder, do not accept on its behalf.
308 return ([[self window] firstResponder] != [self superview] && 328 return ([[self window] firstResponder] != [self superview] &&
309 [[self superview] acceptsFirstResponder]); 329 [[self superview] acceptsFirstResponder]);
310 } 330 }
311 331
312 - (BOOL)becomeFirstResponder { 332 - (BOOL)becomeFirstResponder {
313 // Delegate first responder to the RWHVMac. 333 // Delegate first responder to the RWHVMac.
314 [[self window] makeFirstResponder:[self superview]]; 334 [[self window] makeFirstResponder:[self superview]];
315 return YES; 335 return YES;
316 } 336 }
317 337
318 - (void)viewDidMoveToSuperview { 338 - (void)viewDidMoveToSuperview {
339 TRACE_EVENT0("browser", "AcceleratedPluginView::viewDidMoveToSuperview");
319 if (![self superview]) 340 if (![self superview])
320 [self onRenderWidgetHostViewGone]; 341 [self onRenderWidgetHostViewGone];
321 } 342 }
322 @end 343 @end
323 344
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698