Index: content/browser/renderer_host/render_widget_host_view_mac.mm |
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm |
index 89cd97c42e90acc0b2b13d3cae6eeff9c2ba0b87..1af40343dc8b290dcde0eb1ff491761b87335100 100644 |
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm |
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm |
@@ -24,6 +24,7 @@ |
#include "content/browser/plugin_process_host.h" |
#import "content/browser/renderer_host/accelerated_plugin_view_mac.h" |
#include "content/browser/renderer_host/backing_store_mac.h" |
+#include "content/browser/renderer_host/backing_store_manager.h" |
#include "content/browser/renderer_host/compositing_iosurface_mac.h" |
#include "content/browser/renderer_host/render_process_host_impl.h" |
#include "content/browser/renderer_host/render_view_host_impl.h" |
@@ -263,8 +264,7 @@ RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) |
can_compose_inline_(true), |
is_loading_(false), |
is_hidden_(false), |
- weak_factory_(this), |
- compositing_surface_(gfx::kNullPluginWindow) { |
+ weak_factory_(this) { |
// |cocoa_view_| owns us and we will be deleted when |cocoa_view_| |
// goes away. Since we autorelease it, our caller must put |
// |GetNativeView()| into the view hierarchy right after calling us. |
@@ -961,7 +961,12 @@ void RenderWidgetHostViewMac::CompositorSwapBuffers(uint64 surface_handle, |
if (compositing_iosurface_.get() && !is_hidden_) { |
last_frame_was_accelerated_ = true; |
compositing_iosurface_->SetIOSurface(surface_handle); |
- [cocoa_view_ setNeedsDisplay:YES]; |
+ // No need for presenting if we're already in a drawRect (it will be done |
+ // later). |
+ if (!about_to_validate_and_paint_) { |
+ compositing_iosurface_->DrawIOSurface(cocoa_view_); |
+ AckPendingCompositorSwapBuffers(); |
+ } |
} else { |
AckPendingCompositorSwapBuffers(); |
} |
@@ -987,7 +992,9 @@ void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped( |
"RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped"); |
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- if (params.window == compositing_surface_) { |
+ // Compositor window is always gfx::kNullPluginWindow. |
+ // TODO(jbates) This will be removed when there are no plugin windows. |
+ if (params.window == gfx::kNullPluginWindow) { |
CompositorSwapBuffers(params.surface_handle, params.route_id, gpu_host_id); |
} else { |
// Deprecated accelerated plugin code path. |
@@ -1017,7 +1024,9 @@ void RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer( |
"RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer"); |
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- if (params.window == compositing_surface_) { |
+ // Compositor window is always gfx::kNullPluginWindow. |
+ // TODO(jbates) This will be removed when there are no plugin windows. |
+ if (params.window == gfx::kNullPluginWindow) { |
CompositorSwapBuffers(params.surface_handle, params.route_id, gpu_host_id); |
} else { |
// Deprecated accelerated plugin code path. |
@@ -1043,6 +1052,23 @@ void RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer( |
} |
void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() { |
+ if (compositing_iosurface_.get()) |
+ compositing_iosurface_->UnrefIOSurface(); |
+} |
+ |
+bool RenderWidgetHostViewMac::HasAcceleratedSurface( |
+ const gfx::Size& desired_size) { |
+ return last_frame_was_accelerated_ && |
+ compositing_iosurface_.get() && |
+ compositing_iosurface_->HasIOSurface() && |
+ (desired_size.IsEmpty() || |
+ compositing_iosurface_->io_surface_size() == desired_size); |
+} |
+ |
+void RenderWidgetHostViewMac::AboutToWaitForUpdateMsg() { |
+ // We want to get a fresh frame from the renderer, so ack any pending swaps to |
+ // allow the renderer to produce new frames. |
+ AckPendingCompositorSwapBuffers(); |
} |
void RenderWidgetHostViewMac::OnAcceleratedCompositingStateChange() { |
@@ -1065,8 +1091,9 @@ gfx::Rect RenderWidgetHostViewMac::GetRootWindowBounds() { |
} |
gfx::GLSurfaceHandle RenderWidgetHostViewMac::GetCompositingSurface() { |
- // compositing_surface_ is always gfx::kNullPluginWindow. |
- return gfx::GLSurfaceHandle(compositing_surface_, true); |
+ // Compositor window is always gfx::kNullPluginWindow. |
+ // TODO(jbates) This will be removed when there are no plugin windows. |
+ return gfx::GLSurfaceHandle(gfx::kNullPluginWindow, true); |
} |
void RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstance( |
@@ -1357,6 +1384,7 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) { |
} |
- (void)mouseEvent:(NSEvent*)theEvent { |
+ TRACE_EVENT0("browser", "RenderWidgetHostViewCocoa::mouseEvent"); |
if (delegate_ && [delegate_ respondsToSelector:@selector(handleEvent:)]) { |
BOOL handled = [delegate_ handleEvent:theEvent]; |
if (handled) |
@@ -1518,6 +1546,7 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) { |
} |
- (void)keyEvent:(NSEvent*)theEvent wasKeyEquivalent:(BOOL)equiv { |
+ TRACE_EVENT0("browser", "RenderWidgetHostViewCocoa::keyEvent"); |
DCHECK([theEvent type] != NSKeyDown || |
!equiv == !([theEvent modifierFlags] & NSCommandKeyMask)); |
@@ -1843,6 +1872,7 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) { |
} |
- (void)drawRect:(NSRect)dirtyRect { |
+ TRACE_EVENT0("browser", "RenderWidgetHostViewCocoa::drawRect"); |
if (!renderWidgetHostView_->render_widget_host_) { |
// TODO(shess): Consider using something more noticable? |
[[NSColor whiteColor] set]; |
@@ -1850,30 +1880,46 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) { |
return; |
} |
+ DCHECK(!renderWidgetHostView_->about_to_validate_and_paint_); |
+ |
+ // GetBackingStore works for both software and accelerated frames. If a |
+ // SwapBuffers occurs while GetBackingStore is blocking, we will continue to |
+ // blit the IOSurface below. |
+ renderWidgetHostView_->about_to_validate_and_paint_ = true; |
+ BackingStoreMac* backingStore = static_cast<BackingStoreMac*>( |
+ renderWidgetHostView_->render_widget_host_->GetBackingStore(true)); |
+ renderWidgetHostView_->about_to_validate_and_paint_ = false; |
+ |
const gfx::Rect damagedRect([self flipNSRectToRect:dirtyRect]); |
if (renderWidgetHostView_->last_frame_was_accelerated_) { |
- // Draw transparency to expose the GL underlay: |
- // TODO(jbates) avoid doing this every frame. |
- [[NSColor clearColor] set]; |
- NSRectFill(dirtyRect); |
+ // Delete software backingstore. |
+ // TODO(jbates) Only do this on first GPU frame after software frame. |
+ BackingStoreManager::RemoveBackingStore( |
+ renderWidgetHostView_->render_widget_host_); |
+ |
+ { |
+ TRACE_EVENT0("browser", "NSRectFill"); |
+ // Draw transparency to expose the GL underlay: |
+ // TODO(jbates) avoid doing this every frame. |
+ [[NSColor clearColor] set]; |
+ NSRectFill(dirtyRect); |
+ } |
renderWidgetHostView_->compositing_iosurface_->DrawIOSurface(self); |
renderWidgetHostView_->AckPendingCompositorSwapBuffers(); |
return; |
} |
+ // Forget IOSurface since we are drawing a software frame now. |
+ if (renderWidgetHostView_->compositing_iosurface_.get() && |
+ renderWidgetHostView_->compositing_iosurface_->HasIOSurface()) |
+ renderWidgetHostView_->compositing_iosurface_->UnrefIOSurface(); |
+ |
// In case the last frame was accelerated, ack any pending swaps to unblock |
// the GPU process. |
renderWidgetHostView_->AckPendingCompositorSwapBuffers(); |
- DCHECK(!renderWidgetHostView_->about_to_validate_and_paint_); |
- |
- renderWidgetHostView_->about_to_validate_and_paint_ = true; |
- BackingStoreMac* backingStore = static_cast<BackingStoreMac*>( |
- renderWidgetHostView_->render_widget_host_->GetBackingStore(true)); |
- renderWidgetHostView_->about_to_validate_and_paint_ = false; |
- |
if (backingStore) { |
gfx::Rect bitmapRect(0, 0, |
backingStore->size().width(), |