| 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_EVENT2("browser", "AcceleratedPluginView::getFrameForTime", |
| 20 "swapBuffersCount_", swapBuffersCount_, |
| 21 "acknowledgedSwapBuffersCount_", acknowledgedSwapBuffersCount_); |
| 19 // There is no autorelease pool when this method is called because it will be | 22 // There is no autorelease pool when this method is called because it will be |
| 20 // called from a background thread. | 23 // called from a background thread. |
| 21 base::mac::ScopedNSAutoreleasePool pool; | 24 base::mac::ScopedNSAutoreleasePool pool; |
| 22 | 25 |
| 23 bool sendAck = (rendererId_ != 0 || routeId_ != 0); | 26 bool sendAck = (rendererId_ != 0 || routeId_ != 0); |
| 24 uint64 currentSwapBuffersCount = swapBuffersCount_; | 27 uint64 currentSwapBuffersCount = swapBuffersCount_; |
| 25 if (currentSwapBuffersCount == acknowledgedSwapBuffersCount_) { | 28 if (currentSwapBuffersCount == acknowledgedSwapBuffersCount_) { |
| 26 return kCVReturnSuccess; | 29 return kCVReturnSuccess; |
| 27 } | 30 } |
| 28 | 31 |
| 29 [self drawView]; | 32 [self drawView]; |
| 30 | 33 |
| 31 acknowledgedSwapBuffersCount_ = currentSwapBuffersCount; | 34 acknowledgedSwapBuffersCount_ = currentSwapBuffersCount; |
| 32 if (sendAck && renderWidgetHostView_) { | 35 if (sendAck && renderWidgetHostView_) { |
| 33 renderWidgetHostView_->AcknowledgeSwapBuffers( | 36 renderWidgetHostView_->AcknowledgeSwapBuffers( |
| 34 rendererId_, | 37 rendererId_, |
| 35 routeId_, | 38 routeId_, |
| 36 gpuHostId_, | 39 gpuHostId_, |
| 37 acknowledgedSwapBuffersCount_); | 40 acknowledgedSwapBuffersCount_); |
| 38 } | 41 } |
| 39 | 42 |
| 40 return kCVReturnSuccess; | 43 return kCVReturnSuccess; |
| 41 } | 44 } |
| 42 | 45 |
| 43 // This is the renderer output callback function | 46 ///// This is the renderer output callback function |
| 44 static CVReturn DrawOneAcceleratedPluginCallback( | 47 ///static CVReturn DrawOneAcceleratedPluginCallback( |
| 45 CVDisplayLinkRef displayLink, | 48 /// CVDisplayLinkRef displayLink, |
| 46 const CVTimeStamp* now, | 49 /// const CVTimeStamp* now, |
| 47 const CVTimeStamp* outputTime, | 50 /// const CVTimeStamp* outputTime, |
| 48 CVOptionFlags flagsIn, | 51 /// CVOptionFlags flagsIn, |
| 49 CVOptionFlags* flagsOut, | 52 /// CVOptionFlags* flagsOut, |
| 50 void* displayLinkContext) { | 53 /// void* displayLinkContext) { |
| 51 CVReturn result = | 54 /// CVReturn result = |
| 52 [(AcceleratedPluginView*)displayLinkContext getFrameForTime:outputTime]; | 55 /// [(AcceleratedPluginView*)displayLinkContext getFrameForTime:outputTime]
; |
| 53 return result; | 56 /// return result; |
| 54 } | 57 ///} |
| 55 | 58 |
| 56 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r | 59 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r |
| 57 pluginHandle:(gfx::PluginWindowHandle)pluginHandle { | 60 pluginHandle:(gfx::PluginWindowHandle)pluginHandle { |
| 58 if ((self = [super initWithFrame:NSZeroRect])) { | 61 if ((self = [super initWithFrame:NSZeroRect])) { |
| 62 TRACE_EVENT0("browser", |
| 63 "AcceleratedPluginView::initWithRenderWidgetHostViewMac"); |
| 59 renderWidgetHostView_ = r; | 64 renderWidgetHostView_ = r; |
| 60 pluginHandle_ = pluginHandle; | 65 pluginHandle_ = pluginHandle; |
| 61 cachedSize_ = NSZeroSize; | 66 cachedSize_ = NSZeroSize; |
| 62 swapBuffersCount_ = 0; | 67 swapBuffersCount_ = 0; |
| 63 acknowledgedSwapBuffersCount_ = 0; | 68 acknowledgedSwapBuffersCount_ = 0; |
| 64 rendererId_ = 0; | 69 rendererId_ = 0; |
| 65 routeId_ = 0; | 70 routeId_ = 0; |
| 66 gpuHostId_ = 0; | 71 gpuHostId_ = 0; |
| 67 | 72 |
| 68 [self setAutoresizingMask:NSViewMaxXMargin|NSViewMinYMargin]; | 73 [self setAutoresizingMask:NSViewMaxXMargin|NSViewMinYMargin]; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 84 cglPixelFormat_ = (CGLPixelFormatObj)[glPixelFormat_ CGLPixelFormatObj]; | 89 cglPixelFormat_ = (CGLPixelFormatObj)[glPixelFormat_ CGLPixelFormatObj]; |
| 85 | 90 |
| 86 // Draw at beam vsync. | 91 // Draw at beam vsync. |
| 87 GLint swapInterval; | 92 GLint swapInterval; |
| 88 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync)) | 93 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync)) |
| 89 swapInterval = 0; | 94 swapInterval = 0; |
| 90 else | 95 else |
| 91 swapInterval = 1; | 96 swapInterval = 1; |
| 92 [glContext_ setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval]; | 97 [glContext_ setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval]; |
| 93 | 98 |
| 94 // Set up a display link to do OpenGL rendering on a background thread. | 99 /// // Set up a display link to do OpenGL rendering on a background thread. |
| 95 CVDisplayLinkCreateWithActiveCGDisplays(&displayLink_); | 100 /// CVDisplayLinkCreateWithActiveCGDisplays(&displayLink_); |
| 96 } | 101 } |
| 97 return self; | 102 return self; |
| 98 } | 103 } |
| 99 | 104 |
| 100 - (void)dealloc { | 105 - (void)dealloc { |
| 101 CVDisplayLinkRelease(displayLink_); | 106 ///CVDisplayLinkRelease(displayLink_); |
| 102 if (renderWidgetHostView_) | 107 if (renderWidgetHostView_) { |
| 108 bool sendAck = (rendererId_ != 0 || routeId_ != 0) && |
| 109 (swapBuffersCount_ != acknowledgedSwapBuffersCount_); |
| 110 if (sendAck) { |
| 111 // Prevent deadlock issues if the GPU process is expecting an ack of the |
| 112 // SwapBuffers. |
| 113 renderWidgetHostView_->AcknowledgeSwapBuffers( |
| 114 rendererId_, |
| 115 routeId_, |
| 116 gpuHostId_, |
| 117 swapBuffersCount_); |
| 118 } |
| 103 renderWidgetHostView_->DeallocFakePluginWindowHandle(pluginHandle_); | 119 renderWidgetHostView_->DeallocFakePluginWindowHandle(pluginHandle_); |
| 120 } |
| 104 [[NSNotificationCenter defaultCenter] removeObserver:self]; | 121 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
| 105 [super dealloc]; | 122 [super dealloc]; |
| 106 } | 123 } |
| 107 | 124 |
| 108 - (void)drawView { | 125 - (void)drawView { |
| 109 TRACE_EVENT1("browser", "AcceleratedPluginViewMac::drawView", | 126 TRACE_EVENT1("browser", "AcceleratedPluginViewMac::drawView", |
| 110 "frameNum", swapBuffersCount_); | 127 "frameNum", swapBuffersCount_); |
| 111 // Called on a background thread. Synchronized via the CGL context lock. | 128 // Called on a background thread. Synchronized via the CGL context lock. |
| 112 CGLLockContext(cglContext_); | 129 CGLLockContext(cglContext_); |
| 113 | 130 |
| 114 if (renderWidgetHostView_) { | 131 if (renderWidgetHostView_) { |
| 115 // TODO(thakis): Pixel or view coordinates for size? | 132 // TODO(thakis): Pixel or view coordinates for size? |
| 116 renderWidgetHostView_->DrawAcceleratedSurfaceInstance( | 133 renderWidgetHostView_->DrawAcceleratedSurfaceInstance( |
| 117 cglContext_, pluginHandle_, [self cachedSize]); | 134 cglContext_, pluginHandle_, [self cachedSize]); |
| 118 } | 135 } |
| 119 | 136 |
| 120 CGLFlushDrawable(cglContext_); | 137 CGLFlushDrawable(cglContext_); |
| 121 CGLSetCurrentContext(0); | 138 CGLSetCurrentContext(0); |
| 122 CGLUnlockContext(cglContext_); | 139 CGLUnlockContext(cglContext_); |
| 123 } | 140 } |
| 124 | 141 |
| 125 - (void)setCutoutRects:(NSArray*)cutout_rects { | 142 - (void)setCutoutRects:(NSArray*)cutout_rects { |
| 126 cutoutRects_.reset([cutout_rects copy]); | 143 cutoutRects_.reset([cutout_rects copy]); |
| 127 } | 144 } |
| 128 | 145 |
| 129 - (void)updateSwapBuffersCount:(uint64)count | 146 - (void)updateSwapBuffersCount:(uint64)count |
| 130 fromRenderer:(int)rendererId | 147 fromRenderer:(int)rendererId |
| 131 routeId:(int32)routeId | 148 routeId:(int32)routeId |
| 132 gpuHostId:(int)gpuHostId { | 149 gpuHostId:(int)gpuHostId { |
| 150 TRACE_EVENT2("browser", "AcceleratedPluginView::updateSwapBuffersCount", |
| 151 "routeId", routeId, "count", count); |
| 133 if (rendererId == 0 && routeId == 0) { | 152 if (rendererId == 0 && routeId == 0) { |
| 134 // This notification is coming from a plugin process, for which we | 153 // This notification is coming from a plugin process, for which we |
| 135 // don't have flow control implemented right now. Fake up a swap | 154 // don't have flow control implemented right now. Fake up a swap |
| 136 // buffers count so that we can at least skip useless renders. | 155 // buffers count so that we can at least skip useless renders. |
| 137 ++swapBuffersCount_; | 156 ++swapBuffersCount_; |
| 138 } else { | 157 } else { |
| 139 rendererId_ = rendererId; | 158 rendererId_ = rendererId; |
| 140 routeId_ = routeId; | 159 routeId_ = routeId; |
| 141 gpuHostId_ = gpuHostId; | 160 gpuHostId_ = gpuHostId; |
| 142 swapBuffersCount_ = count; | 161 swapBuffersCount_ = count; |
| 143 } | 162 } |
| 163 [self getFrameForTime:NULL]; |
| 144 } | 164 } |
| 145 | 165 |
| 146 - (void)onRenderWidgetHostViewGone { | 166 - (void)onRenderWidgetHostViewGone { |
| 147 if (!renderWidgetHostView_) | 167 if (!renderWidgetHostView_) |
| 148 return; | 168 return; |
| 149 | 169 |
| 150 CGLLockContext(cglContext_); | 170 CGLLockContext(cglContext_); |
| 151 // Deallocate the plugin handle while we still can. | 171 // Deallocate the plugin handle while we still can. |
| 152 renderWidgetHostView_->DeallocFakePluginWindowHandle(pluginHandle_); | 172 renderWidgetHostView_->DeallocFakePluginWindowHandle(pluginHandle_); |
| 153 renderWidgetHostView_ = NULL; | 173 renderWidgetHostView_ = NULL; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 | 231 |
| 212 // You would think that -update updates the viewport. You would be wrong. | 232 // You would think that -update updates the viewport. You would be wrong. |
| 213 CGLSetCurrentContext(cglContext_); | 233 CGLSetCurrentContext(cglContext_); |
| 214 NSSize size = [self frame].size; | 234 NSSize size = [self frame].size; |
| 215 glViewport(0, 0, size.width, size.height); | 235 glViewport(0, 0, size.width, size.height); |
| 216 | 236 |
| 217 CGLSetCurrentContext(0); | 237 CGLSetCurrentContext(0); |
| 218 CGLUnlockContext(cglContext_); | 238 CGLUnlockContext(cglContext_); |
| 219 globalFrameDidChangeCGLLockCount_--; | 239 globalFrameDidChangeCGLLockCount_--; |
| 220 | 240 |
| 221 if (globalFrameDidChangeCGLLockCount_ == 0) { | 241 ///if (globalFrameDidChangeCGLLockCount_ == 0) { |
| 222 // Make sure the view is synchronized with the correct display. | 242 /// // Make sure the view is synchronized with the correct display. |
| 223 CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext( | 243 /// CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext( |
| 224 displayLink_, cglContext_, cglPixelFormat_); | 244 /// displayLink_, cglContext_, cglPixelFormat_); |
| 225 } | 245 ///} |
| 226 } | 246 } |
| 227 | 247 |
| 228 - (void)renewGState { | 248 - (void)renewGState { |
| 229 // Synchronize with window server to avoid flashes or corrupt drawing. | 249 // Synchronize with window server to avoid flashes or corrupt drawing. |
| 230 [[self window] disableScreenUpdatesUntilFlush]; | 250 [[self window] disableScreenUpdatesUntilFlush]; |
| 231 [self globalFrameDidChange:nil]; | 251 [self globalFrameDidChange:nil]; |
| 232 [super renewGState]; | 252 [super renewGState]; |
| 233 } | 253 } |
| 234 | 254 |
| 235 - (void)lockFocus { | 255 - (void)lockFocus { |
| 236 [super lockFocus]; | 256 [super lockFocus]; |
| 237 | 257 |
| 238 // If we're using OpenGL, make sure it is connected and that the display link | 258 // If we're using OpenGL, make sure it is connected and that the display link |
| 239 // is running. | 259 // is running. |
| 240 if ([glContext_ view] != self) { | 260 if ([glContext_ view] != self) { |
| 241 [glContext_ setView:self]; | 261 [glContext_ setView:self]; |
| 242 | 262 |
| 243 [[NSNotificationCenter defaultCenter] | 263 [[NSNotificationCenter defaultCenter] |
| 244 addObserver:self | 264 addObserver:self |
| 245 selector:@selector(globalFrameDidChange:) | 265 selector:@selector(globalFrameDidChange:) |
| 246 name:NSViewGlobalFrameDidChangeNotification | 266 name:NSViewGlobalFrameDidChangeNotification |
| 247 object:self]; | 267 object:self]; |
| 248 CVDisplayLinkSetOutputCallback( | 268 /// CVDisplayLinkSetOutputCallback( |
| 249 displayLink_, &DrawOneAcceleratedPluginCallback, self); | 269 /// displayLink_, &DrawOneAcceleratedPluginCallback, self); |
| 250 CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext( | 270 /// CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext( |
| 251 displayLink_, cglContext_, cglPixelFormat_); | 271 /// displayLink_, cglContext_, cglPixelFormat_); |
| 252 CVDisplayLinkStart(displayLink_); | 272 /// CVDisplayLinkStart(displayLink_); |
| 253 } | 273 } |
| 254 [glContext_ makeCurrentContext]; | 274 [glContext_ makeCurrentContext]; |
| 255 } | 275 } |
| 256 | 276 |
| 257 - (void)viewWillMoveToWindow:(NSWindow*)newWindow { | 277 - (void)viewWillMoveToWindow:(NSWindow*)newWindow { |
| 258 // Stop the display link thread while the view is not visible. | 278 // Stop the display link thread while the view is not visible. |
| 259 if (newWindow) { | 279 TRACE_EVENT1("renderer", "viewWillMoveToWindow", |
| 260 if (displayLink_ && !CVDisplayLinkIsRunning(displayLink_)) | 280 "newWindow", newWindow); |
| 261 CVDisplayLinkStart(displayLink_); | 281 ///if (newWindow) { |
| 262 } else { | 282 /// if (displayLink_ && !CVDisplayLinkIsRunning(displayLink_)) { |
| 263 if (displayLink_ && CVDisplayLinkIsRunning(displayLink_)) | 283 /// TRACE_EVENT0("renderer", "CVDisplayLinkStart"); |
| 264 CVDisplayLinkStop(displayLink_); | 284 /// CVDisplayLinkStart(displayLink_); |
| 265 } | 285 /// } |
| 286 ///} else { |
| 287 /// if (displayLink_ && CVDisplayLinkIsRunning(displayLink_)) { |
| 288 /// TRACE_EVENT0("renderer", "CVDisplayLinkStop"); |
| 289 /// CVDisplayLinkStop(displayLink_); |
| 290 /// } |
| 291 ///} |
| 266 | 292 |
| 267 // Inform the window hosting this accelerated view that it needs to be | 293 // Inform the window hosting this accelerated view that it needs to be |
| 268 // transparent. | 294 // transparent. |
| 269 if (![self isHiddenOrHasHiddenAncestor]) { | 295 if (![self isHiddenOrHasHiddenAncestor]) { |
| 270 if ([[self window] respondsToSelector:@selector(underlaySurfaceRemoved)]) | 296 if ([[self window] respondsToSelector:@selector(underlaySurfaceRemoved)]) |
| 271 [static_cast<id>([self window]) underlaySurfaceRemoved]; | 297 [static_cast<id>([self window]) underlaySurfaceRemoved]; |
| 272 if ([newWindow respondsToSelector:@selector(underlaySurfaceAdded)]) | 298 if ([newWindow respondsToSelector:@selector(underlaySurfaceAdded)]) |
| 273 [static_cast<id>(newWindow) underlaySurfaceAdded]; | 299 [static_cast<id>(newWindow) underlaySurfaceAdded]; |
| 274 } | 300 } |
| 275 } | 301 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 [[self window] makeFirstResponder:[self superview]]; | 340 [[self window] makeFirstResponder:[self superview]]; |
| 315 return YES; | 341 return YES; |
| 316 } | 342 } |
| 317 | 343 |
| 318 - (void)viewDidMoveToSuperview { | 344 - (void)viewDidMoveToSuperview { |
| 319 if (![self superview]) | 345 if (![self superview]) |
| 320 [self onRenderWidgetHostViewGone]; | 346 [self onRenderWidgetHostViewGone]; |
| 321 } | 347 } |
| 322 @end | 348 @end |
| 323 | 349 |
| OLD | NEW |