OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 <QuartzCore/QuartzCore.h> | 5 #include <QuartzCore/QuartzCore.h> |
6 | 6 |
7 #include "chrome/browser/renderer_host/render_widget_host_view_mac.h" | 7 #include "chrome/browser/renderer_host/render_widget_host_view_mac.h" |
8 | 8 |
9 #include "app/app_switches.h" | 9 #include "app/app_switches.h" |
10 #include "app/surface/io_surface_support_mac.h" | 10 #include "app/surface/io_surface_support_mac.h" |
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 /////////////////////////////////////////////////////////////////////////////// | 443 /////////////////////////////////////////////////////////////////////////////// |
444 // RenderWidgetHostViewMac, public: | 444 // RenderWidgetHostViewMac, public: |
445 | 445 |
446 RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) | 446 RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) |
447 : render_widget_host_(widget), | 447 : render_widget_host_(widget), |
448 about_to_validate_and_paint_(false), | 448 about_to_validate_and_paint_(false), |
449 call_set_needs_display_in_rect_pending_(false), | 449 call_set_needs_display_in_rect_pending_(false), |
450 text_input_type_(WebKit::WebTextInputTypeNone), | 450 text_input_type_(WebKit::WebTextInputTypeNone), |
451 is_loading_(false), | 451 is_loading_(false), |
452 is_hidden_(false), | 452 is_hidden_(false), |
453 shutdown_factory_(this) { | 453 shutdown_factory_(this), |
| 454 needs_gpu_visibility_update_after_repaint_(false) { |
454 // |cocoa_view_| owns us and we will be deleted when |cocoa_view_| goes away. | 455 // |cocoa_view_| owns us and we will be deleted when |cocoa_view_| goes away. |
455 // Since we autorelease it, our caller must put |native_view()| into the view | 456 // Since we autorelease it, our caller must put |native_view()| into the view |
456 // hierarchy right after calling us. | 457 // hierarchy right after calling us. |
457 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] | 458 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] |
458 initWithRenderWidgetHostViewMac:this] autorelease]; | 459 initWithRenderWidgetHostViewMac:this] autorelease]; |
459 render_widget_host_->set_view(this); | 460 render_widget_host_->set_view(this); |
460 | 461 |
461 // Turn on accessibility only if VoiceOver is running. | 462 // Turn on accessibility only if VoiceOver is running. |
462 if (IsVoiceOverRunning()) { | 463 if (IsVoiceOverRunning()) { |
463 Singleton<BrowserAccessibilityState>()->OnScreenReaderDetected(); | 464 Singleton<BrowserAccessibilityState>()->OnScreenReaderDetected(); |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
679 [cocoa_view_ setCaretRect:[cocoa_view_ flipRectToNSRect:caret_rect]]; | 680 [cocoa_view_ setCaretRect:[cocoa_view_ flipRectToNSRect:caret_rect]]; |
680 } | 681 } |
681 | 682 |
682 void RenderWidgetHostViewMac::ImeCancelComposition() { | 683 void RenderWidgetHostViewMac::ImeCancelComposition() { |
683 [cocoa_view_ cancelComposition]; | 684 [cocoa_view_ cancelComposition]; |
684 } | 685 } |
685 | 686 |
686 void RenderWidgetHostViewMac::DidUpdateBackingStore( | 687 void RenderWidgetHostViewMac::DidUpdateBackingStore( |
687 const gfx::Rect& scroll_rect, int scroll_dx, int scroll_dy, | 688 const gfx::Rect& scroll_rect, int scroll_dx, int scroll_dy, |
688 const std::vector<gfx::Rect>& copy_rects) { | 689 const std::vector<gfx::Rect>& copy_rects) { |
689 if (is_hidden_) | 690 if (!is_hidden_) { |
690 return; | 691 std::vector<gfx::Rect> rects(copy_rects); |
691 | 692 |
692 std::vector<gfx::Rect> rects(copy_rects); | 693 // Because the findbar might be open, we cannot use scrollRect:by: here. Fo
r |
| 694 // now, simply mark all of scroll rect as dirty. |
| 695 if (!scroll_rect.IsEmpty()) |
| 696 rects.push_back(scroll_rect); |
693 | 697 |
694 // Because the findbar might be open, we cannot use scrollRect:by: here. For | 698 for (size_t i = 0; i < rects.size(); ++i) { |
695 // now, simply mark all of scroll rect as dirty. | 699 NSRect ns_rect = [cocoa_view_ flipRectToNSRect:rects[i]]; |
696 if (!scroll_rect.IsEmpty()) | |
697 rects.push_back(scroll_rect); | |
698 | 700 |
699 for (size_t i = 0; i < rects.size(); ++i) { | 701 if (about_to_validate_and_paint_) { |
700 NSRect ns_rect = [cocoa_view_ flipRectToNSRect:rects[i]]; | 702 // As much as we'd like to use -setNeedsDisplayInRect: here, we can't. |
| 703 // We're in the middle of executing a -drawRect:, and as soon as it |
| 704 // returns Cocoa will clear its record of what needs display. We |
| 705 // instead use |performSelector:| to call |setNeedsDisplayInRect:| |
| 706 // after returning to the main loop, at which point |drawRect:| is no |
| 707 // longer on the stack. |
| 708 DCHECK([NSThread isMainThread]); |
| 709 if (!call_set_needs_display_in_rect_pending_) { |
| 710 [cocoa_view_ performSelector:@selector(callSetNeedsDisplayInRect) |
| 711 withObject:nil |
| 712 afterDelay:0]; |
| 713 call_set_needs_display_in_rect_pending_ = true; |
| 714 invalid_rect_ = ns_rect; |
| 715 } else { |
| 716 // The old invalid rect is probably invalid now, since the view has |
| 717 // most likely been resized, but there's no harm in dirtying the |
| 718 // union. In the limit, this becomes equivalent to dirtying the |
| 719 // whole view. |
| 720 invalid_rect_ = NSUnionRect(invalid_rect_, ns_rect); |
| 721 } |
| 722 } else { |
| 723 [cocoa_view_ setNeedsDisplayInRect:ns_rect]; |
| 724 } |
| 725 } |
701 | 726 |
702 if (about_to_validate_and_paint_) { | 727 if (!about_to_validate_and_paint_) |
703 // As much as we'd like to use -setNeedsDisplayInRect: here, we can't. | 728 [cocoa_view_ displayIfNeeded]; |
704 // We're in the middle of executing a -drawRect:, and as soon as it | |
705 // returns Cocoa will clear its record of what needs display. We instead | |
706 // use |performSelector:| to call |setNeedsDisplayInRect:| after returning | |
707 // to the main loop, at which point |drawRect:| is no longer on the stack. | |
708 DCHECK([NSThread isMainThread]); | |
709 if (!call_set_needs_display_in_rect_pending_) { | |
710 [cocoa_view_ performSelector:@selector(callSetNeedsDisplayInRect) | |
711 withObject:nil | |
712 afterDelay:0]; | |
713 call_set_needs_display_in_rect_pending_ = true; | |
714 invalid_rect_ = ns_rect; | |
715 } else { | |
716 // The old invalid rect is probably invalid now, since the view has most | |
717 // likely been resized, but there's no harm in dirtying the union. In | |
718 // the limit, this becomes equivalent to dirtying the whole view. | |
719 invalid_rect_ = NSUnionRect(invalid_rect_, ns_rect); | |
720 } | |
721 } else { | |
722 [cocoa_view_ setNeedsDisplayInRect:ns_rect]; | |
723 } | |
724 } | 729 } |
725 | 730 |
| 731 // If |about_to_validate_and_paint_| is set, then -drawRect: is on the stack |
| 732 // and it's not allowed to call -setHidden on the accelerated view. In that |
| 733 // case, -callSetNeedsDisplayInRect: will hide it later. |
| 734 // If |about_to_validate_and_paint_| is not set, do it now. |
726 if (!about_to_validate_and_paint_) | 735 if (!about_to_validate_and_paint_) |
727 [cocoa_view_ displayIfNeeded]; | 736 HandleDelayedGpuViewHiding(); |
728 } | 737 } |
729 | 738 |
730 void RenderWidgetHostViewMac::RenderViewGone() { | 739 void RenderWidgetHostViewMac::RenderViewGone() { |
731 // TODO(darin): keep this around, and draw sad-tab into it. | 740 // TODO(darin): keep this around, and draw sad-tab into it. |
732 UpdateCursorIfOverSelf(); | 741 UpdateCursorIfOverSelf(); |
733 Destroy(); | 742 Destroy(); |
734 } | 743 } |
735 | 744 |
736 void RenderWidgetHostViewMac::Destroy() { | 745 void RenderWidgetHostViewMac::Destroy() { |
737 // On Windows, popups are implemented with a popup window style, so that when | 746 // On Windows, popups are implemented with a popup window style, so that when |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
935 | 944 |
936 plugin_container_manager_.SetSurfaceWasPaintedTo(window, surface_id); | 945 plugin_container_manager_.SetSurfaceWasPaintedTo(window, surface_id); |
937 AcceleratedPluginView* view = | 946 AcceleratedPluginView* view = |
938 static_cast<AcceleratedPluginView*>(it->second); | 947 static_cast<AcceleratedPluginView*>(it->second); |
939 // The surface is hidden until its first paint, to not show gargabe. | 948 // The surface is hidden until its first paint, to not show gargabe. |
940 if (plugin_container_manager_.SurfaceShouldBeVisible(window)) | 949 if (plugin_container_manager_.SurfaceShouldBeVisible(window)) |
941 [view setHidden:NO]; | 950 [view setHidden:NO]; |
942 [view setSurfaceWasSwapped:YES]; | 951 [view setSurfaceWasSwapped:YES]; |
943 } | 952 } |
944 | 953 |
945 void RenderWidgetHostViewMac::GpuRenderingStateDidChange() { | 954 void RenderWidgetHostViewMac::UpdateRootGpuViewVisibility( |
946 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 955 bool show_gpu_widget) { |
947 // Plugins are destroyed on page navigate. The compositor layer on the other | 956 // Plugins are destroyed on page navigate. The compositor layer on the other |
948 // hand is created on demand and then stays alive until its renderer process | 957 // hand is created on demand and then stays alive until its renderer process |
949 // dies (usually on cross-domain navigation). Instead, only a flag | 958 // dies (usually on cross-domain navigation). Instead, only a flag |
950 // |is_gpu_rendering_active()| is flipped when the compositor output should be | 959 // |is_gpu_rendering_active()| is flipped when the compositor output should be |
951 // shown/hidden. | 960 // shown/hidden. |
952 // Show/hide the view belonging to the compositor here. | 961 // Show/hide the view belonging to the compositor here. |
953 plugin_container_manager_.set_gpu_rendering_active( | 962 plugin_container_manager_.set_gpu_rendering_active(show_gpu_widget); |
954 GetRenderWidgetHost()->is_gpu_rendering_active()); | |
955 | 963 |
956 gfx::PluginWindowHandle root_handle = | 964 gfx::PluginWindowHandle root_handle = |
957 plugin_container_manager_.root_container_handle(); | 965 plugin_container_manager_.root_container_handle(); |
958 if (root_handle != gfx::kNullPluginWindow) { | 966 if (root_handle != gfx::kNullPluginWindow) { |
959 PluginViewMap::iterator it = plugin_views_.find(root_handle); | 967 PluginViewMap::iterator it = plugin_views_.find(root_handle); |
960 DCHECK(plugin_views_.end() != it); | 968 DCHECK(plugin_views_.end() != it); |
961 if (plugin_views_.end() == it) { | 969 if (plugin_views_.end() == it) { |
962 return; | 970 return; |
963 } | 971 } |
964 bool visible = | 972 bool visible = |
965 plugin_container_manager_.SurfaceShouldBeVisible(root_handle); | 973 plugin_container_manager_.SurfaceShouldBeVisible(root_handle); |
| 974 [[it->second window] disableScreenUpdatesUntilFlush]; |
966 [it->second setHidden:!visible]; | 975 [it->second setHidden:!visible]; |
967 } | 976 } |
968 } | 977 } |
969 | 978 |
| 979 void RenderWidgetHostViewMac::HandleDelayedGpuViewHiding() { |
| 980 if (needs_gpu_visibility_update_after_repaint_) { |
| 981 UpdateRootGpuViewVisibility(false); |
| 982 needs_gpu_visibility_update_after_repaint_ = false; |
| 983 } |
| 984 } |
| 985 |
| 986 void RenderWidgetHostViewMac::GpuRenderingStateDidChange() { |
| 987 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 988 if (GetRenderWidgetHost()->is_gpu_rendering_active()) { |
| 989 UpdateRootGpuViewVisibility( |
| 990 GetRenderWidgetHost()->is_gpu_rendering_active()); |
| 991 } else { |
| 992 needs_gpu_visibility_update_after_repaint_ = true; |
| 993 } |
| 994 } |
| 995 |
970 void RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstance( | 996 void RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstance( |
971 CGLContextObj context, | 997 CGLContextObj context, |
972 gfx::PluginWindowHandle plugin_handle, | 998 gfx::PluginWindowHandle plugin_handle, |
973 NSSize size) { | 999 NSSize size) { |
974 // Called on the display link thread. | 1000 // Called on the display link thread. |
975 CGLSetCurrentContext(context); | 1001 CGLSetCurrentContext(context); |
976 | 1002 |
977 glMatrixMode(GL_PROJECTION); | 1003 glMatrixMode(GL_PROJECTION); |
978 glLoadIdentity(); | 1004 glLoadIdentity(); |
979 // Note that we place the origin at the upper left corner with +y | 1005 // Note that we place the origin at the upper left corner with +y |
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1490 if (renderWidgetHostView_->render_widget_host_) | 1516 if (renderWidgetHostView_->render_widget_host_) |
1491 renderWidgetHostView_->render_widget_host_->WasResized(); | 1517 renderWidgetHostView_->render_widget_host_->WasResized(); |
1492 } | 1518 } |
1493 | 1519 |
1494 - (void)callSetNeedsDisplayInRect { | 1520 - (void)callSetNeedsDisplayInRect { |
1495 DCHECK([NSThread isMainThread]); | 1521 DCHECK([NSThread isMainThread]); |
1496 DCHECK(renderWidgetHostView_->call_set_needs_display_in_rect_pending_); | 1522 DCHECK(renderWidgetHostView_->call_set_needs_display_in_rect_pending_); |
1497 [self setNeedsDisplayInRect:renderWidgetHostView_->invalid_rect_]; | 1523 [self setNeedsDisplayInRect:renderWidgetHostView_->invalid_rect_]; |
1498 renderWidgetHostView_->call_set_needs_display_in_rect_pending_ = false; | 1524 renderWidgetHostView_->call_set_needs_display_in_rect_pending_ = false; |
1499 renderWidgetHostView_->invalid_rect_ = NSZeroRect; | 1525 renderWidgetHostView_->invalid_rect_ = NSZeroRect; |
| 1526 |
| 1527 renderWidgetHostView_->HandleDelayedGpuViewHiding(); |
1500 } | 1528 } |
1501 | 1529 |
1502 // Fills with white the parts of the area to the right and bottom for |rect| | 1530 // Fills with white the parts of the area to the right and bottom for |rect| |
1503 // that intersect |damagedRect|. | 1531 // that intersect |damagedRect|. |
1504 - (void)fillBottomRightRemainderOfRect:(gfx::Rect)rect | 1532 - (void)fillBottomRightRemainderOfRect:(gfx::Rect)rect |
1505 dirtyRect:(gfx::Rect)damagedRect { | 1533 dirtyRect:(gfx::Rect)damagedRect { |
1506 if (damagedRect.right() > rect.right()) { | 1534 if (damagedRect.right() > rect.right()) { |
1507 int x = std::max(rect.right(), damagedRect.x()); | 1535 int x = std::max(rect.right(), damagedRect.x()); |
1508 int y = std::min(rect.bottom(), damagedRect.bottom()); | 1536 int y = std::min(rect.bottom(), damagedRect.bottom()); |
1509 int width = damagedRect.right() - x; | 1537 int width = damagedRect.right() - x; |
(...skipping 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2534 if (!string) return NO; | 2562 if (!string) return NO; |
2535 | 2563 |
2536 // If the user is currently using an IME, confirm the IME input, | 2564 // If the user is currently using an IME, confirm the IME input, |
2537 // and then insert the text from the service, the same as TextEdit and Safari. | 2565 // and then insert the text from the service, the same as TextEdit and Safari. |
2538 [self confirmComposition]; | 2566 [self confirmComposition]; |
2539 [self insertText:string]; | 2567 [self insertText:string]; |
2540 return YES; | 2568 return YES; |
2541 } | 2569 } |
2542 | 2570 |
2543 @end | 2571 @end |
OLD | NEW |