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 |