Index: chrome/browser/renderer_host/accelerated_plugin_view_mac.mm |
diff --git a/chrome/browser/renderer_host/accelerated_plugin_view_mac.mm b/chrome/browser/renderer_host/accelerated_plugin_view_mac.mm |
index 82638b6ba48ace0e12344a09a76e4b2034a0f8c4..18652a7b3defe368e42804125678d8d10a8b6b8e 100644 |
--- a/chrome/browser/renderer_host/accelerated_plugin_view_mac.mm |
+++ b/chrome/browser/renderer_host/accelerated_plugin_view_mac.mm |
@@ -15,27 +15,53 @@ |
@implementation AcceleratedPluginView |
@synthesize cachedSize = cachedSize_; |
+- (void)drawView { |
+ TRACE_EVENT1("browser", "AcceleratedPluginViewMac::drawView", |
+ "frameNum", swapBuffersCount_); |
+ |
+ if (renderWidgetHostView_) { |
+ // TODO(thakis): Pixel or view coordinates for size? |
+ renderWidgetHostView_->DrawAcceleratedSurfaceInstance( |
+ cglContext_, pluginHandle_, [self cachedSize]); |
+ } |
+ |
+ CGLFlushDrawable(cglContext_); |
+ CGLSetCurrentContext(0); |
+} |
+ |
+// Note: cglContext_ lock must be held during this call. |
Ken Russell (switch to Gerrit)
2011/06/13 21:45:12
This comment applies to drawView too.
|
+- (void)ackSwapBuffers:(uint64)swapBuffersCount { |
+ if (swapBuffersCount > acknowledgedSwapBuffersCount_) { |
+ acknowledgedSwapBuffersCount_ = swapBuffersCount; |
+ bool sendAck = (rendererId_ != 0 || routeId_ != 0); |
+ if (sendAck && renderWidgetHostView_) { |
+ renderWidgetHostView_->AcknowledgeSwapBuffers( |
+ rendererId_, |
+ routeId_, |
+ gpuHostId_, |
+ acknowledgedSwapBuffersCount_); |
+ } |
+ } |
+} |
+ |
- (CVReturn)getFrameForTime:(const CVTimeStamp*)outputTime { |
+ TRACE_EVENT0("browser", "AcceleratedPluginView::getFrameForTime"); |
// There is no autorelease pool when this method is called because it will be |
// called from a background thread. |
base::mac::ScopedNSAutoreleasePool pool; |
- bool sendAck = (rendererId_ != 0 || routeId_ != 0); |
uint64 currentSwapBuffersCount = swapBuffersCount_; |
if (currentSwapBuffersCount == acknowledgedSwapBuffersCount_) { |
return kCVReturnSuccess; |
} |
+ // Called on a background thread. Synchronized via the CGL context lock. |
+ CGLLockContext(cglContext_); |
+ |
[self drawView]; |
+ [self ackSwapBuffers:currentSwapBuffersCount]; |
- acknowledgedSwapBuffersCount_ = currentSwapBuffersCount; |
- if (sendAck && renderWidgetHostView_) { |
- renderWidgetHostView_->AcknowledgeSwapBuffers( |
- rendererId_, |
- routeId_, |
- gpuHostId_, |
- acknowledgedSwapBuffersCount_); |
- } |
+ CGLUnlockContext(cglContext_); |
return kCVReturnSuccess; |
} |
@@ -93,35 +119,34 @@ static CVReturn DrawOneAcceleratedPluginCallback( |
// Set up a display link to do OpenGL rendering on a background thread. |
CVDisplayLinkCreateWithActiveCGDisplays(&displayLink_); |
+ CVDisplayLinkSetOutputCallback( |
+ displayLink_, &DrawOneAcceleratedPluginCallback, self); |
+ CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext( |
+ displayLink_, cglContext_, cglPixelFormat_); |
+ |
+ [[NSNotificationCenter defaultCenter] |
+ addObserver:self |
+ selector:@selector(globalFrameDidChange:) |
+ name:NSViewGlobalFrameDidChangeNotification |
+ object:self]; |
} |
return self; |
} |
- (void)dealloc { |
CVDisplayLinkRelease(displayLink_); |
+ |
+ // Ack pending swaps (if any): |
+ CGLLockContext(cglContext_); |
+ [self ackSwapBuffers:swapBuffersCount_]; |
+ CGLUnlockContext(cglContext_); |
+ |
if (renderWidgetHostView_) |
renderWidgetHostView_->DeallocFakePluginWindowHandle(pluginHandle_); |
[[NSNotificationCenter defaultCenter] removeObserver:self]; |
[super dealloc]; |
} |
-- (void)drawView { |
- TRACE_EVENT1("browser", "AcceleratedPluginViewMac::drawView", |
- "frameNum", swapBuffersCount_); |
- // Called on a background thread. Synchronized via the CGL context lock. |
- CGLLockContext(cglContext_); |
- |
- if (renderWidgetHostView_) { |
- // TODO(thakis): Pixel or view coordinates for size? |
- renderWidgetHostView_->DrawAcceleratedSurfaceInstance( |
- cglContext_, pluginHandle_, [self cachedSize]); |
- } |
- |
- CGLFlushDrawable(cglContext_); |
- CGLSetCurrentContext(0); |
- CGLUnlockContext(cglContext_); |
-} |
- |
- (void)setCutoutRects:(NSArray*)cutout_rects { |
cutoutRects_.reset([cutout_rects copy]); |
} |
@@ -141,6 +166,15 @@ static CVReturn DrawOneAcceleratedPluginCallback( |
gpuHostId_ = gpuHostId; |
swapBuffersCount_ = count; |
} |
+ // If this view is not visible, we have to ack now. Otherwise, |
+ // the ack will not be sent until the tab is made visible, which means it will |
+ // look like the tab is loading (busy cursor) until it is clicked. |
+ if (![self window]) { |
+ // Ack pending swaps (if any): |
+ CGLLockContext(cglContext_); |
+ [self ackSwapBuffers:swapBuffersCount_]; |
+ CGLUnlockContext(cglContext_); |
+ } |
} |
- (void)onRenderWidgetHostViewGone { |
@@ -148,6 +182,8 @@ static CVReturn DrawOneAcceleratedPluginCallback( |
return; |
CGLLockContext(cglContext_); |
+ // Ack pending swaps (if any): |
+ [self ackSwapBuffers:swapBuffersCount_]; |
// Deallocate the plugin handle while we still can. |
renderWidgetHostView_->DeallocFakePluginWindowHandle(pluginHandle_); |
renderWidgetHostView_ = NULL; |
@@ -155,6 +191,7 @@ static CVReturn DrawOneAcceleratedPluginCallback( |
} |
- (void)drawRect:(NSRect)rect { |
+ TRACE_EVENT0("browser", "AcceleratedPluginView::drawRect"); |
const NSRect* dirtyRects; |
int dirtyRectCount; |
[self getRectsBeingDrawn:&dirtyRects count:&dirtyRectCount]; |
@@ -190,7 +227,9 @@ static CVReturn DrawOneAcceleratedPluginCallback( |
NSRectFillList(dirtyRects, dirtyRectCount); |
} |
+ CGLLockContext(cglContext_); |
[self drawView]; |
+ CGLUnlockContext(cglContext_); |
} |
- (void)rightMouseDown:(NSEvent*)event { |
@@ -225,43 +264,52 @@ static CVReturn DrawOneAcceleratedPluginCallback( |
} |
} |
+- (void)prepareForGLRendering { |
+ TRACE_EVENT0("browser", "AcceleratedPluginView::prepareForGLRendering"); |
+ |
+ // If we're using OpenGL, make sure it is connected. |
+ if ([glContext_ view] != self) { |
+ [glContext_ setView:self]; |
+ } |
+} |
+ |
- (void)renewGState { |
+ TRACE_EVENT0("browser", "AcceleratedPluginView::renewGState"); |
// Synchronize with window server to avoid flashes or corrupt drawing. |
[[self window] disableScreenUpdatesUntilFlush]; |
[self globalFrameDidChange:nil]; |
[super renewGState]; |
} |
+- (void)setUpGState { |
+ TRACE_EVENT0("browser", "AcceleratedPluginView::setUpGState"); |
+ [self prepareForGLRendering]; |
+} |
+ |
+// TODO(jbates): is lockFocus needed anymore? it seems redundant with |
+// setUpGState in traces. |
- (void)lockFocus { |
+ TRACE_EVENT0("browser", "AcceleratedPluginView::lockFocus"); |
[super lockFocus]; |
- |
- // If we're using OpenGL, make sure it is connected and that the display link |
- // is running. |
- if ([glContext_ view] != self) { |
- [glContext_ setView:self]; |
- |
- [[NSNotificationCenter defaultCenter] |
- addObserver:self |
- selector:@selector(globalFrameDidChange:) |
- name:NSViewGlobalFrameDidChangeNotification |
- object:self]; |
- CVDisplayLinkSetOutputCallback( |
- displayLink_, &DrawOneAcceleratedPluginCallback, self); |
- CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext( |
- displayLink_, cglContext_, cglPixelFormat_); |
- CVDisplayLinkStart(displayLink_); |
- } |
+ [self prepareForGLRendering]; |
[glContext_ makeCurrentContext]; |
} |
- (void)viewWillMoveToWindow:(NSWindow*)newWindow { |
+ TRACE_EVENT1("browser", "AcceleratedPluginView::viewWillMoveToWindow", |
+ "newWindow", newWindow); |
// Stop the display link thread while the view is not visible. |
if (newWindow) { |
- if (displayLink_ && !CVDisplayLinkIsRunning(displayLink_)) |
+ if (!CVDisplayLinkIsRunning(displayLink_)) |
CVDisplayLinkStart(displayLink_); |
} else { |
- if (displayLink_ && CVDisplayLinkIsRunning(displayLink_)) |
+ if (CVDisplayLinkIsRunning(displayLink_)) |
CVDisplayLinkStop(displayLink_); |
+ |
+ // Ack pending swaps (if any): |
+ CGLLockContext(cglContext_); |
+ [self ackSwapBuffers:swapBuffersCount_]; |
+ CGLUnlockContext(cglContext_); |
} |
// Inform the window hosting this accelerated view that it needs to be |
@@ -275,6 +323,7 @@ static CVReturn DrawOneAcceleratedPluginCallback( |
} |
- (void)viewDidHide { |
+ TRACE_EVENT0("browser", "AcceleratedPluginView::viewDidHide"); |
[super viewDidHide]; |
if ([[self window] respondsToSelector:@selector(underlaySurfaceRemoved)]) { |
@@ -283,6 +332,7 @@ static CVReturn DrawOneAcceleratedPluginCallback( |
} |
- (void)viewDidUnhide { |
+ TRACE_EVENT0("browser", "AcceleratedPluginView::viewDidUnhide"); |
[super viewDidUnhide]; |
if ([[self window] respondsToSelector:@selector(underlaySurfaceRemoved)]) { |
@@ -297,6 +347,7 @@ static CVReturn DrawOneAcceleratedPluginCallback( |
} |
- (void)setFrameSize:(NSSize)newSize { |
+ TRACE_EVENT0("browser", "AcceleratedPluginView::newSize"); |
[self setCachedSize:newSize]; |
[super setFrameSize:newSize]; |
} |
@@ -316,6 +367,7 @@ static CVReturn DrawOneAcceleratedPluginCallback( |
} |
- (void)viewDidMoveToSuperview { |
+ TRACE_EVENT0("browser", "AcceleratedPluginView::viewDidMoveToSuperview"); |
if (![self superview]) |
[self onRenderWidgetHostViewGone]; |
} |