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 |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 [[screen colorSpace] colorSpaceModel] == NSGrayColorSpaceModel; | 390 [[screen colorSpace] colorSpaceModel] == NSGrayColorSpaceModel; |
391 results.rect = display.bounds(); | 391 results.rect = display.bounds(); |
392 results.availableRect = display.work_area(); | 392 results.availableRect = display.work_area(); |
393 results.orientationAngle = display.RotationAsDegree(); | 393 results.orientationAngle = display.RotationAsDegree(); |
394 results.orientationType = | 394 results.orientationType = |
395 content::RenderWidgetHostViewBase::GetOrientationTypeForDesktop(display); | 395 content::RenderWidgetHostViewBase::GetOrientationTypeForDesktop(display); |
396 | 396 |
397 return results; | 397 return results; |
398 } | 398 } |
399 | 399 |
| 400 void RemoveLayerFromSuperlayer( |
| 401 base::scoped_nsobject<CompositingIOSurfaceLayer> layer) { |
| 402 // Disable the fade-out animation as the layer is removed. |
| 403 ScopedCAActionDisabler disabler; |
| 404 [layer removeFromSuperlayer]; |
| 405 } |
| 406 |
400 } // namespace | 407 } // namespace |
401 | 408 |
402 namespace content { | 409 namespace content { |
403 | 410 |
404 //////////////////////////////////////////////////////////////////////////////// | 411 //////////////////////////////////////////////////////////////////////////////// |
405 // DelegatedFrameHost, public: | 412 // DelegatedFrameHost, public: |
406 | 413 |
407 ui::Compositor* RenderWidgetHostViewMac::GetCompositor() const { | 414 ui::Compositor* RenderWidgetHostViewMac::GetCompositor() const { |
408 if (browser_compositor_view_) | 415 if (browser_compositor_view_) |
409 return browser_compositor_view_->GetCompositor(); | 416 return browser_compositor_view_->GetCompositor(); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 | 499 |
493 /////////////////////////////////////////////////////////////////////////////// | 500 /////////////////////////////////////////////////////////////////////////////// |
494 // RenderWidgetHostViewMac, public: | 501 // RenderWidgetHostViewMac, public: |
495 | 502 |
496 RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) | 503 RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) |
497 : render_widget_host_(RenderWidgetHostImpl::From(widget)), | 504 : render_widget_host_(RenderWidgetHostImpl::From(widget)), |
498 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), | 505 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), |
499 can_compose_inline_(true), | 506 can_compose_inline_(true), |
500 browser_compositor_view_placeholder_( | 507 browser_compositor_view_placeholder_( |
501 new BrowserCompositorViewPlaceholderMac), | 508 new BrowserCompositorViewPlaceholderMac), |
| 509 backing_store_scale_factor_(1), |
502 is_loading_(false), | 510 is_loading_(false), |
503 allow_pause_for_resize_or_repaint_(true), | 511 allow_pause_for_resize_or_repaint_(true), |
504 weak_factory_(this), | 512 weak_factory_(this), |
505 fullscreen_parent_host_view_(NULL) { | 513 fullscreen_parent_host_view_(NULL), |
| 514 software_frame_weak_ptr_factory_(this) { |
| 515 software_frame_manager_.reset(new SoftwareFrameManager( |
| 516 software_frame_weak_ptr_factory_.GetWeakPtr())); |
506 // |cocoa_view_| owns us and we will be deleted when |cocoa_view_| | 517 // |cocoa_view_| owns us and we will be deleted when |cocoa_view_| |
507 // goes away. Since we autorelease it, our caller must put | 518 // goes away. Since we autorelease it, our caller must put |
508 // |GetNativeView()| into the view hierarchy right after calling us. | 519 // |GetNativeView()| into the view hierarchy right after calling us. |
509 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] | 520 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] |
510 initWithRenderWidgetHostViewMac:this] autorelease]; | 521 initWithRenderWidgetHostViewMac:this] autorelease]; |
511 | 522 |
512 // Make this view host a solid white layer when there is no content ready to | 523 // Make this view host a solid white layer when there is no content ready to |
513 // draw. | 524 // draw. |
514 background_layer_.reset([[CALayer alloc] init]); | 525 background_layer_.reset([[CALayer alloc] init]); |
515 [background_layer_ | 526 [background_layer_ |
516 setBackgroundColor:CGColorGetConstantColor(kCGColorWhite)]; | 527 setBackgroundColor:CGColorGetConstantColor(kCGColorWhite)]; |
517 [cocoa_view_ setLayer:background_layer_]; | 528 [cocoa_view_ setLayer:background_layer_]; |
518 [cocoa_view_ setWantsLayer:YES]; | 529 [cocoa_view_ setWantsLayer:YES]; |
519 | 530 |
520 root_layer_.reset(new ui::Layer(ui::LAYER_TEXTURED)); | 531 if (!IsDelegatedRendererEnabled()) { |
521 delegated_frame_host_.reset(new DelegatedFrameHost(this)); | 532 // Add a flipped transparent layer as a child, so that we don't need to |
| 533 // fiddle with the position of sub-layers -- they will always be at the |
| 534 // origin. |
| 535 flipped_layer_.reset([[CALayer alloc] init]); |
| 536 [flipped_layer_ setGeometryFlipped:YES]; |
| 537 [flipped_layer_ |
| 538 setAutoresizingMask:kCALayerWidthSizable|kCALayerHeightSizable]; |
| 539 [background_layer_ addSublayer:flipped_layer_]; |
| 540 } |
| 541 |
| 542 if (IsDelegatedRendererEnabled()) { |
| 543 root_layer_.reset(new ui::Layer(ui::LAYER_TEXTURED)); |
| 544 delegated_frame_host_.reset(new DelegatedFrameHost(this)); |
| 545 } |
522 | 546 |
523 gfx::Screen::GetScreenFor(cocoa_view_)->AddObserver(this); | 547 gfx::Screen::GetScreenFor(cocoa_view_)->AddObserver(this); |
524 | 548 |
525 render_widget_host_->SetView(this); | 549 render_widget_host_->SetView(this); |
526 } | 550 } |
527 | 551 |
528 RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { | 552 RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { |
529 gfx::Screen::GetScreenFor(cocoa_view_)->RemoveObserver(this); | 553 gfx::Screen::GetScreenFor(cocoa_view_)->RemoveObserver(this); |
530 | 554 |
531 // This is being called from |cocoa_view_|'s destructor, so invalidate the | 555 // This is being called from |cocoa_view_|'s destructor, so invalidate the |
532 // pointer. | 556 // pointer. |
533 cocoa_view_ = nil; | 557 cocoa_view_ = nil; |
534 | 558 |
535 UnlockMouse(); | 559 UnlockMouse(); |
536 | 560 |
537 // Ensure that the browser compositor is destroyed in a safe order. | 561 // Ensure that the browser compositor is destroyed in a safe order. |
538 ShutdownBrowserCompositor(); | 562 ShutdownBrowserCompositor(); |
539 | 563 |
| 564 // Make sure that the layer doesn't reach into the now-invalid object. |
| 565 DestroyCompositedIOSurfaceAndLayer(); |
| 566 DestroySoftwareLayer(); |
| 567 |
540 // We are owned by RenderWidgetHostViewCocoa, so if we go away before the | 568 // We are owned by RenderWidgetHostViewCocoa, so if we go away before the |
541 // RenderWidgetHost does we need to tell it not to hold a stale pointer to | 569 // RenderWidgetHost does we need to tell it not to hold a stale pointer to |
542 // us. | 570 // us. |
543 if (render_widget_host_) | 571 if (render_widget_host_) |
544 render_widget_host_->SetView(NULL); | 572 render_widget_host_->SetView(NULL); |
545 } | 573 } |
546 | 574 |
547 void RenderWidgetHostViewMac::SetDelegate( | 575 void RenderWidgetHostViewMac::SetDelegate( |
548 NSObject<RenderWidgetHostViewMacDelegate>* delegate) { | 576 NSObject<RenderWidgetHostViewMacDelegate>* delegate) { |
549 [cocoa_view_ setResponderDelegate:delegate]; | 577 [cocoa_view_ setResponderDelegate:delegate]; |
550 } | 578 } |
551 | 579 |
552 void RenderWidgetHostViewMac::SetAllowPauseForResizeOrRepaint(bool allow) { | 580 void RenderWidgetHostViewMac::SetAllowPauseForResizeOrRepaint(bool allow) { |
553 allow_pause_for_resize_or_repaint_ = allow; | 581 allow_pause_for_resize_or_repaint_ = allow; |
554 } | 582 } |
555 | 583 |
556 /////////////////////////////////////////////////////////////////////////////// | 584 /////////////////////////////////////////////////////////////////////////////// |
557 // RenderWidgetHostViewMac, RenderWidgetHostView implementation: | 585 // RenderWidgetHostViewMac, RenderWidgetHostView implementation: |
558 | 586 |
| 587 bool RenderWidgetHostViewMac::EnsureCompositedIOSurface() { |
| 588 // If the context or the IOSurface's context has had an error, re-build |
| 589 // everything from scratch. |
| 590 if (compositing_iosurface_context_ && |
| 591 compositing_iosurface_context_->HasBeenPoisoned()) { |
| 592 LOG(ERROR) << "Failing EnsureCompositedIOSurface because " |
| 593 << "context was poisoned"; |
| 594 return false; |
| 595 } |
| 596 if (compositing_iosurface_ && |
| 597 compositing_iosurface_->HasBeenPoisoned()) { |
| 598 LOG(ERROR) << "Failing EnsureCompositedIOSurface because " |
| 599 << "surface was poisoned"; |
| 600 return false; |
| 601 } |
| 602 |
| 603 int current_window_number = |
| 604 CompositingIOSurfaceContext::kOffscreenContextWindowNumber; |
| 605 bool new_surface_needed = !compositing_iosurface_; |
| 606 bool new_context_needed = |
| 607 !compositing_iosurface_context_ || |
| 608 (compositing_iosurface_context_ && |
| 609 compositing_iosurface_context_->window_number() != |
| 610 current_window_number); |
| 611 |
| 612 if (!new_surface_needed && !new_context_needed) |
| 613 return true; |
| 614 |
| 615 // Create the GL context and shaders. |
| 616 if (new_context_needed) { |
| 617 scoped_refptr<CompositingIOSurfaceContext> new_context = |
| 618 CompositingIOSurfaceContext::Get(current_window_number); |
| 619 // Un-bind the GL context from this view before binding the new GL |
| 620 // context. Having two GL contexts bound to a view will result in |
| 621 // crashes and corruption. |
| 622 // http://crbug.com/230883 |
| 623 if (!new_context) { |
| 624 LOG(ERROR) << "Failed to create CompositingIOSurfaceContext"; |
| 625 return false; |
| 626 } |
| 627 compositing_iosurface_context_ = new_context; |
| 628 } |
| 629 |
| 630 // Create the IOSurface texture. |
| 631 if (new_surface_needed) { |
| 632 compositing_iosurface_ = CompositingIOSurfaceMac::Create(); |
| 633 if (!compositing_iosurface_) { |
| 634 LOG(ERROR) << "Failed to create CompositingIOSurface"; |
| 635 return false; |
| 636 } |
| 637 } |
| 638 |
| 639 return true; |
| 640 } |
| 641 |
559 void RenderWidgetHostViewMac::EnsureBrowserCompositorView() { | 642 void RenderWidgetHostViewMac::EnsureBrowserCompositorView() { |
| 643 if (!delegated_frame_host_) |
| 644 return; |
560 if (browser_compositor_view_) | 645 if (browser_compositor_view_) |
561 return; | 646 return; |
562 | 647 |
563 TRACE_EVENT0("browser", | 648 TRACE_EVENT0("browser", |
564 "RenderWidgetHostViewMac::EnsureBrowserCompositorView"); | 649 "RenderWidgetHostViewMac::EnsureBrowserCompositorView"); |
565 | 650 |
566 browser_compositor_view_.reset(new BrowserCompositorViewMac(this)); | 651 browser_compositor_view_.reset(new BrowserCompositorViewMac(this)); |
567 delegated_frame_host_->AddedToWindow(); | 652 delegated_frame_host_->AddedToWindow(); |
568 delegated_frame_host_->WasShown(ui::LatencyInfo()); | 653 delegated_frame_host_->WasShown(ui::LatencyInfo()); |
569 } | 654 } |
570 | 655 |
571 void RenderWidgetHostViewMac::DestroyBrowserCompositorView() { | 656 void RenderWidgetHostViewMac::DestroyBrowserCompositorView() { |
572 TRACE_EVENT0("browser", | 657 TRACE_EVENT0("browser", |
573 "RenderWidgetHostViewMac::DestroyBrowserCompositorView"); | 658 "RenderWidgetHostViewMac::DestroyBrowserCompositorView"); |
574 if (!browser_compositor_view_) | 659 if (!browser_compositor_view_) |
575 return; | 660 return; |
576 | 661 |
577 // Marking the DelegatedFrameHost as removed from the window hierarchy is | 662 // Marking the DelegatedFrameHost as removed from the window hierarchy is |
578 // necessary to remove all connections to its old ui::Compositor. | 663 // necessary to remove all connections to its old ui::Compositor. |
579 delegated_frame_host_->WasHidden(); | 664 delegated_frame_host_->WasHidden(); |
580 delegated_frame_host_->RemovingFromWindow(); | 665 delegated_frame_host_->RemovingFromWindow(); |
581 browser_compositor_view_.reset(); | 666 browser_compositor_view_.reset(); |
582 } | 667 } |
583 | 668 |
| 669 void RenderWidgetHostViewMac::EnsureSoftwareLayer() { |
| 670 TRACE_EVENT0("browser", "RenderWidgetHostViewMac::EnsureSoftwareLayer"); |
| 671 if (software_layer_) |
| 672 return; |
| 673 |
| 674 software_layer_.reset([[SoftwareLayer alloc] init]); |
| 675 DCHECK(software_layer_); |
| 676 |
| 677 // Disable the fade-in animation as the layer is added. |
| 678 ScopedCAActionDisabler disabler; |
| 679 [flipped_layer_ addSublayer:software_layer_]; |
| 680 } |
| 681 |
| 682 void RenderWidgetHostViewMac::DestroySoftwareLayer() { |
| 683 if (!software_layer_) |
| 684 return; |
| 685 |
| 686 // Disable the fade-out animation as the layer is removed. |
| 687 ScopedCAActionDisabler disabler; |
| 688 [software_layer_ removeFromSuperlayer]; |
| 689 software_layer_.reset(); |
| 690 } |
| 691 |
| 692 void RenderWidgetHostViewMac::EnsureCompositedIOSurfaceLayer() { |
| 693 TRACE_EVENT0("browser", |
| 694 "RenderWidgetHostViewMac::EnsureCompositedIOSurfaceLayer"); |
| 695 DCHECK(compositing_iosurface_context_); |
| 696 if (compositing_iosurface_layer_) |
| 697 return; |
| 698 |
| 699 compositing_iosurface_layer_.reset([[CompositingIOSurfaceLayer alloc] |
| 700 initWithIOSurface:compositing_iosurface_ |
| 701 withScaleFactor:compositing_iosurface_->scale_factor() |
| 702 withClient:this]); |
| 703 DCHECK(compositing_iosurface_layer_); |
| 704 |
| 705 // Disable the fade-in animation as the layer is added. |
| 706 ScopedCAActionDisabler disabler; |
| 707 [flipped_layer_ addSublayer:compositing_iosurface_layer_]; |
| 708 } |
| 709 |
| 710 void RenderWidgetHostViewMac::DestroyCompositedIOSurfaceLayer( |
| 711 DestroyCompositedIOSurfaceLayerBehavior destroy_layer_behavior) { |
| 712 if (!compositing_iosurface_layer_) |
| 713 return; |
| 714 |
| 715 if (destroy_layer_behavior == kRemoveLayerFromHierarchy) { |
| 716 // Disable the fade-out animation as the layer is removed. |
| 717 ScopedCAActionDisabler disabler; |
| 718 [compositing_iosurface_layer_ removeFromSuperlayer]; |
| 719 } |
| 720 [compositing_iosurface_layer_ resetClient]; |
| 721 compositing_iosurface_layer_.reset(); |
| 722 } |
| 723 |
| 724 void RenderWidgetHostViewMac::DestroyCompositedIOSurfaceAndLayer() { |
| 725 // Any pending frames will not be displayed, so ack them now. |
| 726 SendPendingSwapAck(); |
| 727 |
| 728 DestroyCompositedIOSurfaceLayer(kRemoveLayerFromHierarchy); |
| 729 compositing_iosurface_ = NULL; |
| 730 compositing_iosurface_context_ = NULL; |
| 731 } |
| 732 |
584 bool RenderWidgetHostViewMac::OnMessageReceived(const IPC::Message& message) { | 733 bool RenderWidgetHostViewMac::OnMessageReceived(const IPC::Message& message) { |
585 bool handled = true; | 734 bool handled = true; |
586 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewMac, message) | 735 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewMac, message) |
587 IPC_MESSAGE_HANDLER(ViewHostMsg_PluginFocusChanged, OnPluginFocusChanged) | 736 IPC_MESSAGE_HANDLER(ViewHostMsg_PluginFocusChanged, OnPluginFocusChanged) |
588 IPC_MESSAGE_HANDLER(ViewHostMsg_StartPluginIme, OnStartPluginIme) | 737 IPC_MESSAGE_HANDLER(ViewHostMsg_StartPluginIme, OnStartPluginIme) |
589 IPC_MESSAGE_HANDLER(ViewMsg_GetRenderedTextCompleted, | 738 IPC_MESSAGE_HANDLER(ViewMsg_GetRenderedTextCompleted, |
590 OnGetRenderedTextCompleted) | 739 OnGetRenderedTextCompleted) |
591 IPC_MESSAGE_UNHANDLED(handled = false) | 740 IPC_MESSAGE_UNHANDLED(handled = false) |
592 IPC_END_MESSAGE_MAP() | 741 IPC_END_MESSAGE_MAP() |
593 return handled; | 742 return handled; |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
729 render_widget_host_->UpdateVSyncParameters(vsync_timebase_, vsync_interval_); | 878 render_widget_host_->UpdateVSyncParameters(vsync_timebase_, vsync_interval_); |
730 } | 879 } |
731 | 880 |
732 void RenderWidgetHostViewMac::SpeakText(const std::string& text) { | 881 void RenderWidgetHostViewMac::SpeakText(const std::string& text) { |
733 [NSApp speakString:base::SysUTF8ToNSString(text)]; | 882 [NSApp speakString:base::SysUTF8ToNSString(text)]; |
734 } | 883 } |
735 | 884 |
736 void RenderWidgetHostViewMac::UpdateBackingStoreScaleFactor() { | 885 void RenderWidgetHostViewMac::UpdateBackingStoreScaleFactor() { |
737 if (!render_widget_host_) | 886 if (!render_widget_host_) |
738 return; | 887 return; |
| 888 |
| 889 float new_scale_factor = ui::GetScaleFactorForNativeView(cocoa_view_); |
| 890 if (new_scale_factor == backing_store_scale_factor_) |
| 891 return; |
| 892 backing_store_scale_factor_ = new_scale_factor; |
| 893 |
739 render_widget_host_->NotifyScreenInfoChanged(); | 894 render_widget_host_->NotifyScreenInfoChanged(); |
740 } | 895 } |
741 | 896 |
742 RenderWidgetHost* RenderWidgetHostViewMac::GetRenderWidgetHost() const { | 897 RenderWidgetHost* RenderWidgetHostViewMac::GetRenderWidgetHost() const { |
743 return render_widget_host_; | 898 return render_widget_host_; |
744 } | 899 } |
745 | 900 |
746 void RenderWidgetHostViewMac::WasShown() { | 901 void RenderWidgetHostViewMac::WasShown() { |
747 if (!render_widget_host_->is_hidden()) | 902 if (!render_widget_host_->is_hidden()) |
748 return; | 903 return; |
749 | 904 |
750 ui::LatencyInfo renderer_latency_info; | 905 ui::LatencyInfo renderer_latency_info; |
751 renderer_latency_info.AddLatencyNumber( | 906 if ((compositing_iosurface_ && compositing_iosurface_->HasIOSurface()) || |
752 ui::TAB_SHOW_COMPONENT, | 907 software_frame_manager_->HasCurrentFrame() || |
753 render_widget_host_->GetLatencyComponentId(), | 908 (delegated_frame_host_ && delegated_frame_host_->HasSavedFrame())) { |
754 0); | 909 ui::LatencyInfo browser_latency_info; |
| 910 browser_latency_info.AddLatencyNumber( |
| 911 ui::TAB_SHOW_COMPONENT, |
| 912 render_widget_host_->GetLatencyComponentId(), |
| 913 0); |
| 914 pending_latency_info_.push_back(browser_latency_info); |
| 915 } else { |
| 916 renderer_latency_info.AddLatencyNumber( |
| 917 ui::TAB_SHOW_COMPONENT, |
| 918 render_widget_host_->GetLatencyComponentId(), |
| 919 0); |
| 920 } |
| 921 |
755 render_widget_host_->WasShown(renderer_latency_info); | 922 render_widget_host_->WasShown(renderer_latency_info); |
| 923 software_frame_manager_->SetVisibility(true); |
756 | 924 |
757 // If there is not a frame being currently drawn, kick one, so that the below | 925 // If there is not a frame being currently drawn, kick one, so that the below |
758 // pause will have a frame to wait on. | 926 // pause will have a frame to wait on. |
759 render_widget_host_->ScheduleComposite(); | 927 if (IsDelegatedRendererEnabled()) |
| 928 render_widget_host_->ScheduleComposite(); |
| 929 |
| 930 // Call setNeedsDisplay before pausing for new frames to come in -- if any |
| 931 // do, and are drawn, then the needsDisplay bit will be cleared. |
| 932 [compositing_iosurface_layer_ setNeedsDisplay]; |
760 PauseForPendingResizeOrRepaintsAndDraw(); | 933 PauseForPendingResizeOrRepaintsAndDraw(); |
761 } | 934 } |
762 | 935 |
763 void RenderWidgetHostViewMac::WasHidden() { | 936 void RenderWidgetHostViewMac::WasHidden() { |
764 if (render_widget_host_->is_hidden()) | 937 if (render_widget_host_->is_hidden()) |
765 return; | 938 return; |
766 | 939 |
| 940 // Any pending frames will not be displayed until this is shown again. Ack |
| 941 // them now. |
| 942 SendPendingSwapAck(); |
| 943 |
767 DestroyBrowserCompositorView(); | 944 DestroyBrowserCompositorView(); |
768 | 945 |
769 // If we have a renderer, then inform it that we are being hidden so it can | 946 // If we have a renderer, then inform it that we are being hidden so it can |
770 // reduce its resource utilization. | 947 // reduce its resource utilization. |
771 render_widget_host_->WasHidden(); | 948 render_widget_host_->WasHidden(); |
| 949 software_frame_manager_->SetVisibility(false); |
772 } | 950 } |
773 | 951 |
774 void RenderWidgetHostViewMac::SetSize(const gfx::Size& size) { | 952 void RenderWidgetHostViewMac::SetSize(const gfx::Size& size) { |
775 gfx::Rect rect = GetViewBounds(); | 953 gfx::Rect rect = GetViewBounds(); |
776 rect.set_size(size); | 954 rect.set_size(size); |
777 SetBounds(rect); | 955 SetBounds(rect); |
778 } | 956 } |
779 | 957 |
780 void RenderWidgetHostViewMac::SetBounds(const gfx::Rect& rect) { | 958 void RenderWidgetHostViewMac::SetBounds(const gfx::Rect& rect) { |
781 // |rect.size()| is view coordinates, |rect.origin| is screen coordinates, | 959 // |rect.size()| is view coordinates, |rect.origin| is screen coordinates, |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
855 [[cocoa_view_ window] makeFirstResponder:nil]; | 1033 [[cocoa_view_ window] makeFirstResponder:nil]; |
856 } | 1034 } |
857 | 1035 |
858 bool RenderWidgetHostViewMac::HasFocus() const { | 1036 bool RenderWidgetHostViewMac::HasFocus() const { |
859 return [[cocoa_view_ window] firstResponder] == cocoa_view_; | 1037 return [[cocoa_view_ window] firstResponder] == cocoa_view_; |
860 } | 1038 } |
861 | 1039 |
862 bool RenderWidgetHostViewMac::IsSurfaceAvailableForCopy() const { | 1040 bool RenderWidgetHostViewMac::IsSurfaceAvailableForCopy() const { |
863 if (delegated_frame_host_) | 1041 if (delegated_frame_host_) |
864 return delegated_frame_host_->CanCopyToBitmap(); | 1042 return delegated_frame_host_->CanCopyToBitmap(); |
865 return false; | 1043 |
| 1044 return software_frame_manager_->HasCurrentFrame() || |
| 1045 (compositing_iosurface_ && compositing_iosurface_->HasIOSurface()); |
866 } | 1046 } |
867 | 1047 |
868 void RenderWidgetHostViewMac::Show() { | 1048 void RenderWidgetHostViewMac::Show() { |
869 [cocoa_view_ setHidden:NO]; | 1049 [cocoa_view_ setHidden:NO]; |
870 | 1050 |
871 WasShown(); | 1051 WasShown(); |
872 } | 1052 } |
873 | 1053 |
874 void RenderWidgetHostViewMac::Hide() { | 1054 void RenderWidgetHostViewMac::Hide() { |
875 [cocoa_view_ setHidden:YES]; | 1055 [cocoa_view_ setHidden:YES]; |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1106 } | 1286 } |
1107 | 1287 |
1108 void RenderWidgetHostViewMac::CopyFromCompositingSurface( | 1288 void RenderWidgetHostViewMac::CopyFromCompositingSurface( |
1109 const gfx::Rect& src_subrect, | 1289 const gfx::Rect& src_subrect, |
1110 const gfx::Size& dst_size, | 1290 const gfx::Size& dst_size, |
1111 const base::Callback<void(bool, const SkBitmap&)>& callback, | 1291 const base::Callback<void(bool, const SkBitmap&)>& callback, |
1112 const SkColorType color_type) { | 1292 const SkColorType color_type) { |
1113 if (delegated_frame_host_) { | 1293 if (delegated_frame_host_) { |
1114 delegated_frame_host_->CopyFromCompositingSurface( | 1294 delegated_frame_host_->CopyFromCompositingSurface( |
1115 src_subrect, dst_size, callback, color_type); | 1295 src_subrect, dst_size, callback, color_type); |
| 1296 return; |
| 1297 } |
| 1298 |
| 1299 if (color_type != kN32_SkColorType) { |
| 1300 NOTIMPLEMENTED(); |
| 1301 callback.Run(false, SkBitmap()); |
| 1302 } |
| 1303 base::ScopedClosureRunner scoped_callback_runner( |
| 1304 base::Bind(callback, false, SkBitmap())); |
| 1305 float scale = ui::GetScaleFactorForNativeView(cocoa_view_); |
| 1306 gfx::Size dst_pixel_size = gfx::ToFlooredSize( |
| 1307 gfx::ScaleSize(dst_size, scale)); |
| 1308 if (compositing_iosurface_ && compositing_iosurface_->HasIOSurface()) { |
| 1309 ignore_result(scoped_callback_runner.Release()); |
| 1310 compositing_iosurface_->CopyTo(GetScaledOpenGLPixelRect(src_subrect), |
| 1311 dst_pixel_size, |
| 1312 callback); |
| 1313 } else if (software_frame_manager_->HasCurrentFrame()) { |
| 1314 gfx::Rect src_pixel_rect = gfx::ToEnclosingRect(gfx::ScaleRect( |
| 1315 src_subrect, |
| 1316 software_frame_manager_->GetCurrentFrameDeviceScaleFactor())); |
| 1317 SkBitmap source_bitmap; |
| 1318 SkImageInfo source_info = SkImageInfo::MakeN32( |
| 1319 software_frame_manager_->GetCurrentFrameSizeInPixels().width(), |
| 1320 software_frame_manager_->GetCurrentFrameSizeInPixels().height(), |
| 1321 kOpaque_SkAlphaType); |
| 1322 source_bitmap.installPixels( |
| 1323 source_info, |
| 1324 software_frame_manager_->GetCurrentFramePixels(), |
| 1325 source_info.minRowBytes()); |
| 1326 |
| 1327 SkBitmap target_bitmap; |
| 1328 if (!target_bitmap.allocN32Pixels( |
| 1329 dst_pixel_size.width(), dst_pixel_size.height(), true)) |
| 1330 return; |
| 1331 |
| 1332 SkCanvas target_canvas(target_bitmap); |
| 1333 SkRect src_pixel_skrect = SkRect::MakeXYWH( |
| 1334 src_pixel_rect.x(), src_pixel_rect.y(), |
| 1335 src_pixel_rect.width(), src_pixel_rect.height()); |
| 1336 target_canvas.drawBitmapRectToRect( |
| 1337 source_bitmap, |
| 1338 &src_pixel_skrect, |
| 1339 SkRect::MakeXYWH(0, 0, dst_pixel_size.width(), dst_pixel_size.height()), |
| 1340 NULL, |
| 1341 SkCanvas::kNone_DrawBitmapRectFlag); |
| 1342 |
| 1343 ignore_result(scoped_callback_runner.Release()); |
| 1344 callback.Run(true, target_bitmap); |
| 1345 } else { |
| 1346 callback.Run(false, SkBitmap()); |
1116 } | 1347 } |
1117 } | 1348 } |
1118 | 1349 |
1119 void RenderWidgetHostViewMac::CopyFromCompositingSurfaceToVideoFrame( | 1350 void RenderWidgetHostViewMac::CopyFromCompositingSurfaceToVideoFrame( |
1120 const gfx::Rect& src_subrect, | 1351 const gfx::Rect& src_subrect, |
1121 const scoped_refptr<media::VideoFrame>& target, | 1352 const scoped_refptr<media::VideoFrame>& target, |
1122 const base::Callback<void(bool)>& callback) { | 1353 const base::Callback<void(bool)>& callback) { |
1123 if (delegated_frame_host_) { | 1354 if (delegated_frame_host_) { |
1124 delegated_frame_host_->CopyFromCompositingSurfaceToVideoFrame( | 1355 delegated_frame_host_->CopyFromCompositingSurfaceToVideoFrame( |
1125 src_subrect, target, callback); | 1356 src_subrect, target, callback); |
| 1357 return; |
1126 } | 1358 } |
| 1359 |
| 1360 base::ScopedClosureRunner scoped_callback_runner(base::Bind(callback, false)); |
| 1361 if (!compositing_iosurface_ || !compositing_iosurface_->HasIOSurface()) |
| 1362 return; |
| 1363 |
| 1364 if (!target.get()) { |
| 1365 NOTREACHED(); |
| 1366 return; |
| 1367 } |
| 1368 |
| 1369 if (target->format() != media::VideoFrame::YV12 && |
| 1370 target->format() != media::VideoFrame::I420) { |
| 1371 NOTREACHED(); |
| 1372 return; |
| 1373 } |
| 1374 |
| 1375 if (src_subrect.IsEmpty()) |
| 1376 return; |
| 1377 |
| 1378 ignore_result(scoped_callback_runner.Release()); |
| 1379 compositing_iosurface_->CopyToVideoFrame( |
| 1380 GetScaledOpenGLPixelRect(src_subrect), |
| 1381 target, |
| 1382 callback); |
1127 } | 1383 } |
1128 | 1384 |
1129 bool RenderWidgetHostViewMac::CanCopyToVideoFrame() const { | 1385 bool RenderWidgetHostViewMac::CanCopyToVideoFrame() const { |
1130 if (delegated_frame_host_) | 1386 if (delegated_frame_host_) |
1131 return delegated_frame_host_->CanCopyToVideoFrame(); | 1387 return delegated_frame_host_->CanCopyToVideoFrame(); |
1132 return false; | 1388 |
| 1389 return (!software_frame_manager_->HasCurrentFrame() && |
| 1390 compositing_iosurface_ && |
| 1391 compositing_iosurface_->HasIOSurface()); |
1133 } | 1392 } |
1134 | 1393 |
1135 bool RenderWidgetHostViewMac::CanSubscribeFrame() const { | 1394 bool RenderWidgetHostViewMac::CanSubscribeFrame() const { |
1136 if (delegated_frame_host_) | 1395 if (delegated_frame_host_) |
1137 return delegated_frame_host_->CanSubscribeFrame(); | 1396 return delegated_frame_host_->CanSubscribeFrame(); |
1138 return false; | 1397 |
| 1398 return !software_frame_manager_->HasCurrentFrame(); |
1139 } | 1399 } |
1140 | 1400 |
1141 void RenderWidgetHostViewMac::BeginFrameSubscription( | 1401 void RenderWidgetHostViewMac::BeginFrameSubscription( |
1142 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) { | 1402 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) { |
1143 if (delegated_frame_host_) | 1403 if (delegated_frame_host_) { |
1144 delegated_frame_host_->BeginFrameSubscription(subscriber.Pass()); | 1404 delegated_frame_host_->BeginFrameSubscription(subscriber.Pass()); |
| 1405 return; |
| 1406 } |
| 1407 frame_subscriber_ = subscriber.Pass(); |
1145 } | 1408 } |
1146 | 1409 |
1147 void RenderWidgetHostViewMac::EndFrameSubscription() { | 1410 void RenderWidgetHostViewMac::EndFrameSubscription() { |
1148 if (delegated_frame_host_) | 1411 if (delegated_frame_host_) { |
1149 delegated_frame_host_->EndFrameSubscription(); | 1412 delegated_frame_host_->EndFrameSubscription(); |
| 1413 return; |
| 1414 } |
| 1415 |
| 1416 frame_subscriber_.reset(); |
1150 } | 1417 } |
1151 | 1418 |
1152 // Sets whether or not to accept first responder status. | 1419 // Sets whether or not to accept first responder status. |
1153 void RenderWidgetHostViewMac::SetTakesFocusOnlyOnMouseDown(bool flag) { | 1420 void RenderWidgetHostViewMac::SetTakesFocusOnlyOnMouseDown(bool flag) { |
1154 [cocoa_view_ setTakesFocusOnlyOnMouseDown:flag]; | 1421 [cocoa_view_ setTakesFocusOnlyOnMouseDown:flag]; |
1155 } | 1422 } |
1156 | 1423 |
1157 void RenderWidgetHostViewMac::ForwardMouseEvent(const WebMouseEvent& event) { | 1424 void RenderWidgetHostViewMac::ForwardMouseEvent(const WebMouseEvent& event) { |
1158 if (render_widget_host_) | 1425 if (render_widget_host_) |
1159 render_widget_host_->ForwardMouseEvent(event); | 1426 render_widget_host_->ForwardMouseEvent(event); |
(...skipping 27 matching lines...) Expand all Loading... |
1187 } | 1454 } |
1188 | 1455 |
1189 void RenderWidgetHostViewMac::PluginImeCompositionCompleted( | 1456 void RenderWidgetHostViewMac::PluginImeCompositionCompleted( |
1190 const base::string16& text, int plugin_id) { | 1457 const base::string16& text, int plugin_id) { |
1191 if (render_widget_host_) { | 1458 if (render_widget_host_) { |
1192 render_widget_host_->Send(new ViewMsg_PluginImeCompositionCompleted( | 1459 render_widget_host_->Send(new ViewMsg_PluginImeCompositionCompleted( |
1193 render_widget_host_->GetRoutingID(), text, plugin_id)); | 1460 render_widget_host_->GetRoutingID(), text, plugin_id)); |
1194 } | 1461 } |
1195 } | 1462 } |
1196 | 1463 |
| 1464 void RenderWidgetHostViewMac::CompositorSwapBuffers( |
| 1465 IOSurfaceID surface_handle, |
| 1466 const gfx::Rect& damage_rect, |
| 1467 const gfx::Size& size, |
| 1468 float surface_scale_factor, |
| 1469 const std::vector<ui::LatencyInfo>& latency_info) { |
| 1470 // Ensure that the frame be acked unless it is explicitly passed to a |
| 1471 // display function. |
| 1472 base::ScopedClosureRunner scoped_ack( |
| 1473 base::Bind(&RenderWidgetHostViewMac::SendPendingSwapAck, |
| 1474 weak_factory_.GetWeakPtr())); |
| 1475 |
| 1476 if (render_widget_host_->is_hidden()) |
| 1477 return; |
| 1478 |
| 1479 // Ensure that if this function exits before the frame is set up (but not |
| 1480 // necessarily drawn) then it is treated as an error. |
| 1481 base::ScopedClosureRunner scoped_error( |
| 1482 base::Bind(&RenderWidgetHostViewMac::GotAcceleratedCompositingError, |
| 1483 weak_factory_.GetWeakPtr())); |
| 1484 |
| 1485 AddPendingLatencyInfo(latency_info); |
| 1486 |
| 1487 // If compositing_iosurface_ exists and has been poisoned, destroy it |
| 1488 // and allow EnsureCompositedIOSurface to recreate it below. Keep a |
| 1489 // reference to the destroyed layer around until after the below call |
| 1490 // to LayoutLayers, to avoid flickers. |
| 1491 base::ScopedClosureRunner scoped_layer_remover; |
| 1492 if (compositing_iosurface_context_ && |
| 1493 compositing_iosurface_context_->HasBeenPoisoned()) { |
| 1494 scoped_layer_remover.Reset( |
| 1495 base::Bind(RemoveLayerFromSuperlayer, compositing_iosurface_layer_)); |
| 1496 DestroyCompositedIOSurfaceLayer(kLeaveLayerInHierarchy); |
| 1497 DestroyCompositedIOSurfaceAndLayer(); |
| 1498 } |
| 1499 |
| 1500 // Ensure compositing_iosurface_ and compositing_iosurface_context_ be |
| 1501 // allocated. |
| 1502 if (!EnsureCompositedIOSurface()) { |
| 1503 LOG(ERROR) << "Failed EnsureCompositingIOSurface"; |
| 1504 return; |
| 1505 } |
| 1506 |
| 1507 // Make the context current and update the IOSurface with the handle |
| 1508 // passed in by the swap command. |
| 1509 { |
| 1510 gfx::ScopedCGLSetCurrentContext scoped_set_current_context( |
| 1511 compositing_iosurface_context_->cgl_context()); |
| 1512 if (!compositing_iosurface_->SetIOSurfaceWithContextCurrent( |
| 1513 compositing_iosurface_context_, surface_handle, size, |
| 1514 surface_scale_factor)) { |
| 1515 LOG(ERROR) << "Failed SetIOSurface on CompositingIOSurfaceMac"; |
| 1516 return; |
| 1517 } |
| 1518 } |
| 1519 |
| 1520 // Grab video frames now that the IOSurface has been set up. Note that this |
| 1521 // will be done in an offscreen context, so it is necessary to re-set the |
| 1522 // current context afterward. |
| 1523 bool frame_was_captured = false; |
| 1524 if (frame_subscriber_) { |
| 1525 const base::TimeTicks now = gfx::FrameTime::Now(); |
| 1526 base::TimeTicks present_time; |
| 1527 if (vsync_timebase_.is_null() || vsync_interval_ <= base::TimeDelta()) { |
| 1528 present_time = now; |
| 1529 } else { |
| 1530 const int64 intervals_elapsed = (now - vsync_timebase_) / vsync_interval_; |
| 1531 present_time = vsync_timebase_ + |
| 1532 (intervals_elapsed + 1) * vsync_interval_; |
| 1533 } |
| 1534 |
| 1535 scoped_refptr<media::VideoFrame> frame; |
| 1536 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback; |
| 1537 if (frame_subscriber_->ShouldCaptureFrame( |
| 1538 damage_rect, present_time, &frame, &callback)) { |
| 1539 // Flush the context that updated the IOSurface, to ensure that the |
| 1540 // context that does the copy picks up the correct version. |
| 1541 { |
| 1542 gfx::ScopedCGLSetCurrentContext scoped_set_current_context( |
| 1543 compositing_iosurface_context_->cgl_context()); |
| 1544 glFlush(); |
| 1545 } |
| 1546 compositing_iosurface_->CopyToVideoFrame( |
| 1547 gfx::Rect(size), frame, |
| 1548 base::Bind(callback, present_time)); |
| 1549 frame_was_captured = true; |
| 1550 } |
| 1551 } |
| 1552 |
| 1553 // At this point the surface, its context, and its layer have been set up, so |
| 1554 // don't generate an error (one may be generated when drawing). |
| 1555 ignore_result(scoped_error.Release()); |
| 1556 |
| 1557 GotAcceleratedFrame(); |
| 1558 |
| 1559 gfx::Size window_size(NSSizeToCGSize([cocoa_view_ frame].size)); |
| 1560 if (window_size.IsEmpty()) { |
| 1561 // setNeedsDisplay will never display and we'll never ack if the window is |
| 1562 // empty, so ack now and don't bother calling setNeedsDisplay below. |
| 1563 return; |
| 1564 } |
| 1565 if (window_number() <= 0) { |
| 1566 // It's normal for a backgrounded tab that is being captured to have no |
| 1567 // window but not be hidden. Immediately ack the frame, and don't try to |
| 1568 // draw it. |
| 1569 if (frame_was_captured) |
| 1570 return; |
| 1571 |
| 1572 // If this frame was not captured, there is likely some sort of bug. Ack |
| 1573 // the frame and hope for the best. Because the IOSurface and layer are |
| 1574 // populated, it will likely be displayed when the view is added to a |
| 1575 // window's hierarchy. |
| 1576 |
| 1577 // TODO(shess) If the view does not have a window, or the window |
| 1578 // does not have backing, the IOSurface will log "invalid drawable" |
| 1579 // in -setView:. It is not clear how this code is reached with such |
| 1580 // a case, so record some info into breakpad (some subset of |
| 1581 // browsers are likely to crash later for unrelated reasons). |
| 1582 // http://crbug.com/148882 |
| 1583 const char* const kCrashKey = "rwhvm_window"; |
| 1584 NSWindow* window = [cocoa_view_ window]; |
| 1585 if (!window) { |
| 1586 base::debug::SetCrashKeyValue(kCrashKey, "Missing window"); |
| 1587 } else { |
| 1588 std::string value = |
| 1589 base::StringPrintf("window %s delegate %s controller %s", |
| 1590 object_getClassName(window), |
| 1591 object_getClassName([window delegate]), |
| 1592 object_getClassName([window windowController])); |
| 1593 base::debug::SetCrashKeyValue(kCrashKey, value); |
| 1594 } |
| 1595 return; |
| 1596 } |
| 1597 |
| 1598 // If we reach here, then the frame will be displayed by a future draw |
| 1599 // call, so don't make the callback. |
| 1600 ignore_result(scoped_ack.Release()); |
| 1601 DCHECK(compositing_iosurface_layer_); |
| 1602 [compositing_iosurface_layer_ gotNewFrame]; |
| 1603 |
| 1604 // Try to finish previous copy requests after draw to get better pipelining. |
| 1605 if (compositing_iosurface_) |
| 1606 compositing_iosurface_->CheckIfAllCopiesAreFinished(false); |
| 1607 |
| 1608 // The IOSurface's size may have changed, so re-layout the layers to take |
| 1609 // this into account. This may force an immediate draw. |
| 1610 LayoutLayers(); |
| 1611 } |
| 1612 |
| 1613 void RenderWidgetHostViewMac::GotAcceleratedCompositingError() { |
| 1614 LOG(ERROR) << "Encountered accelerated compositing error"; |
| 1615 base::MessageLoop::current()->PostTask( |
| 1616 FROM_HERE, |
| 1617 base::Bind(&RenderWidgetHostViewMac::DestroyCompositingStateOnError, |
| 1618 weak_factory_.GetWeakPtr())); |
| 1619 } |
| 1620 |
| 1621 void RenderWidgetHostViewMac::DestroyCompositingStateOnError() { |
| 1622 // This should be called with a clean stack. Make sure that no context is |
| 1623 // current. |
| 1624 DCHECK(!CGLGetCurrentContext()); |
| 1625 |
| 1626 // The existing GL contexts may be in a bad state, so don't re-use any of the |
| 1627 // existing ones anymore, rather, allocate new ones. |
| 1628 if (compositing_iosurface_context_) |
| 1629 compositing_iosurface_context_->PoisonContextAndSharegroup(); |
| 1630 |
| 1631 DestroyCompositedIOSurfaceAndLayer(); |
| 1632 |
| 1633 // Request that a new frame be generated and dirty the view. |
| 1634 if (render_widget_host_) |
| 1635 render_widget_host_->ScheduleComposite(); |
| 1636 [cocoa_view_ setNeedsDisplay:YES]; |
| 1637 |
| 1638 // TODO(ccameron): It may be a good idea to request that the renderer recreate |
| 1639 // its GL context as well, and fall back to software if this happens |
| 1640 // repeatedly. |
| 1641 } |
| 1642 |
1197 bool RenderWidgetHostViewMac::GetLineBreakIndex( | 1643 bool RenderWidgetHostViewMac::GetLineBreakIndex( |
1198 const std::vector<gfx::Rect>& bounds, | 1644 const std::vector<gfx::Rect>& bounds, |
1199 const gfx::Range& range, | 1645 const gfx::Range& range, |
1200 size_t* line_break_point) { | 1646 size_t* line_break_point) { |
1201 DCHECK(line_break_point); | 1647 DCHECK(line_break_point); |
1202 if (range.start() >= bounds.size() || range.is_reversed() || range.is_empty()) | 1648 if (range.start() >= bounds.size() || range.is_reversed() || range.is_empty()) |
1203 return false; | 1649 return false; |
1204 | 1650 |
1205 // We can't check line breaking completely from only rectangle array. Thus we | 1651 // We can't check line breaking completely from only rectangle array. Thus we |
1206 // assume the line breaking as the next character's y offset is larger than | 1652 // assume the line breaking as the next character's y offset is larger than |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1323 *actual_range = gfx::Range( | 1769 *actual_range = gfx::Range( |
1324 composition_range_.start() + ui_actual_range.start(), | 1770 composition_range_.start() + ui_actual_range.start(), |
1325 composition_range_.start() + ui_actual_range.end()).ToNSRange(); | 1771 composition_range_.start() + ui_actual_range.end()).ToNSRange(); |
1326 } | 1772 } |
1327 return true; | 1773 return true; |
1328 } | 1774 } |
1329 | 1775 |
1330 void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped( | 1776 void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped( |
1331 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, | 1777 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, |
1332 int gpu_host_id) { | 1778 int gpu_host_id) { |
| 1779 TRACE_EVENT0("browser", |
| 1780 "RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped"); |
| 1781 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1782 |
| 1783 AddPendingSwapAck(params.route_id, |
| 1784 gpu_host_id, |
| 1785 compositing_iosurface_ ? |
| 1786 compositing_iosurface_->GetRendererID() : 0); |
| 1787 |
| 1788 switch (GetSurfaceHandleType(params.surface_handle)) { |
| 1789 case kSurfaceHandleTypeIOSurface: { |
| 1790 IOSurfaceID io_surface_id = IOSurfaceIDFromSurfaceHandle( |
| 1791 params.surface_handle); |
| 1792 |
| 1793 CompositorSwapBuffers(io_surface_id, |
| 1794 gfx::Rect(), |
| 1795 params.size, |
| 1796 params.scale_factor, |
| 1797 params.latency_info); |
| 1798 } break; |
| 1799 case kSurfaceHandleTypeCAContext: { |
| 1800 // Disable the fade-out animation as the layer is added. |
| 1801 ScopedCAActionDisabler disabler; |
| 1802 |
| 1803 CAContextID context_id = CAContextIDFromSurfaceHandle( |
| 1804 params.surface_handle); |
| 1805 |
| 1806 // If if the layer has changed put the new layer in the hierarchy and |
| 1807 // take the old one out. |
| 1808 if ([remote_layer_host_ contextId] != context_id) { |
| 1809 [remote_layer_host_ removeFromSuperlayer]; |
| 1810 |
| 1811 remote_layer_host_.reset([[CALayerHost alloc] init]); |
| 1812 [remote_layer_host_ setContextId:context_id]; |
| 1813 [remote_layer_host_ |
| 1814 setAutoresizingMask:kCALayerMaxXMargin|kCALayerMaxYMargin]; |
| 1815 [flipped_layer_ addSublayer:remote_layer_host_]; |
| 1816 } |
| 1817 |
| 1818 // Ack the frame immediately. Any GPU back pressure will be applied by |
| 1819 // the remote layer from within the GPU process. |
| 1820 SendPendingSwapAck(); |
| 1821 } break; |
| 1822 default: |
| 1823 LOG(ERROR) << "Invalid surface handle type."; |
| 1824 break; |
| 1825 } |
1333 } | 1826 } |
1334 | 1827 |
1335 void RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer( | 1828 void RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer( |
1336 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params, | 1829 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params, |
1337 int gpu_host_id) { | 1830 int gpu_host_id) { |
| 1831 TRACE_EVENT0("browser", |
| 1832 "RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer"); |
| 1833 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1834 |
| 1835 AddPendingSwapAck(params.route_id, |
| 1836 gpu_host_id, |
| 1837 compositing_iosurface_ ? |
| 1838 compositing_iosurface_->GetRendererID() : 0); |
| 1839 CompositorSwapBuffers( |
| 1840 IOSurfaceIDFromSurfaceHandle(params.surface_handle), |
| 1841 gfx::Rect(params.x, params.y, params.width, params.height), |
| 1842 params.surface_size, |
| 1843 params.surface_scale_factor, |
| 1844 params.latency_info); |
1338 } | 1845 } |
1339 | 1846 |
1340 void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() { | 1847 void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() { |
| 1848 if (render_widget_host_->is_hidden()) |
| 1849 DestroyCompositedIOSurfaceAndLayer(); |
1341 } | 1850 } |
1342 | 1851 |
1343 void RenderWidgetHostViewMac::AcceleratedSurfaceRelease() { | 1852 void RenderWidgetHostViewMac::AcceleratedSurfaceRelease() { |
| 1853 DestroyCompositedIOSurfaceAndLayer(); |
1344 } | 1854 } |
1345 | 1855 |
1346 bool RenderWidgetHostViewMac::HasAcceleratedSurface( | 1856 bool RenderWidgetHostViewMac::HasAcceleratedSurface( |
1347 const gfx::Size& desired_size) { | 1857 const gfx::Size& desired_size) { |
1348 if (browser_compositor_view_) | 1858 if (browser_compositor_view_) |
1349 return browser_compositor_view_->HasFrameOfSize(desired_size); | 1859 return browser_compositor_view_->HasFrameOfSize(desired_size); |
| 1860 if (compositing_iosurface_) { |
| 1861 return compositing_iosurface_->HasIOSurface() && |
| 1862 (desired_size.IsEmpty() || |
| 1863 compositing_iosurface_->dip_io_surface_size() == desired_size); |
| 1864 } |
| 1865 if (software_frame_manager_->HasCurrentFrame()) { |
| 1866 return (desired_size.IsEmpty() || |
| 1867 software_frame_manager_->GetCurrentFrameSizeInDIP() == |
| 1868 desired_size); |
| 1869 } |
1350 return false; | 1870 return false; |
1351 } | 1871 } |
1352 | 1872 |
1353 void RenderWidgetHostViewMac::OnSwapCompositorFrame( | 1873 void RenderWidgetHostViewMac::OnSwapCompositorFrame( |
1354 uint32 output_surface_id, scoped_ptr<cc::CompositorFrame> frame) { | 1874 uint32 output_surface_id, scoped_ptr<cc::CompositorFrame> frame) { |
1355 TRACE_EVENT0("browser", "RenderWidgetHostViewMac::OnSwapCompositorFrame"); | 1875 TRACE_EVENT0("browser", "RenderWidgetHostViewMac::OnSwapCompositorFrame"); |
1356 | 1876 |
1357 if (frame->delegated_frame_data) { | 1877 if (frame->delegated_frame_data) { |
1358 float scale_factor = frame->metadata.device_scale_factor; | 1878 float scale_factor = frame->metadata.device_scale_factor; |
1359 | 1879 |
(...skipping 11 matching lines...) Expand all Loading... |
1371 scale_factor, pixel_size); | 1891 scale_factor, pixel_size); |
1372 } | 1892 } |
1373 | 1893 |
1374 SendVSyncParametersToRenderer(); | 1894 SendVSyncParametersToRenderer(); |
1375 | 1895 |
1376 delegated_frame_host_->SwapDelegatedFrame( | 1896 delegated_frame_host_->SwapDelegatedFrame( |
1377 output_surface_id, | 1897 output_surface_id, |
1378 frame->delegated_frame_data.Pass(), | 1898 frame->delegated_frame_data.Pass(), |
1379 frame->metadata.device_scale_factor, | 1899 frame->metadata.device_scale_factor, |
1380 frame->metadata.latency_info); | 1900 frame->metadata.latency_info); |
| 1901 } else if (frame->software_frame_data) { |
| 1902 if (!software_frame_manager_->SwapToNewFrame( |
| 1903 output_surface_id, |
| 1904 frame->software_frame_data.get(), |
| 1905 frame->metadata.device_scale_factor, |
| 1906 render_widget_host_->GetProcess()->GetHandle())) { |
| 1907 render_widget_host_->GetProcess()->ReceivedBadMessage(); |
| 1908 return; |
| 1909 } |
| 1910 |
| 1911 // Add latency info to report when the frame finishes drawing. |
| 1912 AddPendingLatencyInfo(frame->metadata.latency_info); |
| 1913 |
| 1914 const void* pixels = software_frame_manager_->GetCurrentFramePixels(); |
| 1915 gfx::Size size_in_pixels = |
| 1916 software_frame_manager_->GetCurrentFrameSizeInPixels(); |
| 1917 |
| 1918 EnsureSoftwareLayer(); |
| 1919 [software_layer_ setContentsToData:pixels |
| 1920 withRowBytes:4 * size_in_pixels.width() |
| 1921 withPixelSize:size_in_pixels |
| 1922 withScaleFactor:frame->metadata.device_scale_factor]; |
| 1923 |
| 1924 // Send latency information to the host immediately, as there will be no |
| 1925 // subsequent draw call in which to do so. |
| 1926 SendPendingLatencyInfoToHost(); |
| 1927 |
| 1928 GotSoftwareFrame(); |
| 1929 |
| 1930 cc::CompositorFrameAck ack; |
| 1931 RenderWidgetHostImpl::SendSwapCompositorFrameAck( |
| 1932 render_widget_host_->GetRoutingID(), |
| 1933 software_frame_manager_->GetCurrentFrameOutputSurfaceId(), |
| 1934 render_widget_host_->GetProcess()->GetID(), |
| 1935 ack); |
| 1936 software_frame_manager_->SwapToNewFrameComplete( |
| 1937 !render_widget_host_->is_hidden()); |
| 1938 |
| 1939 // Notify observers, tab capture observers in particular, that a new |
| 1940 // software frame has come in. |
| 1941 NotificationService::current()->Notify( |
| 1942 NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE, |
| 1943 Source<RenderWidgetHost>(render_widget_host_), |
| 1944 NotificationService::NoDetails()); |
1381 } else { | 1945 } else { |
1382 DLOG(ERROR) << "Received unexpected frame type."; | 1946 DLOG(ERROR) << "Received unexpected frame type."; |
1383 RecordAction( | 1947 RecordAction( |
1384 base::UserMetricsAction("BadMessageTerminate_UnexpectedFrameType")); | 1948 base::UserMetricsAction("BadMessageTerminate_UnexpectedFrameType")); |
1385 render_widget_host_->GetProcess()->ReceivedBadMessage(); | 1949 render_widget_host_->GetProcess()->ReceivedBadMessage(); |
1386 } | 1950 } |
1387 } | 1951 } |
1388 | 1952 |
1389 void RenderWidgetHostViewMac::AcceleratedSurfaceInitialized(int host_id, | 1953 void RenderWidgetHostViewMac::AcceleratedSurfaceInitialized(int host_id, |
1390 int route_id) { | 1954 int route_id) { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1451 [cocoa_view_ processedWheelEvent:event consumed:consumed]; | 2015 [cocoa_view_ processedWheelEvent:event consumed:consumed]; |
1452 } | 2016 } |
1453 | 2017 |
1454 bool RenderWidgetHostViewMac::Send(IPC::Message* message) { | 2018 bool RenderWidgetHostViewMac::Send(IPC::Message* message) { |
1455 if (render_widget_host_) | 2019 if (render_widget_host_) |
1456 return render_widget_host_->Send(message); | 2020 return render_widget_host_->Send(message); |
1457 delete message; | 2021 delete message; |
1458 return false; | 2022 return false; |
1459 } | 2023 } |
1460 | 2024 |
| 2025 void RenderWidgetHostViewMac::SoftwareFrameWasFreed( |
| 2026 uint32 output_surface_id, unsigned frame_id) { |
| 2027 if (!render_widget_host_) |
| 2028 return; |
| 2029 cc::CompositorFrameAck ack; |
| 2030 ack.last_software_frame_id = frame_id; |
| 2031 RenderWidgetHostImpl::SendReclaimCompositorResources( |
| 2032 render_widget_host_->GetRoutingID(), |
| 2033 output_surface_id, |
| 2034 render_widget_host_->GetProcess()->GetID(), |
| 2035 ack); |
| 2036 } |
| 2037 |
| 2038 void RenderWidgetHostViewMac::ReleaseReferencesToSoftwareFrame() { |
| 2039 DestroySoftwareLayer(); |
| 2040 } |
| 2041 |
1461 void RenderWidgetHostViewMac::ShutdownHost() { | 2042 void RenderWidgetHostViewMac::ShutdownHost() { |
1462 weak_factory_.InvalidateWeakPtrs(); | 2043 weak_factory_.InvalidateWeakPtrs(); |
1463 render_widget_host_->Shutdown(); | 2044 render_widget_host_->Shutdown(); |
1464 // Do not touch any members at this point, |this| has been deleted. | 2045 // Do not touch any members at this point, |this| has been deleted. |
1465 } | 2046 } |
1466 | 2047 |
1467 void RenderWidgetHostViewMac::ShutdownBrowserCompositor() { | 2048 void RenderWidgetHostViewMac::ShutdownBrowserCompositor() { |
1468 DestroyBrowserCompositorView(); | 2049 DestroyBrowserCompositorView(); |
1469 delegated_frame_host_.reset(); | 2050 delegated_frame_host_.reset(); |
1470 root_layer_.reset(); | 2051 root_layer_.reset(); |
1471 browser_compositor_view_placeholder_.reset(); | 2052 browser_compositor_view_placeholder_.reset(); |
1472 } | 2053 } |
1473 | 2054 |
| 2055 void RenderWidgetHostViewMac::GotAcceleratedFrame() { |
| 2056 EnsureCompositedIOSurfaceLayer(); |
| 2057 SendVSyncParametersToRenderer(); |
| 2058 |
| 2059 // Delete software backingstore and layer. |
| 2060 software_frame_manager_->DiscardCurrentFrame(); |
| 2061 DestroySoftwareLayer(); |
| 2062 } |
| 2063 |
| 2064 void RenderWidgetHostViewMac::GotSoftwareFrame() { |
| 2065 TRACE_EVENT0("browser", "RenderWidgetHostViewMac::GotSoftwareFrame"); |
| 2066 |
| 2067 if (!render_widget_host_) |
| 2068 return; |
| 2069 |
| 2070 EnsureSoftwareLayer(); |
| 2071 LayoutLayers(); |
| 2072 SendVSyncParametersToRenderer(); |
| 2073 |
| 2074 // Draw the contents of the frame immediately. It is critical that this |
| 2075 // happen before the frame be acked, otherwise the new frame will likely be |
| 2076 // ready before the drawing is complete, thrashing the browser main thread. |
| 2077 [software_layer_ displayIfNeeded]; |
| 2078 |
| 2079 DestroyCompositedIOSurfaceAndLayer(); |
| 2080 } |
| 2081 |
1474 void RenderWidgetHostViewMac::SetActive(bool active) { | 2082 void RenderWidgetHostViewMac::SetActive(bool active) { |
1475 if (render_widget_host_) { | 2083 if (render_widget_host_) { |
1476 render_widget_host_->SetActive(active); | 2084 render_widget_host_->SetActive(active); |
1477 if (active) { | 2085 if (active) { |
1478 if (HasFocus()) | 2086 if (HasFocus()) |
1479 render_widget_host_->Focus(); | 2087 render_widget_host_->Focus(); |
1480 } else { | 2088 } else { |
1481 render_widget_host_->Blur(); | 2089 render_widget_host_->Blur(); |
1482 } | 2090 } |
1483 } | 2091 } |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1572 | 2180 |
1573 void RenderWidgetHostViewMac::OnStartPluginIme() { | 2181 void RenderWidgetHostViewMac::OnStartPluginIme() { |
1574 [cocoa_view_ setPluginImeActive:YES]; | 2182 [cocoa_view_ setPluginImeActive:YES]; |
1575 } | 2183 } |
1576 | 2184 |
1577 void RenderWidgetHostViewMac::OnGetRenderedTextCompleted( | 2185 void RenderWidgetHostViewMac::OnGetRenderedTextCompleted( |
1578 const std::string& text) { | 2186 const std::string& text) { |
1579 SpeakText(text); | 2187 SpeakText(text); |
1580 } | 2188 } |
1581 | 2189 |
| 2190 gfx::Rect RenderWidgetHostViewMac::GetScaledOpenGLPixelRect( |
| 2191 const gfx::Rect& rect) { |
| 2192 gfx::Rect src_gl_subrect = rect; |
| 2193 src_gl_subrect.set_y(GetViewBounds().height() - rect.bottom()); |
| 2194 |
| 2195 return gfx::ToEnclosingRect(gfx::ScaleRect(src_gl_subrect, |
| 2196 ViewScaleFactor())); |
| 2197 } |
| 2198 |
| 2199 void RenderWidgetHostViewMac::AddPendingLatencyInfo( |
| 2200 const std::vector<ui::LatencyInfo>& latency_info) { |
| 2201 for (size_t i = 0; i < latency_info.size(); i++) { |
| 2202 pending_latency_info_.push_back(latency_info[i]); |
| 2203 } |
| 2204 } |
| 2205 |
| 2206 void RenderWidgetHostViewMac::SendPendingLatencyInfoToHost() { |
| 2207 for (size_t i = 0; i < pending_latency_info_.size(); i++) { |
| 2208 pending_latency_info_[i].AddLatencyNumber( |
| 2209 ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, 0); |
| 2210 render_widget_host_->FrameSwapped(pending_latency_info_[i]); |
| 2211 } |
| 2212 pending_latency_info_.clear(); |
| 2213 } |
| 2214 |
| 2215 void RenderWidgetHostViewMac::AddPendingSwapAck( |
| 2216 int32 route_id, int gpu_host_id, int32 renderer_id) { |
| 2217 // Note that multiple un-acked swaps can come in the event of a GPU process |
| 2218 // loss. Drop the old acks. |
| 2219 pending_swap_ack_.reset(new PendingSwapAck( |
| 2220 route_id, gpu_host_id, renderer_id)); |
| 2221 } |
| 2222 |
| 2223 void RenderWidgetHostViewMac::SendPendingSwapAck() { |
| 2224 if (!pending_swap_ack_) |
| 2225 return; |
| 2226 |
| 2227 AcceleratedSurfaceMsg_BufferPresented_Params ack_params; |
| 2228 ack_params.sync_point = 0; |
| 2229 ack_params.renderer_id = pending_swap_ack_->renderer_id; |
| 2230 RenderWidgetHostImpl::AcknowledgeBufferPresent(pending_swap_ack_->route_id, |
| 2231 pending_swap_ack_->gpu_host_id, |
| 2232 ack_params); |
| 2233 pending_swap_ack_.reset(); |
| 2234 } |
| 2235 |
1582 void RenderWidgetHostViewMac::PauseForPendingResizeOrRepaintsAndDraw() { | 2236 void RenderWidgetHostViewMac::PauseForPendingResizeOrRepaintsAndDraw() { |
1583 if (!render_widget_host_ || render_widget_host_->is_hidden()) | 2237 if (!render_widget_host_ || render_widget_host_->is_hidden()) |
1584 return; | 2238 return; |
1585 | 2239 |
1586 // Pausing for one view prevents others from receiving frames. | 2240 // Pausing for one view prevents others from receiving frames. |
1587 // This may lead to large delays, causing overlaps. See crbug.com/352020. | 2241 // This may lead to large delays, causing overlaps. See crbug.com/352020. |
1588 if (!allow_pause_for_resize_or_repaint_) | 2242 if (!allow_pause_for_resize_or_repaint_) |
1589 return; | 2243 return; |
1590 | 2244 |
| 2245 // Ensure that all frames are acked before waiting for a frame to come in. |
| 2246 // Note that we will draw a frame at the end of this function, so it is safe |
| 2247 // to ack a never-drawn frame here. |
| 2248 SendPendingSwapAck(); |
| 2249 |
1591 // Wait for a frame of the right size to come in. | 2250 // Wait for a frame of the right size to come in. |
1592 if (browser_compositor_view_) | 2251 if (browser_compositor_view_) |
1593 browser_compositor_view_->BeginPumpingFrames(); | 2252 browser_compositor_view_->BeginPumpingFrames(); |
1594 render_widget_host_->PauseForPendingResizeOrRepaints(); | 2253 render_widget_host_->PauseForPendingResizeOrRepaints(); |
1595 if (browser_compositor_view_) | 2254 if (browser_compositor_view_) |
1596 browser_compositor_view_->EndPumpingFrames(); | 2255 browser_compositor_view_->EndPumpingFrames(); |
| 2256 |
| 2257 // Immediately draw any frames that haven't been drawn yet. This is necessary |
| 2258 // to keep the window and the window's contents in sync. |
| 2259 [cocoa_view_ displayIfNeeded]; |
| 2260 [software_layer_ displayIfNeeded]; |
| 2261 [compositing_iosurface_layer_ displayIfNeededAndAck]; |
| 2262 } |
| 2263 |
| 2264 void RenderWidgetHostViewMac::LayoutLayers() { |
| 2265 if (delegated_frame_host_) { |
| 2266 return; |
| 2267 } |
| 2268 |
| 2269 // Disable animation of the layer's resizing or change in contents scale. |
| 2270 ScopedCAActionDisabler disabler; |
| 2271 |
| 2272 // Dynamically calling setContentsScale on a CAOpenGLLayer for which |
| 2273 // setAsynchronous is dynamically toggled can result in flashes of corrupt |
| 2274 // content. Work around this by replacing the entire layer when the scale |
| 2275 // factor changes. |
| 2276 if (compositing_iosurface_ && |
| 2277 [compositing_iosurface_layer_ |
| 2278 respondsToSelector:(@selector(contentsScale))]) { |
| 2279 if (compositing_iosurface_->scale_factor() != |
| 2280 [compositing_iosurface_layer_ contentsScale]) { |
| 2281 DestroyCompositedIOSurfaceLayer(kRemoveLayerFromHierarchy); |
| 2282 EnsureCompositedIOSurfaceLayer(); |
| 2283 } |
| 2284 } |
| 2285 if (compositing_iosurface_ && |
| 2286 compositing_iosurface_->HasIOSurface() && |
| 2287 compositing_iosurface_layer_) { |
| 2288 CGRect layer_bounds = CGRectMake( |
| 2289 0, |
| 2290 0, |
| 2291 compositing_iosurface_->dip_io_surface_size().width(), |
| 2292 compositing_iosurface_->dip_io_surface_size().height()); |
| 2293 bool bounds_changed = !CGRectEqualToRect( |
| 2294 layer_bounds, [compositing_iosurface_layer_ bounds]); |
| 2295 [compositing_iosurface_layer_ setBounds:layer_bounds]; |
| 2296 |
| 2297 // If the bounds changed, then draw the frame immediately, to ensure that |
| 2298 // content displayed is in sync with the window size. |
| 2299 if (bounds_changed) { |
| 2300 // Also, sometimes, especially when infobars are being removed, the |
| 2301 // setNeedsDisplay calls are dropped on the floor, and stale content is |
| 2302 // displayed. Calling displayIfNeeded will ensure that the right size |
| 2303 // frame is drawn to the screen. |
| 2304 // http://crbug.com/350817 |
| 2305 [compositing_iosurface_layer_ setNeedsDisplayAndDisplayAndAck]; |
| 2306 } |
| 2307 } |
1597 } | 2308 } |
1598 | 2309 |
1599 SkColorType RenderWidgetHostViewMac::PreferredReadbackFormat() { | 2310 SkColorType RenderWidgetHostViewMac::PreferredReadbackFormat() { |
1600 return kN32_SkColorType; | 2311 return kN32_SkColorType; |
1601 } | 2312 } |
1602 | 2313 |
1603 //////////////////////////////////////////////////////////////////////////////// | 2314 //////////////////////////////////////////////////////////////////////////////// |
1604 // CompositingIOSurfaceLayerClient, public: | 2315 // CompositingIOSurfaceLayerClient, public: |
1605 | 2316 |
1606 bool RenderWidgetHostViewMac::AcceleratedLayerShouldAckImmediately() const { | 2317 bool RenderWidgetHostViewMac::AcceleratedLayerShouldAckImmediately() const { |
1607 // If vsync is disabled, then always draw and ack frames immediately. | 2318 // If vsync is disabled, then always draw and ack frames immediately. |
1608 static bool is_vsync_disabled = | 2319 static bool is_vsync_disabled = |
1609 base::CommandLine::ForCurrentProcess()->HasSwitch( | 2320 base::CommandLine::ForCurrentProcess()->HasSwitch( |
1610 switches::kDisableGpuVsync); | 2321 switches::kDisableGpuVsync); |
1611 if (is_vsync_disabled) | 2322 if (is_vsync_disabled) |
1612 return true; | 2323 return true; |
1613 | 2324 |
1614 // If the window is occluded, then this frame's display call may be severely | 2325 // If the window is occluded, then this frame's display call may be severely |
1615 // throttled. This is a good thing, unless tab capture may be active, because | 2326 // throttled. This is a good thing, unless tab capture may be active, because |
1616 // the broadcast will be inappropriately throttled. | 2327 // the broadcast will be inappropriately throttled. |
1617 // http://crbug.com/350410 | 2328 // http://crbug.com/350410 |
1618 | 2329 |
1619 // If tab capture isn't active then only ack frames when we draw them. | 2330 // If tab capture isn't active then only ack frames when we draw them. |
1620 if (delegated_frame_host_ && !delegated_frame_host_->HasFrameSubscriber()) | 2331 if (delegated_frame_host_) { |
1621 return false; | 2332 if (!delegated_frame_host_->HasFrameSubscriber()) |
| 2333 return false; |
| 2334 } else { |
| 2335 if (!frame_subscriber_) |
| 2336 return false; |
| 2337 } |
1622 | 2338 |
1623 NSWindow* window = [cocoa_view_ window]; | 2339 NSWindow* window = [cocoa_view_ window]; |
1624 // If the view isn't even in the heirarchy then frames will never be drawn, | 2340 // If the view isn't even in the heirarchy then frames will never be drawn, |
1625 // so ack them immediately. | 2341 // so ack them immediately. |
1626 if (!window) | 2342 if (!window) |
1627 return true; | 2343 return true; |
1628 | 2344 |
1629 // Check the window occlusion API. | 2345 // Check the window occlusion API. |
1630 if ([window respondsToSelector:@selector(occlusionState)]) { | 2346 if ([window respondsToSelector:@selector(occlusionState)]) { |
1631 if ([window occlusionState] & NSWindowOcclusionStateVisible) { | 2347 if ([window occlusionState] & NSWindowOcclusionStateVisible) { |
1632 // If the window is visible then it is safe to wait until frames are | 2348 // If the window is visible then it is safe to wait until frames are |
1633 // drawn to ack them. | 2349 // drawn to ack them. |
1634 return false; | 2350 return false; |
1635 } else { | 2351 } else { |
1636 // If the window is occluded then frames may never be drawn, so ack them | 2352 // If the window is occluded then frames may never be drawn, so ack them |
1637 // immediately. | 2353 // immediately. |
1638 return true; | 2354 return true; |
1639 } | 2355 } |
1640 } | 2356 } |
1641 | 2357 |
1642 // If the window occlusion API is not present then ack frames when we draw | 2358 // If the window occlusion API is not present then ack frames when we draw |
1643 // them. | 2359 // them. |
1644 return false; | 2360 return false; |
1645 } | 2361 } |
1646 | 2362 |
1647 void RenderWidgetHostViewMac::AcceleratedLayerDidDrawFrame() { | 2363 void RenderWidgetHostViewMac::AcceleratedLayerDidDrawFrame() { |
| 2364 if (!render_widget_host_) |
| 2365 return; |
| 2366 |
| 2367 SendPendingLatencyInfoToHost(); |
| 2368 SendPendingSwapAck(); |
1648 } | 2369 } |
1649 | 2370 |
1650 void RenderWidgetHostViewMac::AcceleratedLayerHitError() { | 2371 void RenderWidgetHostViewMac::AcceleratedLayerHitError() { |
| 2372 if (!render_widget_host_) |
| 2373 return; |
| 2374 // Perform all acks that would have been done if the frame had succeeded, to |
| 2375 // un-block the renderer. |
| 2376 AcceleratedLayerDidDrawFrame(); |
| 2377 GotAcceleratedCompositingError(); |
1651 } | 2378 } |
1652 | 2379 |
1653 //////////////////////////////////////////////////////////////////////////////// | 2380 //////////////////////////////////////////////////////////////////////////////// |
1654 // gfx::DisplayObserver, public: | 2381 // gfx::DisplayObserver, public: |
1655 | 2382 |
1656 void RenderWidgetHostViewMac::OnDisplayAdded(const gfx::Display& display) { | 2383 void RenderWidgetHostViewMac::OnDisplayAdded(const gfx::Display& display) { |
1657 } | 2384 } |
1658 | 2385 |
1659 void RenderWidgetHostViewMac::OnDisplayRemoved(const gfx::Display& display) { | 2386 void RenderWidgetHostViewMac::OnDisplayRemoved(const gfx::Display& display) { |
1660 } | 2387 } |
(...skipping 19 matching lines...) Expand all Loading... |
1680 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { | 2407 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { |
1681 self = [super initWithFrame:NSZeroRect]; | 2408 self = [super initWithFrame:NSZeroRect]; |
1682 if (self) { | 2409 if (self) { |
1683 self.acceptsTouchEvents = YES; | 2410 self.acceptsTouchEvents = YES; |
1684 editCommand_helper_.reset(new RenderWidgetHostViewMacEditCommandHelper); | 2411 editCommand_helper_.reset(new RenderWidgetHostViewMacEditCommandHelper); |
1685 editCommand_helper_->AddEditingSelectorsToClass([self class]); | 2412 editCommand_helper_->AddEditingSelectorsToClass([self class]); |
1686 | 2413 |
1687 renderWidgetHostView_.reset(r); | 2414 renderWidgetHostView_.reset(r); |
1688 canBeKeyView_ = YES; | 2415 canBeKeyView_ = YES; |
1689 focusedPluginIdentifier_ = -1; | 2416 focusedPluginIdentifier_ = -1; |
| 2417 renderWidgetHostView_->backing_store_scale_factor_ = |
| 2418 ui::GetScaleFactorForNativeView(self); |
1690 | 2419 |
1691 // OpenGL support: | 2420 // OpenGL support: |
1692 if ([self respondsToSelector: | 2421 if ([self respondsToSelector: |
1693 @selector(setWantsBestResolutionOpenGLSurface:)]) { | 2422 @selector(setWantsBestResolutionOpenGLSurface:)]) { |
1694 [self setWantsBestResolutionOpenGLSurface:YES]; | 2423 [self setWantsBestResolutionOpenGLSurface:YES]; |
1695 } | 2424 } |
| 2425 handlingGlobalFrameDidChange_ = NO; |
1696 [[NSNotificationCenter defaultCenter] | 2426 [[NSNotificationCenter defaultCenter] |
1697 addObserver:self | 2427 addObserver:self |
1698 selector:@selector(didChangeScreenParameters:) | 2428 selector:@selector(didChangeScreenParameters:) |
1699 name:NSApplicationDidChangeScreenParametersNotification | 2429 name:NSApplicationDidChangeScreenParametersNotification |
1700 object:nil]; | 2430 object:nil]; |
1701 } | 2431 } |
1702 return self; | 2432 return self; |
1703 } | 2433 } |
1704 | 2434 |
1705 - (void)dealloc { | 2435 - (void)dealloc { |
(...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2399 - (void)setFrameSize:(NSSize)newSize { | 3129 - (void)setFrameSize:(NSSize)newSize { |
2400 TRACE_EVENT0("browser", "RenderWidgetHostViewCocoa::setFrameSize"); | 3130 TRACE_EVENT0("browser", "RenderWidgetHostViewCocoa::setFrameSize"); |
2401 | 3131 |
2402 // NB: -[NSView setFrame:] calls through -setFrameSize:, so overriding | 3132 // NB: -[NSView setFrame:] calls through -setFrameSize:, so overriding |
2403 // -setFrame: isn't neccessary. | 3133 // -setFrame: isn't neccessary. |
2404 [super setFrameSize:newSize]; | 3134 [super setFrameSize:newSize]; |
2405 | 3135 |
2406 if (!renderWidgetHostView_->render_widget_host_) | 3136 if (!renderWidgetHostView_->render_widget_host_) |
2407 return; | 3137 return; |
2408 | 3138 |
| 3139 // Move the CALayers to their positions in the new view size. Note that |
| 3140 // this will not draw anything because the non-background layers' sizes |
| 3141 // didn't actually change. |
| 3142 renderWidgetHostView_->LayoutLayers(); |
| 3143 |
2409 renderWidgetHostView_->render_widget_host_->SendScreenRects(); | 3144 renderWidgetHostView_->render_widget_host_->SendScreenRects(); |
2410 renderWidgetHostView_->render_widget_host_->WasResized(); | 3145 renderWidgetHostView_->render_widget_host_->WasResized(); |
2411 if (renderWidgetHostView_->delegated_frame_host_) | 3146 if (renderWidgetHostView_->delegated_frame_host_) |
2412 renderWidgetHostView_->delegated_frame_host_->WasResized(); | 3147 renderWidgetHostView_->delegated_frame_host_->WasResized(); |
2413 | 3148 |
2414 // Wait for the frame that WasResize might have requested. If the view is | 3149 // Wait for the frame that WasResize might have requested. If the view is |
2415 // being made visible at a new size, then this call will have no effect | 3150 // being made visible at a new size, then this call will have no effect |
2416 // because the view widget is still hidden, and the pause call in WasShown | 3151 // because the view widget is still hidden, and the pause call in WasShown |
2417 // will have this effect for us. | 3152 // will have this effect for us. |
2418 renderWidgetHostView_->PauseForPendingResizeOrRepaintsAndDraw(); | 3153 renderWidgetHostView_->PauseForPendingResizeOrRepaintsAndDraw(); |
(...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3355 | 4090 |
3356 // "-webkit-app-region: drag | no-drag" is implemented on Mac by excluding | 4091 // "-webkit-app-region: drag | no-drag" is implemented on Mac by excluding |
3357 // regions that are not draggable. (See ControlRegionView in | 4092 // regions that are not draggable. (See ControlRegionView in |
3358 // native_app_window_cocoa.mm). This requires the render host view to be | 4093 // native_app_window_cocoa.mm). This requires the render host view to be |
3359 // draggable by default. | 4094 // draggable by default. |
3360 - (BOOL)mouseDownCanMoveWindow { | 4095 - (BOOL)mouseDownCanMoveWindow { |
3361 return YES; | 4096 return YES; |
3362 } | 4097 } |
3363 | 4098 |
3364 @end | 4099 @end |
OLD | NEW |