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 <OpenGL/gl.h> | 8 #include <OpenGL/gl.h> |
9 #include <QuartzCore/QuartzCore.h> | 9 #include <QuartzCore/QuartzCore.h> |
10 | 10 |
11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/callback_helpers.h" | 13 #include "base/callback_helpers.h" |
14 #include "base/command_line.h" | 14 #include "base/command_line.h" |
15 #include "base/debug/crash_logging.h" | 15 #include "base/debug/crash_logging.h" |
16 #include "base/debug/trace_event.h" | 16 #include "base/debug/trace_event.h" |
17 #include "base/logging.h" | 17 #include "base/logging.h" |
18 #include "base/mac/mac_util.h" | 18 #include "base/mac/mac_util.h" |
19 #include "base/mac/scoped_cftyperef.h" | 19 #include "base/mac/scoped_cftyperef.h" |
20 #import "base/mac/scoped_nsobject.h" | 20 #import "base/mac/scoped_nsobject.h" |
21 #include "base/mac/sdk_forward_declarations.h" | 21 #include "base/mac/sdk_forward_declarations.h" |
22 #include "base/message_loop/message_loop.h" | 22 #include "base/message_loop/message_loop.h" |
23 #include "base/metrics/histogram.h" | 23 #include "base/metrics/histogram.h" |
24 #include "base/strings/string_util.h" | 24 #include "base/strings/string_util.h" |
25 #include "base/strings/stringprintf.h" | 25 #include "base/strings/stringprintf.h" |
26 #include "base/strings/sys_string_conversions.h" | 26 #include "base/strings/sys_string_conversions.h" |
27 #include "base/strings/utf_string_conversions.h" | 27 #include "base/strings/utf_string_conversions.h" |
28 #include "base/sys_info.h" | 28 #include "base/sys_info.h" |
| 29 #include "cc/base/switches.h" |
29 #import "content/browser/accessibility/browser_accessibility_cocoa.h" | 30 #import "content/browser/accessibility/browser_accessibility_cocoa.h" |
30 #include "content/browser/accessibility/browser_accessibility_manager_mac.h" | 31 #include "content/browser/accessibility/browser_accessibility_manager_mac.h" |
31 #import "content/browser/cocoa/system_hotkey_helper_mac.h" | 32 #import "content/browser/cocoa/system_hotkey_helper_mac.h" |
32 #import "content/browser/cocoa/system_hotkey_map.h" | 33 #import "content/browser/cocoa/system_hotkey_map.h" |
33 #include "content/browser/compositor/resize_lock.h" | 34 #include "content/browser/compositor/resize_lock.h" |
34 #include "content/browser/frame_host/frame_tree.h" | 35 #include "content/browser/frame_host/frame_tree.h" |
35 #include "content/browser/frame_host/frame_tree_node.h" | 36 #include "content/browser/frame_host/frame_tree_node.h" |
36 #include "content/browser/frame_host/render_frame_host_impl.h" | 37 #include "content/browser/frame_host/render_frame_host_impl.h" |
37 #include "content/browser/gpu/compositor_util.h" | 38 #include "content/browser/gpu/compositor_util.h" |
38 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h" | 39 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h" |
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 : render_widget_host_(RenderWidgetHostImpl::From(widget)), | 505 : render_widget_host_(RenderWidgetHostImpl::From(widget)), |
505 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), | 506 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), |
506 can_compose_inline_(true), | 507 can_compose_inline_(true), |
507 browser_compositor_view_placeholder_( | 508 browser_compositor_view_placeholder_( |
508 new BrowserCompositorViewPlaceholderMac), | 509 new BrowserCompositorViewPlaceholderMac), |
509 backing_store_scale_factor_(1), | 510 backing_store_scale_factor_(1), |
510 is_loading_(false), | 511 is_loading_(false), |
511 allow_pause_for_resize_or_repaint_(true), | 512 allow_pause_for_resize_or_repaint_(true), |
512 weak_factory_(this), | 513 weak_factory_(this), |
513 fullscreen_parent_host_view_(NULL), | 514 fullscreen_parent_host_view_(NULL), |
| 515 needs_begin_frame_(false), |
| 516 begin_frame_scheduling_is_enabled_(false), |
514 software_frame_weak_ptr_factory_(this) { | 517 software_frame_weak_ptr_factory_(this) { |
515 software_frame_manager_.reset(new SoftwareFrameManager( | 518 software_frame_manager_.reset(new SoftwareFrameManager( |
516 software_frame_weak_ptr_factory_.GetWeakPtr())); | 519 software_frame_weak_ptr_factory_.GetWeakPtr())); |
517 // |cocoa_view_| owns us and we will be deleted when |cocoa_view_| | 520 // |cocoa_view_| owns us and we will be deleted when |cocoa_view_| |
518 // goes away. Since we autorelease it, our caller must put | 521 // goes away. Since we autorelease it, our caller must put |
519 // |GetNativeView()| into the view hierarchy right after calling us. | 522 // |GetNativeView()| into the view hierarchy right after calling us. |
520 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] | 523 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] |
521 initWithRenderWidgetHostViewMac:this] autorelease]; | 524 initWithRenderWidgetHostViewMac:this] autorelease]; |
522 | 525 |
523 // Make this view host a solid white layer when there is no content ready to | 526 // Make this view host a solid white layer when there is no content ready to |
(...skipping 16 matching lines...) Expand all Loading... |
540 } | 543 } |
541 | 544 |
542 if (IsDelegatedRendererEnabled()) { | 545 if (IsDelegatedRendererEnabled()) { |
543 root_layer_.reset(new ui::Layer(ui::LAYER_TEXTURED)); | 546 root_layer_.reset(new ui::Layer(ui::LAYER_TEXTURED)); |
544 delegated_frame_host_.reset(new DelegatedFrameHost(this)); | 547 delegated_frame_host_.reset(new DelegatedFrameHost(this)); |
545 } | 548 } |
546 | 549 |
547 gfx::Screen::GetScreenFor(cocoa_view_)->AddObserver(this); | 550 gfx::Screen::GetScreenFor(cocoa_view_)->AddObserver(this); |
548 | 551 |
549 render_widget_host_->SetView(this); | 552 render_widget_host_->SetView(this); |
| 553 |
| 554 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 555 cc::switches::kEnableBeginFrameScheduling) && |
| 556 !CommandLIne::HasSwitch(switches::kDisableGpuVsync)) |
| 557 begin_frame_scheduling_is_enabled_ = true; |
550 } | 558 } |
551 | 559 |
552 RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { | 560 RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { |
| 561 // |this| should be removed from BeginFrameManger's observer list cleanly. |
| 562 if (begin_frame_scheduling_is_enalbed_) { |
| 563 DCHECK(needs_begin_frame_); |
| 564 display_link_->RemoveObserver(this); |
| 565 } |
553 gfx::Screen::GetScreenFor(cocoa_view_)->RemoveObserver(this); | 566 gfx::Screen::GetScreenFor(cocoa_view_)->RemoveObserver(this); |
554 | 567 |
555 // This is being called from |cocoa_view_|'s destructor, so invalidate the | 568 // This is being called from |cocoa_view_|'s destructor, so invalidate the |
556 // pointer. | 569 // pointer. |
557 cocoa_view_ = nil; | 570 cocoa_view_ = nil; |
558 | 571 |
559 UnlockMouse(); | 572 UnlockMouse(); |
560 | 573 |
561 // 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. |
562 DestroyCompositedIOSurfaceAndLayer(); | 575 DestroyCompositedIOSurfaceAndLayer(); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 return; | 658 return; |
646 if (browser_compositor_view_) | 659 if (browser_compositor_view_) |
647 return; | 660 return; |
648 | 661 |
649 TRACE_EVENT0("browser", | 662 TRACE_EVENT0("browser", |
650 "RenderWidgetHostViewMac::EnsureBrowserCompositorView"); | 663 "RenderWidgetHostViewMac::EnsureBrowserCompositorView"); |
651 | 664 |
652 browser_compositor_view_.reset(new BrowserCompositorViewMac(this)); | 665 browser_compositor_view_.reset(new BrowserCompositorViewMac(this)); |
653 delegated_frame_host_->AddedToWindow(); | 666 delegated_frame_host_->AddedToWindow(); |
654 delegated_frame_host_->WasShown(); | 667 delegated_frame_host_->WasShown(); |
| 668 |
| 669 if (needs_begin_frame_) |
| 670 GetCompositor()->begin_frame_manager()->AddObserver(this); |
655 } | 671 } |
656 | 672 |
657 void RenderWidgetHostViewMac::DestroyBrowserCompositorView() { | 673 void RenderWidgetHostViewMac::DestroyBrowserCompositorView() { |
658 TRACE_EVENT0("browser", | 674 TRACE_EVENT0("browser", |
659 "RenderWidgetHostViewMac::DestroyBrowserCompositorView"); | 675 "RenderWidgetHostViewMac::DestroyBrowserCompositorView"); |
660 if (!browser_compositor_view_) | 676 if (!browser_compositor_view_) |
661 return; | 677 return; |
662 | 678 |
| 679 if (needs_begin_frame_) |
| 680 GetCompositor()->begin_frame_manager()->RemoveObserver(this); |
| 681 |
663 delegated_frame_host_->WasHidden(); | 682 delegated_frame_host_->WasHidden(); |
664 delegated_frame_host_->RemovingFromWindow(); | 683 delegated_frame_host_->RemovingFromWindow(); |
665 browser_compositor_view_.reset(); | 684 browser_compositor_view_.reset(); |
666 } | 685 } |
667 | 686 |
668 void RenderWidgetHostViewMac::EnsureSoftwareLayer() { | 687 void RenderWidgetHostViewMac::EnsureSoftwareLayer() { |
669 TRACE_EVENT0("browser", "RenderWidgetHostViewMac::EnsureSoftwareLayer"); | 688 TRACE_EVENT0("browser", "RenderWidgetHostViewMac::EnsureSoftwareLayer"); |
670 if (software_layer_) | 689 if (software_layer_) |
671 return; | 690 return; |
672 | 691 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
727 DestroyCompositedIOSurfaceLayer(kRemoveLayerFromHierarchy); | 746 DestroyCompositedIOSurfaceLayer(kRemoveLayerFromHierarchy); |
728 compositing_iosurface_ = NULL; | 747 compositing_iosurface_ = NULL; |
729 compositing_iosurface_context_ = NULL; | 748 compositing_iosurface_context_ = NULL; |
730 } | 749 } |
731 | 750 |
732 bool RenderWidgetHostViewMac::OnMessageReceived(const IPC::Message& message) { | 751 bool RenderWidgetHostViewMac::OnMessageReceived(const IPC::Message& message) { |
733 bool handled = true; | 752 bool handled = true; |
734 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewMac, message) | 753 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewMac, message) |
735 IPC_MESSAGE_HANDLER(ViewHostMsg_PluginFocusChanged, OnPluginFocusChanged) | 754 IPC_MESSAGE_HANDLER(ViewHostMsg_PluginFocusChanged, OnPluginFocusChanged) |
736 IPC_MESSAGE_HANDLER(ViewHostMsg_StartPluginIme, OnStartPluginIme) | 755 IPC_MESSAGE_HANDLER(ViewHostMsg_StartPluginIme, OnStartPluginIme) |
| 756 IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrame, OnSetNeedsBeginFrame) |
737 IPC_MESSAGE_UNHANDLED(handled = false) | 757 IPC_MESSAGE_UNHANDLED(handled = false) |
738 IPC_END_MESSAGE_MAP() | 758 IPC_END_MESSAGE_MAP() |
739 return handled; | 759 return handled; |
740 } | 760 } |
741 | 761 |
742 void RenderWidgetHostViewMac::InitAsChild( | 762 void RenderWidgetHostViewMac::InitAsChild( |
743 gfx::NativeView parent_view) { | 763 gfx::NativeView parent_view) { |
744 } | 764 } |
745 | 765 |
746 void RenderWidgetHostViewMac::InitAsPopup( | 766 void RenderWidgetHostViewMac::InitAsPopup( |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
852 NSDictionary* screen_description = [screen deviceDescription]; | 872 NSDictionary* screen_description = [screen deviceDescription]; |
853 NSNumber* screen_number = [screen_description objectForKey:@"NSScreenNumber"]; | 873 NSNumber* screen_number = [screen_description objectForKey:@"NSScreenNumber"]; |
854 CGDirectDisplayID display_id = [screen_number unsignedIntValue]; | 874 CGDirectDisplayID display_id = [screen_number unsignedIntValue]; |
855 | 875 |
856 display_link_ = DisplayLinkMac::GetForDisplay(display_id); | 876 display_link_ = DisplayLinkMac::GetForDisplay(display_id); |
857 if (!display_link_) { | 877 if (!display_link_) { |
858 // Note that on some headless systems, the display link will fail to be | 878 // Note that on some headless systems, the display link will fail to be |
859 // created, so this should not be a fatal error. | 879 // created, so this should not be a fatal error. |
860 LOG(ERROR) << "Failed to create display link."; | 880 LOG(ERROR) << "Failed to create display link."; |
861 } | 881 } |
| 882 |
| 883 if (begin_frame_scheduling_is_enabled_) |
| 884 display_link_->AddObserver(this); |
862 } | 885 } |
863 | 886 |
864 void RenderWidgetHostViewMac::SendVSyncParametersToRenderer() { | 887 void RenderWidgetHostViewMac::SendVSyncParametersToRenderer() { |
| 888 if (begin_frame_scheduling_is_enabled_) |
| 889 return; |
| 890 |
865 if (!render_widget_host_ || !display_link_) | 891 if (!render_widget_host_ || !display_link_) |
866 return; | 892 return; |
867 | 893 |
868 if (!display_link_->GetVSyncParameters(&vsync_timebase_, &vsync_interval_)) { | 894 if (!display_link_->GetVSyncParameters(&vsync_timebase_, &vsync_interval_)) { |
869 vsync_timebase_ = base::TimeTicks(); | 895 vsync_timebase_ = base::TimeTicks(); |
870 vsync_interval_ = base::TimeDelta(); | 896 vsync_interval_ = base::TimeDelta(); |
871 return; | 897 return; |
872 } | 898 } |
873 | 899 |
874 render_widget_host_->UpdateVSyncParameters(vsync_timebase_, vsync_interval_); | 900 render_widget_host_->UpdateVSyncParameters(vsync_timebase_, vsync_interval_); |
875 } | 901 } |
876 | 902 |
| 903 void RenderWidgetHostViewMac::OnSetNeedsBeginFrame(bool enabled) { |
| 904 DCHECK(begin_frame_scheduling_is_enabled_); |
| 905 |
| 906 if (needs_begin_frame_ == enabled) |
| 907 return; |
| 908 |
| 909 TRACE_EVENT1("cc", "RenderWidgetHostViewMac::OnSetNeedsBeginFrame", |
| 910 "enabled", enabled); |
| 911 |
| 912 if (enabled) |
| 913 GetCompositor()->begin_frame_manager()->AddObserver(this, |
| 914 last_begin_frame_args_); |
| 915 else |
| 916 GetCompositor()->begin_frame_manager()->RemoveObserver(this); |
| 917 |
| 918 needs_begin_frame_ = enabled; |
| 919 } |
| 920 |
877 void RenderWidgetHostViewMac::UpdateBackingStoreScaleFactor() { | 921 void RenderWidgetHostViewMac::UpdateBackingStoreScaleFactor() { |
878 if (!render_widget_host_) | 922 if (!render_widget_host_) |
879 return; | 923 return; |
880 | 924 |
881 float new_scale_factor = ui::GetScaleFactorForNativeView(cocoa_view_); | 925 float new_scale_factor = ui::GetScaleFactorForNativeView(cocoa_view_); |
882 if (new_scale_factor == backing_store_scale_factor_) | 926 if (new_scale_factor == backing_store_scale_factor_) |
883 return; | 927 return; |
884 backing_store_scale_factor_ = new_scale_factor; | 928 backing_store_scale_factor_ = new_scale_factor; |
885 | 929 |
886 render_widget_host_->NotifyScreenInfoChanged(); | 930 render_widget_host_->NotifyScreenInfoChanged(); |
(...skipping 1448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2335 | 2379 |
2336 void RenderWidgetHostViewMac::OnDisplayMetricsChanged( | 2380 void RenderWidgetHostViewMac::OnDisplayMetricsChanged( |
2337 const gfx::Display& display, uint32_t metrics) { | 2381 const gfx::Display& display, uint32_t metrics) { |
2338 gfx::Screen* screen = gfx::Screen::GetScreenFor(cocoa_view_); | 2382 gfx::Screen* screen = gfx::Screen::GetScreenFor(cocoa_view_); |
2339 if (display.id() != screen->GetDisplayNearestWindow(cocoa_view_).id()) | 2383 if (display.id() != screen->GetDisplayNearestWindow(cocoa_view_).id()) |
2340 return; | 2384 return; |
2341 | 2385 |
2342 UpdateScreenInfo(cocoa_view_); | 2386 UpdateScreenInfo(cocoa_view_); |
2343 } | 2387 } |
2344 | 2388 |
| 2389 void RenderWidgetHostViewMac::OnSendBeginFrame( |
| 2390 const cc::BeginFrameArgs& args) { |
| 2391 DCHECK(begin_frame_scheduling_is_enabled_); |
| 2392 DCHECK(render_widget_host_); |
| 2393 TRACE_EVENT0("cc", "RenderWidgetHostViewMac::OnSendBeginFrame"); |
| 2394 |
| 2395 cc::BeginFrameArgs adjusted_args(args); |
| 2396 |
| 2397 delegated_frame_host_->UpdateVSyncParameters(adjusted_args); |
| 2398 |
| 2399 // TODO(brianderson): Use adaptive draw-time estimation. |
| 2400 base::TimeDelta estimated_browser_composite_time = |
| 2401 base::TimeDelta::FromMicroseconds( |
| 2402 (1.0f * base::Time::kMicrosecondsPerSecond) / (3.0f * 60)); |
| 2403 |
| 2404 adjusted_args.deadline -= estimated_browser_composite_time; |
| 2405 |
| 2406 render_widget_host_->Send(new ViewMsg_BeginFrame( |
| 2407 render_widget_host_->GetRoutingID(), |
| 2408 adjusted_args)); |
| 2409 last_begin_frame_args_ = args; |
| 2410 } |
| 2411 |
| 2412 void RenderWidgetHostViewMac::OnVSync(base::TimeTicks timebase, |
| 2413 base::TimeDelta interval) { |
| 2414 DCHECK(begin_frame_scheduling_is_enabled_); |
| 2415 |
| 2416 GetCompositor()->begin_frame_manager()->StartBeginFrame( |
| 2417 cc::BeginFrameArgs::Create(timebase, |
| 2418 timebase + interval, |
| 2419 interval)); |
| 2420 } |
| 2421 |
2345 } // namespace content | 2422 } // namespace content |
2346 | 2423 |
2347 // RenderWidgetHostViewCocoa --------------------------------------------------- | 2424 // RenderWidgetHostViewCocoa --------------------------------------------------- |
2348 | 2425 |
2349 @implementation RenderWidgetHostViewCocoa | 2426 @implementation RenderWidgetHostViewCocoa |
2350 @synthesize selectedRange = selectedRange_; | 2427 @synthesize selectedRange = selectedRange_; |
2351 @synthesize suppressNextEscapeKeyUp = suppressNextEscapeKeyUp_; | 2428 @synthesize suppressNextEscapeKeyUp = suppressNextEscapeKeyUp_; |
2352 @synthesize markedRange = markedRange_; | 2429 @synthesize markedRange = markedRange_; |
2353 | 2430 |
2354 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { | 2431 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { |
(...skipping 1682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4037 | 4114 |
4038 // "-webkit-app-region: drag | no-drag" is implemented on Mac by excluding | 4115 // "-webkit-app-region: drag | no-drag" is implemented on Mac by excluding |
4039 // regions that are not draggable. (See ControlRegionView in | 4116 // regions that are not draggable. (See ControlRegionView in |
4040 // native_app_window_cocoa.mm). This requires the render host view to be | 4117 // native_app_window_cocoa.mm). This requires the render host view to be |
4041 // draggable by default. | 4118 // draggable by default. |
4042 - (BOOL)mouseDownCanMoveWindow { | 4119 - (BOOL)mouseDownCanMoveWindow { |
4043 return YES; | 4120 return YES; |
4044 } | 4121 } |
4045 | 4122 |
4046 @end | 4123 @end |
OLD | NEW |