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/io_surface_layer_mac.h" | 34 #include "content/browser/compositor/io_surface_layer_mac.h" |
34 #include "content/browser/compositor/resize_lock.h" | 35 #include "content/browser/compositor/resize_lock.h" |
35 #include "content/browser/compositor/software_layer_mac.h" | 36 #include "content/browser/compositor/software_layer_mac.h" |
36 #include "content/browser/frame_host/frame_tree.h" | 37 #include "content/browser/frame_host/frame_tree.h" |
37 #include "content/browser/frame_host/frame_tree_node.h" | 38 #include "content/browser/frame_host/frame_tree_node.h" |
38 #include "content/browser/frame_host/render_frame_host_impl.h" | 39 #include "content/browser/frame_host/render_frame_host_impl.h" |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
523 | 524 |
524 RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) | 525 RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) |
525 : render_widget_host_(RenderWidgetHostImpl::From(widget)), | 526 : render_widget_host_(RenderWidgetHostImpl::From(widget)), |
526 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), | 527 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), |
527 can_compose_inline_(true), | 528 can_compose_inline_(true), |
528 browser_compositor_view_placeholder_( | 529 browser_compositor_view_placeholder_( |
529 new BrowserCompositorViewPlaceholderMac), | 530 new BrowserCompositorViewPlaceholderMac), |
530 is_loading_(false), | 531 is_loading_(false), |
531 allow_pause_for_resize_or_repaint_(true), | 532 allow_pause_for_resize_or_repaint_(true), |
532 weak_factory_(this), | 533 weak_factory_(this), |
533 fullscreen_parent_host_view_(NULL) { | 534 fullscreen_parent_host_view_(NULL), |
| 535 needs_begin_frame_(false), |
| 536 software_frame_weak_ptr_factory_(this) { |
| 537 software_frame_manager_.reset( |
| 538 new SoftwareFrameManager(software_frame_weak_ptr_factory_.GetWeakPtr())); |
534 // |cocoa_view_| owns us and we will be deleted when |cocoa_view_| | 539 // |cocoa_view_| owns us and we will be deleted when |cocoa_view_| |
535 // goes away. Since we autorelease it, our caller must put | 540 // goes away. Since we autorelease it, our caller must put |
536 // |GetNativeView()| into the view hierarchy right after calling us. | 541 // |GetNativeView()| into the view hierarchy right after calling us. |
537 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] | 542 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] |
538 initWithRenderWidgetHostViewMac:this] autorelease]; | 543 initWithRenderWidgetHostViewMac:this] autorelease]; |
539 | 544 |
540 // Make this view host a solid white layer when there is no content ready to | 545 // Make this view host a solid white layer when there is no content ready to |
541 // draw. | 546 // draw. |
542 background_layer_.reset([[CALayer alloc] init]); | 547 background_layer_.reset([[CALayer alloc] init]); |
543 [background_layer_ | 548 [background_layer_ |
544 setBackgroundColor:CGColorGetConstantColor(kCGColorWhite)]; | 549 setBackgroundColor:CGColorGetConstantColor(kCGColorWhite)]; |
545 [cocoa_view_ setLayer:background_layer_]; | 550 [cocoa_view_ setLayer:background_layer_]; |
546 [cocoa_view_ setWantsLayer:YES]; | 551 [cocoa_view_ setWantsLayer:YES]; |
547 | 552 |
548 if (IsDelegatedRendererEnabled()) { | 553 if (IsDelegatedRendererEnabled()) { |
549 root_layer_.reset(new ui::Layer(ui::LAYER_TEXTURED)); | 554 root_layer_.reset(new ui::Layer(ui::LAYER_TEXTURED)); |
550 delegated_frame_host_.reset(new DelegatedFrameHost(this)); | 555 delegated_frame_host_.reset(new DelegatedFrameHost(this)); |
551 } | 556 } |
552 | 557 |
553 gfx::Screen::GetScreenFor(cocoa_view_)->AddObserver(this); | 558 gfx::Screen::GetScreenFor(cocoa_view_)->AddObserver(this); |
554 | 559 |
555 render_widget_host_->SetView(this); | 560 render_widget_host_->SetView(this); |
556 } | 561 } |
557 | 562 |
558 RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { | 563 RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { |
| 564 if (display_link_) { |
| 565 DCHECK(needs_begin_frame_); |
| 566 display_link_->RemoveObserver(this); |
| 567 } |
559 gfx::Screen::GetScreenFor(cocoa_view_)->RemoveObserver(this); | 568 gfx::Screen::GetScreenFor(cocoa_view_)->RemoveObserver(this); |
560 | 569 |
561 // This is being called from |cocoa_view_|'s destructor, so invalidate the | 570 // This is being called from |cocoa_view_|'s destructor, so invalidate the |
562 // pointer. | 571 // pointer. |
563 cocoa_view_ = nil; | 572 cocoa_view_ = nil; |
564 | 573 |
565 UnlockMouse(); | 574 UnlockMouse(); |
566 | 575 |
567 // Ensure that the browser compositor is destroyed in a safe order. | 576 // Ensure that the browser compositor is destroyed in a safe order. |
568 ShutdownBrowserCompositor(); | 577 ShutdownBrowserCompositor(); |
(...skipping 20 matching lines...) Expand all Loading... |
589 void RenderWidgetHostViewMac::EnsureBrowserCompositorView() { | 598 void RenderWidgetHostViewMac::EnsureBrowserCompositorView() { |
590 if (browser_compositor_view_) | 599 if (browser_compositor_view_) |
591 return; | 600 return; |
592 | 601 |
593 TRACE_EVENT0("browser", | 602 TRACE_EVENT0("browser", |
594 "RenderWidgetHostViewMac::EnsureBrowserCompositorView"); | 603 "RenderWidgetHostViewMac::EnsureBrowserCompositorView"); |
595 | 604 |
596 browser_compositor_view_.reset(new BrowserCompositorViewMac(this)); | 605 browser_compositor_view_.reset(new BrowserCompositorViewMac(this)); |
597 delegated_frame_host_->AddedToWindow(); | 606 delegated_frame_host_->AddedToWindow(); |
598 delegated_frame_host_->WasShown(ui::LatencyInfo()); | 607 delegated_frame_host_->WasShown(ui::LatencyInfo()); |
| 608 |
| 609 if (needs_begin_frame_) |
| 610 GetCompositor()->AddBeginFrameObserver(this, last_begin_frame_args_); |
599 } | 611 } |
600 | 612 |
601 void RenderWidgetHostViewMac::DestroyBrowserCompositorView() { | 613 void RenderWidgetHostViewMac::DestroyBrowserCompositorView() { |
602 TRACE_EVENT0("browser", | 614 TRACE_EVENT0("browser", |
603 "RenderWidgetHostViewMac::DestroyBrowserCompositorView"); | 615 "RenderWidgetHostViewMac::DestroyBrowserCompositorView"); |
604 if (!browser_compositor_view_) | 616 if (!browser_compositor_view_) |
605 return; | 617 return; |
606 | 618 |
607 // Marking the DelegatedFrameHost as removed from the window hierarchy is | 619 // Marking the DelegatedFrameHost as removed from the window hierarchy is |
608 // necessary to remove all connections to its old ui::Compositor. | 620 // necessary to remove all connections to its old ui::Compositor. |
609 delegated_frame_host_->WasHidden(); | 621 delegated_frame_host_->WasHidden(); |
610 delegated_frame_host_->RemovingFromWindow(); | 622 delegated_frame_host_->RemovingFromWindow(); |
611 browser_compositor_view_.reset(); | 623 browser_compositor_view_.reset(); |
| 624 |
| 625 if (needs_begin_frame_) { |
| 626 GetCompositor()->RemoveBeginFrameObserver(this); |
| 627 needs_begin_frame_ = false; |
| 628 } |
612 } | 629 } |
613 | 630 |
614 bool RenderWidgetHostViewMac::OnMessageReceived(const IPC::Message& message) { | 631 bool RenderWidgetHostViewMac::OnMessageReceived(const IPC::Message& message) { |
615 bool handled = true; | 632 bool handled = true; |
616 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewMac, message) | 633 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewMac, message) |
617 IPC_MESSAGE_HANDLER(ViewHostMsg_PluginFocusChanged, OnPluginFocusChanged) | 634 IPC_MESSAGE_HANDLER(ViewHostMsg_PluginFocusChanged, OnPluginFocusChanged) |
618 IPC_MESSAGE_HANDLER(ViewHostMsg_StartPluginIme, OnStartPluginIme) | 635 IPC_MESSAGE_HANDLER(ViewHostMsg_StartPluginIme, OnStartPluginIme) |
619 IPC_MESSAGE_HANDLER(ViewMsg_GetRenderedTextCompleted, | 636 IPC_MESSAGE_HANDLER(ViewMsg_GetRenderedTextCompleted, |
620 OnGetRenderedTextCompleted) | 637 OnGetRenderedTextCompleted) |
| 638 IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrame, OnSetNeedsBeginFrame) |
621 IPC_MESSAGE_UNHANDLED(handled = false) | 639 IPC_MESSAGE_UNHANDLED(handled = false) |
622 IPC_END_MESSAGE_MAP() | 640 IPC_END_MESSAGE_MAP() |
623 return handled; | 641 return handled; |
624 } | 642 } |
625 | 643 |
626 void RenderWidgetHostViewMac::InitAsChild( | 644 void RenderWidgetHostViewMac::InitAsChild( |
627 gfx::NativeView parent_view) { | 645 gfx::NativeView parent_view) { |
628 } | 646 } |
629 | 647 |
630 void RenderWidgetHostViewMac::InitAsPopup( | 648 void RenderWidgetHostViewMac::InitAsPopup( |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
736 NSScreen* screen = [[cocoa_view_ window] screen]; | 754 NSScreen* screen = [[cocoa_view_ window] screen]; |
737 NSDictionary* screen_description = [screen deviceDescription]; | 755 NSDictionary* screen_description = [screen deviceDescription]; |
738 NSNumber* screen_number = [screen_description objectForKey:@"NSScreenNumber"]; | 756 NSNumber* screen_number = [screen_description objectForKey:@"NSScreenNumber"]; |
739 CGDirectDisplayID display_id = [screen_number unsignedIntValue]; | 757 CGDirectDisplayID display_id = [screen_number unsignedIntValue]; |
740 | 758 |
741 display_link_ = DisplayLinkMac::GetForDisplay(display_id); | 759 display_link_ = DisplayLinkMac::GetForDisplay(display_id); |
742 if (!display_link_) { | 760 if (!display_link_) { |
743 // Note that on some headless systems, the display link will fail to be | 761 // Note that on some headless systems, the display link will fail to be |
744 // created, so this should not be a fatal error. | 762 // created, so this should not be a fatal error. |
745 LOG(ERROR) << "Failed to create display link."; | 763 LOG(ERROR) << "Failed to create display link."; |
746 } | |
747 } | |
748 | |
749 void RenderWidgetHostViewMac::SendVSyncParametersToRenderer() { | |
750 if (!render_widget_host_ || !display_link_) | |
751 return; | |
752 | |
753 if (!display_link_->GetVSyncParameters(&vsync_timebase_, &vsync_interval_)) { | |
754 vsync_timebase_ = base::TimeTicks(); | |
755 vsync_interval_ = base::TimeDelta(); | |
756 return; | 764 return; |
757 } | 765 } |
758 | 766 |
759 render_widget_host_->UpdateVSyncParameters(vsync_timebase_, vsync_interval_); | 767 display_link_->AddObserver(this); |
| 768 } |
| 769 |
| 770 void RenderWidgetHostViewMac::OnSetNeedsBeginFrame(bool enabled) { |
| 771 DCHECK(display_link_); |
| 772 |
| 773 if (needs_begin_frame_ == enabled) |
| 774 return; |
| 775 |
| 776 TRACE_EVENT1("cc", |
| 777 "RenderWidgetHostViewMac::OnSetNeedsBeginFrame", |
| 778 "enabled", |
| 779 enabled); |
| 780 |
| 781 needs_begin_frame_ = enabled; |
| 782 |
| 783 if (enabled) |
| 784 GetCompositor()->AddBeginFrameObserver(this, last_begin_frame_args_); |
| 785 else |
| 786 DCHECK(!GetCompsoitr()); |
760 } | 787 } |
761 | 788 |
762 void RenderWidgetHostViewMac::SpeakText(const std::string& text) { | 789 void RenderWidgetHostViewMac::SpeakText(const std::string& text) { |
763 [NSApp speakString:base::SysUTF8ToNSString(text)]; | 790 [NSApp speakString:base::SysUTF8ToNSString(text)]; |
764 } | 791 } |
765 | 792 |
766 void RenderWidgetHostViewMac::UpdateBackingStoreScaleFactor() { | 793 void RenderWidgetHostViewMac::UpdateBackingStoreScaleFactor() { |
767 if (!render_widget_host_) | 794 if (!render_widget_host_) |
768 return; | 795 return; |
769 render_widget_host_->NotifyScreenInfoChanged(); | 796 render_widget_host_->NotifyScreenInfoChanged(); |
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1403 gfx::Size dip_size = | 1430 gfx::Size dip_size = |
1404 ConvertSizeToDIP(scale_factor, pixel_size); | 1431 ConvertSizeToDIP(scale_factor, pixel_size); |
1405 | 1432 |
1406 root_layer_->SetBounds(gfx::Rect(dip_size)); | 1433 root_layer_->SetBounds(gfx::Rect(dip_size)); |
1407 if (!render_widget_host_->is_hidden()) { | 1434 if (!render_widget_host_->is_hidden()) { |
1408 EnsureBrowserCompositorView(); | 1435 EnsureBrowserCompositorView(); |
1409 browser_compositor_view_->GetCompositor()->SetScaleAndSize( | 1436 browser_compositor_view_->GetCompositor()->SetScaleAndSize( |
1410 scale_factor, pixel_size); | 1437 scale_factor, pixel_size); |
1411 } | 1438 } |
1412 | 1439 |
1413 SendVSyncParametersToRenderer(); | |
1414 | |
1415 delegated_frame_host_->SwapDelegatedFrame( | 1440 delegated_frame_host_->SwapDelegatedFrame( |
1416 output_surface_id, | 1441 output_surface_id, |
1417 frame->delegated_frame_data.Pass(), | 1442 frame->delegated_frame_data.Pass(), |
1418 frame->metadata.device_scale_factor, | 1443 frame->metadata.device_scale_factor, |
1419 frame->metadata.latency_info); | 1444 frame->metadata.latency_info); |
1420 } else { | 1445 } else { |
1421 DLOG(ERROR) << "Received unexpected frame type."; | 1446 DLOG(ERROR) << "Received unexpected frame type."; |
1422 RecordAction( | 1447 RecordAction( |
1423 base::UserMetricsAction("BadMessageTerminate_UnexpectedFrameType")); | 1448 base::UserMetricsAction("BadMessageTerminate_UnexpectedFrameType")); |
1424 render_widget_host_->GetProcess()->ReceivedBadMessage(); | 1449 render_widget_host_->GetProcess()->ReceivedBadMessage(); |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1650 | 1675 |
1651 void RenderWidgetHostViewMac::OnDisplayMetricsChanged( | 1676 void RenderWidgetHostViewMac::OnDisplayMetricsChanged( |
1652 const gfx::Display& display, uint32_t metrics) { | 1677 const gfx::Display& display, uint32_t metrics) { |
1653 gfx::Screen* screen = gfx::Screen::GetScreenFor(cocoa_view_); | 1678 gfx::Screen* screen = gfx::Screen::GetScreenFor(cocoa_view_); |
1654 if (display.id() != screen->GetDisplayNearestWindow(cocoa_view_).id()) | 1679 if (display.id() != screen->GetDisplayNearestWindow(cocoa_view_).id()) |
1655 return; | 1680 return; |
1656 | 1681 |
1657 UpdateScreenInfo(cocoa_view_); | 1682 UpdateScreenInfo(cocoa_view_); |
1658 } | 1683 } |
1659 | 1684 |
| 1685 void RenderWidgetHostViewMac::OnSendBeginFrame(const cc::BeginFrameArgs& args) { |
| 1686 DCHECK(display_link_); |
| 1687 DCHECK(render_widget_host_); |
| 1688 TRACE_EVENT0("cc", "RenderWidgetHostViewMac::OnSendBeginFrame"); |
| 1689 |
| 1690 delegated_frame_host_->UpdateVSyncParameters(args); |
| 1691 |
| 1692 render_widget_host_->Send( |
| 1693 new ViewMsg_BeginFrame(render_widget_host_->GetRoutingID(), args)); |
| 1694 last_begin_frame_args_ = args; |
| 1695 vsync_timebase_ = args.frame_time; |
| 1696 vsync_interval_ = args.interval; |
| 1697 } |
| 1698 |
| 1699 void RenderWidgetHostViewMac::OnVSync(base::TimeTicks timebase, |
| 1700 base::TimeDelta interval) { |
| 1701 DCHECK(display_link_); |
| 1702 |
| 1703 if (!GetCompositor()) |
| 1704 return; |
| 1705 |
| 1706 GetCompositor()->StartBeginFrame( |
| 1707 cc::BeginFrameArgs::Create(timebase, timebase + interval, interval)); |
| 1708 } |
| 1709 |
1660 } // namespace content | 1710 } // namespace content |
1661 | 1711 |
1662 // RenderWidgetHostViewCocoa --------------------------------------------------- | 1712 // RenderWidgetHostViewCocoa --------------------------------------------------- |
1663 | 1713 |
1664 @implementation RenderWidgetHostViewCocoa | 1714 @implementation RenderWidgetHostViewCocoa |
1665 @synthesize selectedRange = selectedRange_; | 1715 @synthesize selectedRange = selectedRange_; |
1666 @synthesize suppressNextEscapeKeyUp = suppressNextEscapeKeyUp_; | 1716 @synthesize suppressNextEscapeKeyUp = suppressNextEscapeKeyUp_; |
1667 @synthesize markedRange = markedRange_; | 1717 @synthesize markedRange = markedRange_; |
1668 | 1718 |
1669 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { | 1719 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { |
(...skipping 1674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3344 | 3394 |
3345 // "-webkit-app-region: drag | no-drag" is implemented on Mac by excluding | 3395 // "-webkit-app-region: drag | no-drag" is implemented on Mac by excluding |
3346 // regions that are not draggable. (See ControlRegionView in | 3396 // regions that are not draggable. (See ControlRegionView in |
3347 // native_app_window_cocoa.mm). This requires the render host view to be | 3397 // native_app_window_cocoa.mm). This requires the render host view to be |
3348 // draggable by default. | 3398 // draggable by default. |
3349 - (BOOL)mouseDownCanMoveWindow { | 3399 - (BOOL)mouseDownCanMoveWindow { |
3350 return YES; | 3400 return YES; |
3351 } | 3401 } |
3352 | 3402 |
3353 @end | 3403 @end |
OLD | NEW |