OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #include "content/browser/renderer_host/render_widget_host_view_mac.h" | 5 #include "content/browser/renderer_host/render_widget_host_view_mac.h" |
6 | 6 |
7 #import <objc/runtime.h> | 7 #import <objc/runtime.h> |
8 #include <QuartzCore/QuartzCore.h> | 8 #include <QuartzCore/QuartzCore.h> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/callback_helpers.h" | 12 #include "base/callback_helpers.h" |
13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
14 #include "base/debug/crash_logging.h" | 14 #include "base/debug/crash_logging.h" |
15 #include "base/debug/trace_event.h" | 15 #include "base/debug/trace_event.h" |
16 #include "base/logging.h" | 16 #include "base/logging.h" |
17 #include "base/mac/mac_util.h" | 17 #include "base/mac/mac_util.h" |
18 #include "base/mac/scoped_cftyperef.h" | 18 #include "base/mac/scoped_cftyperef.h" |
19 #import "base/mac/scoped_nsobject.h" | 19 #import "base/mac/scoped_nsobject.h" |
20 #include "base/mac/sdk_forward_declarations.h" | 20 #include "base/mac/sdk_forward_declarations.h" |
21 #include "base/message_loop/message_loop.h" | 21 #include "base/message_loop/message_loop.h" |
22 #include "base/metrics/histogram.h" | 22 #include "base/metrics/histogram.h" |
23 #include "base/strings/string_util.h" | 23 #include "base/strings/string_util.h" |
24 #include "base/strings/stringprintf.h" | 24 #include "base/strings/stringprintf.h" |
25 #include "base/strings/sys_string_conversions.h" | 25 #include "base/strings/sys_string_conversions.h" |
26 #include "base/strings/utf_string_conversions.h" | 26 #include "base/strings/utf_string_conversions.h" |
27 #include "base/sys_info.h" | 27 #include "base/sys_info.h" |
28 #import "content/browser/accessibility/browser_accessibility_cocoa.h" | 28 #import "content/browser/accessibility/browser_accessibility_cocoa.h" |
29 #include "content/browser/accessibility/browser_accessibility_manager_mac.h" | 29 #include "content/browser/accessibility/browser_accessibility_manager_mac.h" |
30 #include "content/browser/compositor/resize_lock.h" | |
30 #include "content/browser/frame_host/frame_tree.h" | 31 #include "content/browser/frame_host/frame_tree.h" |
31 #include "content/browser/frame_host/frame_tree_node.h" | 32 #include "content/browser/frame_host/frame_tree_node.h" |
32 #include "content/browser/frame_host/render_frame_host_impl.h" | 33 #include "content/browser/frame_host/render_frame_host_impl.h" |
34 #include "content/browser/gpu/gpu_process_host.h" | |
35 #include "content/browser/gpu/gpu_surface_tracker.h" | |
33 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h" | 36 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h" |
34 #include "content/browser/renderer_host/compositing_iosurface_layer_mac.h" | 37 #include "content/browser/renderer_host/compositing_iosurface_layer_mac.h" |
35 #include "content/browser/renderer_host/compositing_iosurface_mac.h" | 38 #include "content/browser/renderer_host/compositing_iosurface_mac.h" |
39 #include "content/browser/renderer_host/render_widget_helper.h" | |
36 #include "content/browser/renderer_host/render_view_host_impl.h" | 40 #include "content/browser/renderer_host/render_view_host_impl.h" |
37 #import "content/browser/renderer_host/render_widget_host_view_mac_dictionary_he lper.h" | 41 #import "content/browser/renderer_host/render_widget_host_view_mac_dictionary_he lper.h" |
38 #import "content/browser/renderer_host/render_widget_host_view_mac_editcommand_h elper.h" | 42 #import "content/browser/renderer_host/render_widget_host_view_mac_editcommand_h elper.h" |
39 #import "content/browser/renderer_host/text_input_client_mac.h" | 43 #import "content/browser/renderer_host/text_input_client_mac.h" |
40 #include "content/common/accessibility_messages.h" | 44 #include "content/common/accessibility_messages.h" |
41 #include "content/common/edit_command.h" | 45 #include "content/common/edit_command.h" |
42 #include "content/common/gpu/gpu_messages.h" | 46 #include "content/common/gpu/gpu_messages.h" |
43 #include "content/common/input_messages.h" | 47 #include "content/common/input_messages.h" |
44 #include "content/common/view_messages.h" | 48 #include "content/common/view_messages.h" |
45 #include "content/common/webplugin_geometry.h" | 49 #include "content/common/webplugin_geometry.h" |
46 #include "content/port/browser/render_widget_host_view_frame_subscriber.h" | 50 #include "content/port/browser/render_widget_host_view_frame_subscriber.h" |
47 #include "content/public/browser/browser_thread.h" | 51 #include "content/public/browser/browser_thread.h" |
48 #include "content/public/browser/native_web_keyboard_event.h" | 52 #include "content/public/browser/native_web_keyboard_event.h" |
49 #include "content/public/browser/notification_service.h" | 53 #include "content/public/browser/notification_service.h" |
50 #include "content/public/browser/notification_types.h" | 54 #include "content/public/browser/notification_types.h" |
51 #import "content/public/browser/render_widget_host_view_mac_delegate.h" | 55 #import "content/public/browser/render_widget_host_view_mac_delegate.h" |
52 #include "content/public/browser/user_metrics.h" | 56 #include "content/public/browser/user_metrics.h" |
53 #include "content/public/browser/web_contents.h" | 57 #include "content/public/browser/web_contents.h" |
54 #include "skia/ext/platform_canvas.h" | 58 #include "skia/ext/platform_canvas.h" |
55 #include "third_party/WebKit/public/platform/WebScreenInfo.h" | 59 #include "third_party/WebKit/public/platform/WebScreenInfo.h" |
56 #include "third_party/WebKit/public/web/WebInputEvent.h" | 60 #include "third_party/WebKit/public/web/WebInputEvent.h" |
57 #include "third_party/WebKit/public/web/mac/WebInputEventFactory.h" | 61 #include "third_party/WebKit/public/web/mac/WebInputEventFactory.h" |
58 #import "third_party/mozilla/ComplexTextInputPanel.h" | 62 #import "third_party/mozilla/ComplexTextInputPanel.h" |
59 #include "ui/base/cocoa/animation_utils.h" | 63 #include "ui/base/cocoa/animation_utils.h" |
60 #import "ui/base/cocoa/fullscreen_window_manager.h" | 64 #import "ui/base/cocoa/fullscreen_window_manager.h" |
61 #import "ui/base/cocoa/underlay_opengl_hosting_window.h" | 65 #import "ui/base/cocoa/underlay_opengl_hosting_window.h" |
62 #include "ui/events/keycodes/keyboard_codes.h" | 66 #include "ui/events/keycodes/keyboard_codes.h" |
63 #include "ui/base/layout.h" | 67 #include "ui/base/layout.h" |
68 #include "ui/compositor/compositor.h" | |
69 #include "ui/compositor/layer.h" | |
64 #include "ui/gfx/display.h" | 70 #include "ui/gfx/display.h" |
65 #include "ui/gfx/point.h" | 71 #include "ui/gfx/point.h" |
66 #include "ui/gfx/rect_conversions.h" | 72 #include "ui/gfx/rect_conversions.h" |
67 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" | 73 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" |
68 #include "ui/gfx/screen.h" | 74 #include "ui/gfx/screen.h" |
69 #include "ui/gfx/size_conversions.h" | 75 #include "ui/gfx/size_conversions.h" |
70 #include "ui/gl/gl_switches.h" | 76 #include "ui/gl/gl_switches.h" |
71 #include "ui/gl/io_surface_support_mac.h" | 77 #include "ui/gl/io_surface_support_mac.h" |
72 | 78 |
73 using content::BrowserAccessibility; | 79 using content::BrowserAccessibility; |
(...skipping 27 matching lines...) Expand all Loading... | |
101 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 | 107 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 |
102 @interface NSView (NSOpenGLSurfaceResolutionLionAPI) | 108 @interface NSView (NSOpenGLSurfaceResolutionLionAPI) |
103 - (void)setWantsBestResolutionOpenGLSurface:(BOOL)flag; | 109 - (void)setWantsBestResolutionOpenGLSurface:(BOOL)flag; |
104 @end | 110 @end |
105 | 111 |
106 static NSString* const NSWindowDidChangeBackingPropertiesNotification = | 112 static NSString* const NSWindowDidChangeBackingPropertiesNotification = |
107 @"NSWindowDidChangeBackingPropertiesNotification"; | 113 @"NSWindowDidChangeBackingPropertiesNotification"; |
108 | 114 |
109 #endif // 10.7 | 115 #endif // 10.7 |
110 | 116 |
117 // Declare methods used to present swaps to this view. | |
118 @interface NSView (ContentCompositingView) | |
119 - (void)onNativeSurfaceBuffersSwappedWithParams: | |
120 (GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params)params; | |
121 @end | |
122 | |
123 @implementation NSView (ContentCompositingView) | |
124 - (void)onNativeSurfaceBuffersSwappedWithParams: | |
125 (GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params)params { | |
126 } | |
127 @end | |
128 | |
111 // This method will return YES for OS X versions 10.7.3 and later, and NO | 129 // This method will return YES for OS X versions 10.7.3 and later, and NO |
112 // otherwise. | 130 // otherwise. |
113 // Used to prevent a crash when building with the 10.7 SDK and accessing the | 131 // Used to prevent a crash when building with the 10.7 SDK and accessing the |
114 // notification below. See: http://crbug.com/260595. | 132 // notification below. See: http://crbug.com/260595. |
115 static BOOL SupportsBackingPropertiesChangedNotification() { | 133 static BOOL SupportsBackingPropertiesChangedNotification() { |
116 // windowDidChangeBackingProperties: method has been added to the | 134 // windowDidChangeBackingProperties: method has been added to the |
117 // NSWindowDelegate protocol in 10.7.3, at the same time as the | 135 // NSWindowDelegate protocol in 10.7.3, at the same time as the |
118 // NSWindowDidChangeBackingPropertiesNotification notification was added. | 136 // NSWindowDidChangeBackingPropertiesNotification notification was added. |
119 // If the protocol contains this method description, the notification should | 137 // If the protocol contains this method description, the notification should |
120 // be supported as well. | 138 // be supported as well. |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
243 [NSNotificationCenter defaultCenter]; | 261 [NSNotificationCenter defaultCenter]; |
244 [notificationCenter removeObserver:self | 262 [notificationCenter removeObserver:self |
245 name:NSMenuDidBeginTrackingNotification | 263 name:NSMenuDidBeginTrackingNotification |
246 object:[NSApp mainMenu]]; | 264 object:[NSApp mainMenu]]; |
247 } | 265 } |
248 | 266 |
249 @end | 267 @end |
250 | 268 |
251 namespace { | 269 namespace { |
252 | 270 |
271 // Class used to manage the lifetime of the UI compositor. | |
272 class CompositorInitializer { | |
273 public: | |
274 CompositorInitializer() { | |
275 ui::Compositor::Initialize(); | |
276 } | |
277 ~CompositorInitializer() { | |
278 ui::Compositor::Terminate(); | |
279 } | |
280 }; | |
281 | |
253 // Maximum number of characters we allow in a tooltip. | 282 // Maximum number of characters we allow in a tooltip. |
254 const size_t kMaxTooltipLength = 1024; | 283 const size_t kMaxTooltipLength = 1024; |
255 | 284 |
256 // TODO(suzhe): Upstream this function. | 285 // TODO(suzhe): Upstream this function. |
257 blink::WebColor WebColorFromNSColor(NSColor *color) { | 286 blink::WebColor WebColorFromNSColor(NSColor *color) { |
258 CGFloat r, g, b, a; | 287 CGFloat r, g, b, a; |
259 [color getRed:&r green:&g blue:&b alpha:&a]; | 288 [color getRed:&r green:&g blue:&b alpha:&a]; |
260 | 289 |
261 return | 290 return |
262 std::max(0, std::min(static_cast<int>(lroundf(255.0f * a)), 255)) << 24 | | 291 std::max(0, std::min(static_cast<int>(lroundf(255.0f * a)), 255)) << 24 | |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
386 // Disable the fade-out animation as the layer is removed. | 415 // Disable the fade-out animation as the layer is removed. |
387 ScopedCAActionDisabler disabler; | 416 ScopedCAActionDisabler disabler; |
388 [layer removeFromSuperlayer]; | 417 [layer removeFromSuperlayer]; |
389 } | 418 } |
390 | 419 |
391 } // namespace | 420 } // namespace |
392 | 421 |
393 namespace content { | 422 namespace content { |
394 | 423 |
395 /////////////////////////////////////////////////////////////////////////////// | 424 /////////////////////////////////////////////////////////////////////////////// |
425 // RenderWidgetHelper, public: | |
426 | |
427 void RenderWidgetHelper::OnNativeSurfaceBuffersSwapped( | |
piman
2014/05/06 00:59:01
nit: move to render_widget_helper.cc
ccameron
2014/05/06 17:15:56
This need to (at some point), bottom out in Object
piman
2014/05/06 19:58:09
I guess render_widget_helper_mac.mm is probably th
ccameron
2014/05/06 20:39:00
Done.
| |
428 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params) { | |
429 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { | |
430 // Immediately acknowledge this frame on the IO thread instead of the UI | |
431 // thread. The UI thread will wait on the GPU process. If the UI thread | |
432 // were to be responsible for acking swaps, then there would be a cycle | |
433 // and a potential deadlock. | |
434 // TODO(ccameron): This immediate ack circumvents GPU back-pressure that | |
435 // is necessary to throttle renderers. Fix that. | |
436 // TODO(ccameron): It is possible that the IOSurface will be deleted or | |
437 // reused soon as it is acked. Take out a reference to the IOSurface here, | |
438 // to ensure the IOSurface does not disappear before routing to the UI | |
439 // thread. | |
440 GpuProcessHost* gpu_process_host = GpuProcessHost::Get( | |
441 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, | |
442 CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH); | |
piman
2014/05/06 00:59:01
This is coming from GpuProcessHost::OnAccelerated
ccameron
2014/05/06 17:15:56
Good idea. Done.
| |
443 if (gpu_process_host) { | |
444 AcceleratedSurfaceMsg_BufferPresented_Params ack_params; | |
445 ack_params.sync_point = 0; | |
446 ack_params.renderer_id = 0; | |
447 gpu_process_host->Send(new AcceleratedSurfaceMsg_BufferPresented( | |
448 params.route_id, ack_params)); | |
449 } | |
450 BrowserThread::PostTask( | |
451 BrowserThread::UI, | |
452 FROM_HERE, | |
453 base::Bind(&OnNativeSurfaceBuffersSwapped, params)); | |
454 return; | |
455 } | |
456 | |
457 gfx::AcceleratedWidget native_widget = | |
458 GpuSurfaceTracker::Get()->AcquireNativeWidget(params.surface_id); | |
piman
2014/05/06 00:59:01
Because of races, this could be kNullAcceleratedWi
ccameron
2014/05/06 17:15:56
Calling a method on a NULL object in Objective C i
piman
2014/05/06 19:58:09
Ok, thanks.
| |
459 [native_widget onNativeSurfaceBuffersSwappedWithParams:params]; | |
460 } | |
461 | |
462 //////////////////////////////////////////////////////////////////////////////// | |
463 // DelegatedFrameHost, public: | |
464 | |
465 ui::Compositor* RenderWidgetHostViewMac::GetCompositor() const { | |
466 return compositor_.get(); | |
467 } | |
468 | |
469 ui::Layer* RenderWidgetHostViewMac::GetLayer() { | |
470 return root_layer_.get(); | |
471 } | |
472 | |
473 RenderWidgetHostImpl* RenderWidgetHostViewMac::GetHost() { | |
474 return render_widget_host_; | |
475 } | |
476 | |
477 void RenderWidgetHostViewMac::SchedulePaintInRect( | |
478 const gfx::Rect& damage_rect_in_dip) { | |
479 compositor_->ScheduleFullRedraw(); | |
480 } | |
481 | |
482 bool RenderWidgetHostViewMac::IsVisible() { | |
483 return !render_widget_host_->is_hidden(); | |
484 } | |
485 | |
486 gfx::Size RenderWidgetHostViewMac::DesiredFrameSize() { | |
487 return GetViewBounds().size(); | |
488 } | |
489 | |
490 float RenderWidgetHostViewMac::CurrentDeviceScaleFactor() { | |
491 return ViewScaleFactor(); | |
492 } | |
493 | |
494 gfx::Size RenderWidgetHostViewMac::ConvertViewSizeToPixel( | |
495 const gfx::Size& size) { | |
496 return gfx::ToEnclosingRect(gfx::ScaleRect(gfx::Rect(size), | |
497 ViewScaleFactor())).size(); | |
498 } | |
499 | |
500 scoped_ptr<ResizeLock> RenderWidgetHostViewMac::CreateResizeLock( | |
501 bool defer_compositor_lock) { | |
502 NOTREACHED(); | |
503 ResizeLock* lock = NULL; | |
504 return scoped_ptr<ResizeLock>(lock); | |
505 } | |
506 | |
507 DelegatedFrameHost* RenderWidgetHostViewMac::GetDelegatedFrameHost() const { | |
508 return delegated_frame_host_.get(); | |
509 } | |
510 | |
511 /////////////////////////////////////////////////////////////////////////////// | |
396 // RenderWidgetHostViewBase, public: | 512 // RenderWidgetHostViewBase, public: |
397 | 513 |
398 // static | 514 // static |
399 void RenderWidgetHostViewBase::GetDefaultScreenInfo( | 515 void RenderWidgetHostViewBase::GetDefaultScreenInfo( |
400 blink::WebScreenInfo* results) { | 516 blink::WebScreenInfo* results) { |
401 *results = GetWebScreenInfo(NULL); | 517 *results = GetWebScreenInfo(NULL); |
402 } | 518 } |
403 | 519 |
404 /////////////////////////////////////////////////////////////////////////////// | 520 /////////////////////////////////////////////////////////////////////////////// |
405 // RenderWidgetHostViewMac, public: | 521 // RenderWidgetHostViewMac, public: |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
441 } | 557 } |
442 | 558 |
443 render_widget_host_->SetView(this); | 559 render_widget_host_->SetView(this); |
444 } | 560 } |
445 | 561 |
446 RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { | 562 RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { |
447 // This is being called from |cocoa_view_|'s destructor, so invalidate the | 563 // This is being called from |cocoa_view_|'s destructor, so invalidate the |
448 // pointer. | 564 // pointer. |
449 cocoa_view_ = nil; | 565 cocoa_view_ = nil; |
450 | 566 |
567 // Delete the delegated frame state. | |
568 delegated_frame_host_.reset(); | |
569 compositor_.reset(); | |
570 root_layer_.reset(); | |
571 | |
451 UnlockMouse(); | 572 UnlockMouse(); |
452 | 573 |
453 // Make sure that the layer doesn't reach into the now-invalid object. | 574 // Make sure that the layer doesn't reach into the now-invalid object. |
454 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); | 575 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); |
455 DestroySoftwareLayer(); | 576 DestroySoftwareLayer(); |
456 | 577 |
457 // We are owned by RenderWidgetHostViewCocoa, so if we go away before the | 578 // We are owned by RenderWidgetHostViewCocoa, so if we go away before the |
458 // RenderWidgetHost does we need to tell it not to hold a stale pointer to | 579 // RenderWidgetHost does we need to tell it not to hold a stale pointer to |
459 // us. | 580 // us. |
460 if (render_widget_host_) | 581 if (render_widget_host_) |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
788 } | 909 } |
789 | 910 |
790 void RenderWidgetHostViewMac::WasShown() { | 911 void RenderWidgetHostViewMac::WasShown() { |
791 if (!render_widget_host_->is_hidden()) | 912 if (!render_widget_host_->is_hidden()) |
792 return; | 913 return; |
793 | 914 |
794 if (web_contents_switch_paint_time_.is_null()) | 915 if (web_contents_switch_paint_time_.is_null()) |
795 web_contents_switch_paint_time_ = base::TimeTicks::Now(); | 916 web_contents_switch_paint_time_ = base::TimeTicks::Now(); |
796 render_widget_host_->WasShown(); | 917 render_widget_host_->WasShown(); |
797 software_frame_manager_->SetVisibility(true); | 918 software_frame_manager_->SetVisibility(true); |
919 if (delegated_frame_host_) | |
920 delegated_frame_host_->WasShown(); | |
798 | 921 |
799 // Call setNeedsDisplay before pausing for new frames to come in -- if any | 922 // Call setNeedsDisplay before pausing for new frames to come in -- if any |
800 // do, and are drawn, then the needsDisplay bit will be cleared. | 923 // do, and are drawn, then the needsDisplay bit will be cleared. |
801 [software_layer_ setNeedsDisplay]; | 924 [software_layer_ setNeedsDisplay]; |
802 [compositing_iosurface_layer_ setNeedsDisplay]; | 925 [compositing_iosurface_layer_ setNeedsDisplay]; |
803 PauseForPendingResizeOrRepaintsAndDraw(); | 926 PauseForPendingResizeOrRepaintsAndDraw(); |
804 | 927 |
805 // We're messing with the window, so do this to ensure no flashes. | 928 // We're messing with the window, so do this to ensure no flashes. |
806 if (!use_core_animation_) | 929 if (!use_core_animation_) |
807 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; | 930 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; |
808 } | 931 } |
809 | 932 |
810 void RenderWidgetHostViewMac::WasHidden() { | 933 void RenderWidgetHostViewMac::WasHidden() { |
811 if (render_widget_host_->is_hidden()) | 934 if (render_widget_host_->is_hidden()) |
812 return; | 935 return; |
813 | 936 |
814 // Any pending frames will not be displayed until this is shown again. Ack | 937 // Any pending frames will not be displayed until this is shown again. Ack |
815 // them now. | 938 // them now. |
816 SendPendingSwapAck(); | 939 SendPendingSwapAck(); |
817 | 940 |
818 // If we have a renderer, then inform it that we are being hidden so it can | 941 // If we have a renderer, then inform it that we are being hidden so it can |
819 // reduce its resource utilization. | 942 // reduce its resource utilization. |
820 render_widget_host_->WasHidden(); | 943 render_widget_host_->WasHidden(); |
821 software_frame_manager_->SetVisibility(false); | 944 software_frame_manager_->SetVisibility(false); |
945 if (delegated_frame_host_) | |
946 delegated_frame_host_->WasHidden(); | |
822 | 947 |
823 // There can be a transparent flash as this view is removed and the next is | 948 // There can be a transparent flash as this view is removed and the next is |
824 // added, because of OSX windowing races between displaying the contents of | 949 // added, because of OSX windowing races between displaying the contents of |
825 // the NSView and its corresponding OpenGL context. | 950 // the NSView and its corresponding OpenGL context. |
826 // disableScreenUpdatesUntilFlush prevents the transparent flash by avoiding | 951 // disableScreenUpdatesUntilFlush prevents the transparent flash by avoiding |
827 // screen updates until the next tab draws. | 952 // screen updates until the next tab draws. |
828 if (!use_core_animation_) | 953 if (!use_core_animation_) |
829 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; | 954 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; |
830 | 955 |
831 web_contents_switch_paint_time_ = base::TimeTicks(); | 956 web_contents_switch_paint_time_ = base::TimeTicks(); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
913 void RenderWidgetHostViewMac::Blur() { | 1038 void RenderWidgetHostViewMac::Blur() { |
914 UnlockMouse(); | 1039 UnlockMouse(); |
915 [[cocoa_view_ window] makeFirstResponder:nil]; | 1040 [[cocoa_view_ window] makeFirstResponder:nil]; |
916 } | 1041 } |
917 | 1042 |
918 bool RenderWidgetHostViewMac::HasFocus() const { | 1043 bool RenderWidgetHostViewMac::HasFocus() const { |
919 return [[cocoa_view_ window] firstResponder] == cocoa_view_; | 1044 return [[cocoa_view_ window] firstResponder] == cocoa_view_; |
920 } | 1045 } |
921 | 1046 |
922 bool RenderWidgetHostViewMac::IsSurfaceAvailableForCopy() const { | 1047 bool RenderWidgetHostViewMac::IsSurfaceAvailableForCopy() const { |
1048 if (delegated_frame_host_) | |
1049 return delegated_frame_host_->CanCopyToBitmap(); | |
1050 | |
923 return software_frame_manager_->HasCurrentFrame() || | 1051 return software_frame_manager_->HasCurrentFrame() || |
924 (compositing_iosurface_ && compositing_iosurface_->HasIOSurface()); | 1052 (compositing_iosurface_ && compositing_iosurface_->HasIOSurface()); |
925 } | 1053 } |
926 | 1054 |
927 void RenderWidgetHostViewMac::Show() { | 1055 void RenderWidgetHostViewMac::Show() { |
928 [cocoa_view_ setHidden:NO]; | 1056 [cocoa_view_ setHidden:NO]; |
929 | 1057 |
930 WasShown(); | 1058 WasShown(); |
931 } | 1059 } |
932 | 1060 |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1153 | 1281 |
1154 bool RenderWidgetHostViewMac::IsPopup() const { | 1282 bool RenderWidgetHostViewMac::IsPopup() const { |
1155 return popup_type_ != blink::WebPopupTypeNone; | 1283 return popup_type_ != blink::WebPopupTypeNone; |
1156 } | 1284 } |
1157 | 1285 |
1158 void RenderWidgetHostViewMac::CopyFromCompositingSurface( | 1286 void RenderWidgetHostViewMac::CopyFromCompositingSurface( |
1159 const gfx::Rect& src_subrect, | 1287 const gfx::Rect& src_subrect, |
1160 const gfx::Size& dst_size, | 1288 const gfx::Size& dst_size, |
1161 const base::Callback<void(bool, const SkBitmap&)>& callback, | 1289 const base::Callback<void(bool, const SkBitmap&)>& callback, |
1162 const SkBitmap::Config config) { | 1290 const SkBitmap::Config config) { |
1291 if (delegated_frame_host_) { | |
1292 delegated_frame_host_->CopyFromCompositingSurface( | |
1293 src_subrect, dst_size, callback, config); | |
1294 return; | |
1295 } | |
1296 | |
1163 if (config != SkBitmap::kARGB_8888_Config) { | 1297 if (config != SkBitmap::kARGB_8888_Config) { |
1164 NOTIMPLEMENTED(); | 1298 NOTIMPLEMENTED(); |
1165 callback.Run(false, SkBitmap()); | 1299 callback.Run(false, SkBitmap()); |
1166 } | 1300 } |
1167 base::ScopedClosureRunner scoped_callback_runner( | 1301 base::ScopedClosureRunner scoped_callback_runner( |
1168 base::Bind(callback, false, SkBitmap())); | 1302 base::Bind(callback, false, SkBitmap())); |
1169 float scale = ScaleFactorForView(cocoa_view_); | 1303 float scale = ScaleFactorForView(cocoa_view_); |
1170 gfx::Size dst_pixel_size = gfx::ToFlooredSize( | 1304 gfx::Size dst_pixel_size = gfx::ToFlooredSize( |
1171 gfx::ScaleSize(dst_size, scale)); | 1305 gfx::ScaleSize(dst_size, scale)); |
1172 if (compositing_iosurface_ && compositing_iosurface_->HasIOSurface()) { | 1306 if (compositing_iosurface_ && compositing_iosurface_->HasIOSurface()) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1210 | 1344 |
1211 ignore_result(scoped_callback_runner.Release()); | 1345 ignore_result(scoped_callback_runner.Release()); |
1212 callback.Run(true, target_bitmap); | 1346 callback.Run(true, target_bitmap); |
1213 } | 1347 } |
1214 } | 1348 } |
1215 | 1349 |
1216 void RenderWidgetHostViewMac::CopyFromCompositingSurfaceToVideoFrame( | 1350 void RenderWidgetHostViewMac::CopyFromCompositingSurfaceToVideoFrame( |
1217 const gfx::Rect& src_subrect, | 1351 const gfx::Rect& src_subrect, |
1218 const scoped_refptr<media::VideoFrame>& target, | 1352 const scoped_refptr<media::VideoFrame>& target, |
1219 const base::Callback<void(bool)>& callback) { | 1353 const base::Callback<void(bool)>& callback) { |
1354 if (delegated_frame_host_) { | |
1355 delegated_frame_host_->CopyFromCompositingSurfaceToVideoFrame( | |
1356 src_subrect, target, callback); | |
1357 return; | |
1358 } | |
1359 | |
1220 base::ScopedClosureRunner scoped_callback_runner(base::Bind(callback, false)); | 1360 base::ScopedClosureRunner scoped_callback_runner(base::Bind(callback, false)); |
1221 if (!render_widget_host_->is_accelerated_compositing_active() || | 1361 if (!render_widget_host_->is_accelerated_compositing_active() || |
1222 !compositing_iosurface_ || | 1362 !compositing_iosurface_ || |
1223 !compositing_iosurface_->HasIOSurface()) | 1363 !compositing_iosurface_->HasIOSurface()) |
1224 return; | 1364 return; |
1225 | 1365 |
1226 if (!target.get()) { | 1366 if (!target.get()) { |
1227 NOTREACHED(); | 1367 NOTREACHED(); |
1228 return; | 1368 return; |
1229 } | 1369 } |
1230 | 1370 |
1231 if (target->format() != media::VideoFrame::YV12 && | 1371 if (target->format() != media::VideoFrame::YV12 && |
1232 target->format() != media::VideoFrame::I420) { | 1372 target->format() != media::VideoFrame::I420) { |
1233 NOTREACHED(); | 1373 NOTREACHED(); |
1234 return; | 1374 return; |
1235 } | 1375 } |
1236 | 1376 |
1237 if (src_subrect.IsEmpty()) | 1377 if (src_subrect.IsEmpty()) |
1238 return; | 1378 return; |
1239 | 1379 |
1240 ignore_result(scoped_callback_runner.Release()); | 1380 ignore_result(scoped_callback_runner.Release()); |
1241 compositing_iosurface_->CopyToVideoFrame( | 1381 compositing_iosurface_->CopyToVideoFrame( |
1242 GetScaledOpenGLPixelRect(src_subrect), | 1382 GetScaledOpenGLPixelRect(src_subrect), |
1243 target, | 1383 target, |
1244 callback); | 1384 callback); |
1245 } | 1385 } |
1246 | 1386 |
1247 bool RenderWidgetHostViewMac::CanCopyToVideoFrame() const { | 1387 bool RenderWidgetHostViewMac::CanCopyToVideoFrame() const { |
1388 if (delegated_frame_host_) | |
1389 return delegated_frame_host_->CanCopyToVideoFrame(); | |
1390 | |
1248 return (!software_frame_manager_->HasCurrentFrame() && | 1391 return (!software_frame_manager_->HasCurrentFrame() && |
1249 render_widget_host_->is_accelerated_compositing_active() && | 1392 render_widget_host_->is_accelerated_compositing_active() && |
1250 compositing_iosurface_ && | 1393 compositing_iosurface_ && |
1251 compositing_iosurface_->HasIOSurface()); | 1394 compositing_iosurface_->HasIOSurface()); |
1252 } | 1395 } |
1253 | 1396 |
1254 bool RenderWidgetHostViewMac::CanSubscribeFrame() const { | 1397 bool RenderWidgetHostViewMac::CanSubscribeFrame() const { |
1398 if (delegated_frame_host_) | |
1399 return delegated_frame_host_->CanSubscribeFrame(); | |
1400 | |
1255 return !software_frame_manager_->HasCurrentFrame(); | 1401 return !software_frame_manager_->HasCurrentFrame(); |
1256 } | 1402 } |
1257 | 1403 |
1258 void RenderWidgetHostViewMac::BeginFrameSubscription( | 1404 void RenderWidgetHostViewMac::BeginFrameSubscription( |
1259 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) { | 1405 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) { |
1406 if (delegated_frame_host_) { | |
1407 delegated_frame_host_->BeginFrameSubscription(subscriber.Pass()); | |
1408 return; | |
1409 } | |
1260 frame_subscriber_ = subscriber.Pass(); | 1410 frame_subscriber_ = subscriber.Pass(); |
1261 } | 1411 } |
1262 | 1412 |
1263 void RenderWidgetHostViewMac::EndFrameSubscription() { | 1413 void RenderWidgetHostViewMac::EndFrameSubscription() { |
1414 if (delegated_frame_host_) { | |
1415 delegated_frame_host_->EndFrameSubscription(); | |
1416 return; | |
1417 } | |
1418 | |
1264 frame_subscriber_.reset(); | 1419 frame_subscriber_.reset(); |
1265 } | 1420 } |
1266 | 1421 |
1267 // Sets whether or not to accept first responder status. | 1422 // Sets whether or not to accept first responder status. |
1268 void RenderWidgetHostViewMac::SetTakesFocusOnlyOnMouseDown(bool flag) { | 1423 void RenderWidgetHostViewMac::SetTakesFocusOnlyOnMouseDown(bool flag) { |
1269 [cocoa_view_ setTakesFocusOnlyOnMouseDown:flag]; | 1424 [cocoa_view_ setTakesFocusOnlyOnMouseDown:flag]; |
1270 } | 1425 } |
1271 | 1426 |
1272 void RenderWidgetHostViewMac::ForwardMouseEvent(const WebMouseEvent& event) { | 1427 void RenderWidgetHostViewMac::ForwardMouseEvent(const WebMouseEvent& event) { |
1273 if (render_widget_host_) | 1428 if (render_widget_host_) |
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1771 return (software_frame_manager_->HasCurrentFrame() && | 1926 return (software_frame_manager_->HasCurrentFrame() && |
1772 (desired_size.IsEmpty() || | 1927 (desired_size.IsEmpty() || |
1773 software_frame_manager_->GetCurrentFrameSizeInDIP() == | 1928 software_frame_manager_->GetCurrentFrameSizeInDIP() == |
1774 desired_size)); | 1929 desired_size)); |
1775 } | 1930 } |
1776 return false; | 1931 return false; |
1777 } | 1932 } |
1778 | 1933 |
1779 void RenderWidgetHostViewMac::OnSwapCompositorFrame( | 1934 void RenderWidgetHostViewMac::OnSwapCompositorFrame( |
1780 uint32 output_surface_id, scoped_ptr<cc::CompositorFrame> frame) { | 1935 uint32 output_surface_id, scoped_ptr<cc::CompositorFrame> frame) { |
1781 // Only software compositor frames are accepted. | 1936 if (frame->delegated_frame_data) { |
1782 if (!frame->software_frame_data) { | 1937 // Initialize the global UI compositor once. |
1938 static base::LazyInstance<CompositorInitializer> | |
1939 compositor_initializer_; | |
piman
2014/05/06 00:59:01
Can we move this to BrowserMainLoop? That is where
ccameron
2014/05/06 17:15:56
Done.
| |
1940 ignore_result(compositor_initializer_.Get()); | |
1941 | |
1942 if (!compositor_) { | |
1943 compositor_.reset(new ui::Compositor(cocoa_view_)); | |
1944 root_layer_.reset(new ui::Layer(ui::LAYER_TEXTURED)); | |
1945 delegated_frame_host_.reset(new DelegatedFrameHost(this)); | |
1946 } | |
1947 | |
1948 delegated_frame_host_->SwapDelegatedFrame( | |
1949 output_surface_id, | |
1950 frame->delegated_frame_data.Pass(), | |
1951 frame->metadata.device_scale_factor, | |
1952 frame->metadata.latency_info); | |
1953 | |
1954 gfx::Size size = ToCeiledSize(frame->metadata.viewport_size); | |
1955 float scale_factor = frame->metadata.page_scale_factor; | |
1956 if (compositor_->size() != size || | |
1957 compositor_->device_scale_factor() != scale_factor) { | |
1958 compositor_->SetScaleAndSize(scale_factor, size); | |
1959 root_layer_->SetBounds(gfx::Rect(0, 0, size.width(), size.height())); | |
piman
2014/05/06 00:59:01
I think both of these should be done when the RWHV
ccameron
2014/05/06 17:15:56
I've found it best to resize everything to match t
piman
2014/05/06 19:58:09
What about the non-CA path?
I guess what you sugg
ccameron
2014/05/06 20:39:00
non-CA path will be deleted soon (grin).
| |
1960 } | |
1961 if (compositor_->root_layer() != root_layer_) | |
1962 compositor_->SetRootLayer(root_layer_.get()); | |
1963 } else if (frame->software_frame_data) { | |
1964 if (!software_frame_manager_->SwapToNewFrame( | |
1965 output_surface_id, | |
1966 frame->software_frame_data.get(), | |
1967 frame->metadata.device_scale_factor, | |
1968 render_widget_host_->GetProcess()->GetHandle())) { | |
1969 render_widget_host_->GetProcess()->ReceivedBadMessage(); | |
1970 return; | |
1971 } | |
1972 | |
1973 // Add latency info to report when the frame finishes drawing. | |
1974 AddPendingLatencyInfo(frame->metadata.latency_info); | |
piman
2014/05/06 00:59:01
you'll want to do this in either case.
ccameron
2014/05/06 17:15:56
The DelegatedFrameHost tracks the latency_info for
piman
2014/05/06 19:58:09
Ok.
| |
1975 GotSoftwareFrame(); | |
1976 | |
1977 cc::CompositorFrameAck ack; | |
1978 RenderWidgetHostImpl::SendSwapCompositorFrameAck( | |
1979 render_widget_host_->GetRoutingID(), | |
1980 software_frame_manager_->GetCurrentFrameOutputSurfaceId(), | |
1981 render_widget_host_->GetProcess()->GetID(), | |
1982 ack); | |
1983 software_frame_manager_->SwapToNewFrameComplete( | |
1984 !render_widget_host_->is_hidden()); | |
1985 | |
1986 // Notify observers, tab capture observers in particular, that a new | |
1987 // software frame has come in. | |
1988 NotificationService::current()->Notify( | |
1989 NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE, | |
1990 Source<RenderWidgetHost>(render_widget_host_), | |
1991 NotificationService::NoDetails()); | |
1992 } else { | |
1783 DLOG(ERROR) << "Received unexpected frame type."; | 1993 DLOG(ERROR) << "Received unexpected frame type."; |
1784 RecordAction( | 1994 RecordAction( |
1785 base::UserMetricsAction("BadMessageTerminate_UnexpectedFrameType")); | 1995 base::UserMetricsAction("BadMessageTerminate_UnexpectedFrameType")); |
1786 render_widget_host_->GetProcess()->ReceivedBadMessage(); | 1996 render_widget_host_->GetProcess()->ReceivedBadMessage(); |
1787 return; | |
1788 } | 1997 } |
1789 | |
1790 if (!software_frame_manager_->SwapToNewFrame( | |
1791 output_surface_id, | |
1792 frame->software_frame_data.get(), | |
1793 frame->metadata.device_scale_factor, | |
1794 render_widget_host_->GetProcess()->GetHandle())) { | |
1795 render_widget_host_->GetProcess()->ReceivedBadMessage(); | |
1796 return; | |
1797 } | |
1798 | |
1799 // Add latency info to report when the frame finishes drawing. | |
1800 AddPendingLatencyInfo(frame->metadata.latency_info); | |
1801 GotSoftwareFrame(); | |
1802 | |
1803 cc::CompositorFrameAck ack; | |
1804 RenderWidgetHostImpl::SendSwapCompositorFrameAck( | |
1805 render_widget_host_->GetRoutingID(), | |
1806 software_frame_manager_->GetCurrentFrameOutputSurfaceId(), | |
1807 render_widget_host_->GetProcess()->GetID(), | |
1808 ack); | |
1809 software_frame_manager_->SwapToNewFrameComplete( | |
1810 !render_widget_host_->is_hidden()); | |
1811 | |
1812 // Notify observers, tab capture observers in particular, that a new software | |
1813 // frame has come in. | |
1814 NotificationService::current()->Notify( | |
1815 NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE, | |
1816 Source<RenderWidgetHost>(render_widget_host_), | |
1817 NotificationService::NoDetails()); | |
1818 } | 1998 } |
1819 | 1999 |
1820 void RenderWidgetHostViewMac::OnAcceleratedCompositingStateChange() { | 2000 void RenderWidgetHostViewMac::OnAcceleratedCompositingStateChange() { |
1821 } | 2001 } |
1822 | 2002 |
1823 void RenderWidgetHostViewMac::AcceleratedSurfaceInitialized(int host_id, | 2003 void RenderWidgetHostViewMac::AcceleratedSurfaceInitialized(int host_id, |
1824 int route_id) { | 2004 int route_id) { |
1825 } | 2005 } |
1826 | 2006 |
1827 void RenderWidgetHostViewMac::GetScreenInfo(blink::WebScreenInfo* results) { | 2007 void RenderWidgetHostViewMac::GetScreenInfo(blink::WebScreenInfo* results) { |
(...skipping 1279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3107 if (!renderWidgetHostView_->render_widget_host_) | 3287 if (!renderWidgetHostView_->render_widget_host_) |
3108 return; | 3288 return; |
3109 | 3289 |
3110 // Move the CALayers to their positions in the new view size. Note that | 3290 // Move the CALayers to their positions in the new view size. Note that |
3111 // this will not draw anything because the non-background layers' sizes | 3291 // this will not draw anything because the non-background layers' sizes |
3112 // didn't actually change. | 3292 // didn't actually change. |
3113 renderWidgetHostView_->LayoutLayers(); | 3293 renderWidgetHostView_->LayoutLayers(); |
3114 | 3294 |
3115 renderWidgetHostView_->render_widget_host_->SendScreenRects(); | 3295 renderWidgetHostView_->render_widget_host_->SendScreenRects(); |
3116 renderWidgetHostView_->render_widget_host_->WasResized(); | 3296 renderWidgetHostView_->render_widget_host_->WasResized(); |
3297 if (renderWidgetHostView_->delegated_frame_host_) | |
3298 renderWidgetHostView_->delegated_frame_host_->WasResized(); | |
3117 | 3299 |
3118 // Wait for the frame that WasResize might have requested. If the view is | 3300 // Wait for the frame that WasResize might have requested. If the view is |
3119 // being made visible at a new size, then this call will have no effect | 3301 // being made visible at a new size, then this call will have no effect |
3120 // because the view widget is still hidden, and the pause call in WasShown | 3302 // because the view widget is still hidden, and the pause call in WasShown |
3121 // will have this effect for us. | 3303 // will have this effect for us. |
3122 renderWidgetHostView_->PauseForPendingResizeOrRepaintsAndDraw(); | 3304 renderWidgetHostView_->PauseForPendingResizeOrRepaintsAndDraw(); |
3123 } | 3305 } |
3124 | 3306 |
3125 // Fills with white the parts of the area to the right and bottom for |rect| | 3307 // Fills with white the parts of the area to the right and bottom for |rect| |
3126 // that intersect |damagedRect|. | 3308 // that intersect |damagedRect|. |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3166 height = -height; | 3348 height = -height; |
3167 } | 3349 } |
3168 | 3350 |
3169 NSRect r = [self flipRectToNSRect:gfx::Rect(x, y, width, height)]; | 3351 NSRect r = [self flipRectToNSRect:gfx::Rect(x, y, width, height)]; |
3170 CGContextSetFillColorWithColor(context, | 3352 CGContextSetFillColorWithColor(context, |
3171 CGColorGetConstantColor(kCGColorWhite)); | 3353 CGColorGetConstantColor(kCGColorWhite)); |
3172 CGContextFillRect(context, NSRectToCGRect(r)); | 3354 CGContextFillRect(context, NSRectToCGRect(r)); |
3173 } | 3355 } |
3174 } | 3356 } |
3175 | 3357 |
3358 - (void)onNativeSurfaceBuffersSwappedWithParams: | |
3359 (GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params)params { | |
3360 | |
3361 renderWidgetHostView_->CompositorSwapBuffers( | |
3362 params.surface_handle, | |
3363 params.size, | |
3364 params.scale_factor, | |
3365 params.latency_info); | |
3366 } | |
3367 | |
3176 - (void)drawRect:(NSRect)dirtyRect { | 3368 - (void)drawRect:(NSRect)dirtyRect { |
3177 TRACE_EVENT0("browser", "RenderWidgetHostViewCocoa::drawRect"); | 3369 TRACE_EVENT0("browser", "RenderWidgetHostViewCocoa::drawRect"); |
3178 DCHECK(!renderWidgetHostView_->use_core_animation_); | 3370 DCHECK(!renderWidgetHostView_->use_core_animation_); |
3179 | 3371 |
3180 if (!renderWidgetHostView_->render_widget_host_) { | 3372 if (!renderWidgetHostView_->render_widget_host_) { |
3181 // When using CoreAnimation, this path is used to paint the contents area | 3373 // When using CoreAnimation, this path is used to paint the contents area |
3182 // white before any frames come in. When layers to draw frames exist, this | 3374 // white before any frames come in. When layers to draw frames exist, this |
3183 // is not hit. | 3375 // is not hit. |
3184 [[NSColor whiteColor] set]; | 3376 [[NSColor whiteColor] set]; |
3185 NSRectFill(dirtyRect); | 3377 NSRectFill(dirtyRect); |
(...skipping 1093 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4279 } | 4471 } |
4280 | 4472 |
4281 - (void)disableRendering { | 4473 - (void)disableRendering { |
4282 // Disable the fade-out animation as the layer is removed. | 4474 // Disable the fade-out animation as the layer is removed. |
4283 ScopedCAActionDisabler disabler; | 4475 ScopedCAActionDisabler disabler; |
4284 [self removeFromSuperlayer]; | 4476 [self removeFromSuperlayer]; |
4285 renderWidgetHostView_ = nil; | 4477 renderWidgetHostView_ = nil; |
4286 } | 4478 } |
4287 | 4479 |
4288 @end // implementation SoftwareLayer | 4480 @end // implementation SoftwareLayer |
OLD | NEW |