Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: content/browser/renderer_host/render_widget_host_view_mac.mm

Issue 423773002: Unified BeginFrame scheduling (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: WIP in mac and android Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698