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 |