Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |