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

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

Issue 4148004: Mac gpu: on gpu<->nongpu transitions, make sure to not show uninitialized memory (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comments 2 Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/renderer_host/render_widget_host_view_mac.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « chrome/browser/renderer_host/render_widget_host_view_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698