Chromium Code Reviews| 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]; |
| } |