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 <QuartzCore/QuartzCore.h> | 8 #include <QuartzCore/QuartzCore.h> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
155 @property(nonatomic, assign) NSRange markedRange; | 155 @property(nonatomic, assign) NSRange markedRange; |
156 | 156 |
157 + (BOOL)shouldAutohideCursorForEvent:(NSEvent*)event; | 157 + (BOOL)shouldAutohideCursorForEvent:(NSEvent*)event; |
158 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r; | 158 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r; |
159 - (void)gotUnhandledWheelEvent; | 159 - (void)gotUnhandledWheelEvent; |
160 - (void)scrollOffsetPinnedToLeft:(BOOL)left toRight:(BOOL)right; | 160 - (void)scrollOffsetPinnedToLeft:(BOOL)left toRight:(BOOL)right; |
161 - (void)setHasHorizontalScrollbar:(BOOL)has_horizontal_scrollbar; | 161 - (void)setHasHorizontalScrollbar:(BOOL)has_horizontal_scrollbar; |
162 - (void)keyEvent:(NSEvent*)theEvent wasKeyEquivalent:(BOOL)equiv; | 162 - (void)keyEvent:(NSEvent*)theEvent wasKeyEquivalent:(BOOL)equiv; |
163 - (void)windowDidChangeBackingProperties:(NSNotification*)notification; | 163 - (void)windowDidChangeBackingProperties:(NSNotification*)notification; |
164 - (void)windowChangedGlobalFrame:(NSNotification*)notification; | 164 - (void)windowChangedGlobalFrame:(NSNotification*)notification; |
165 - (void)drawWithDirtyRect:(CGRect)dirtyRect | |
166 inContext:(CGContextRef)context; | |
167 - (void)checkForPluginImeCancellation; | 165 - (void)checkForPluginImeCancellation; |
168 - (void)updateScreenProperties; | 166 - (void)updateScreenProperties; |
169 - (void)setResponderDelegate: | 167 - (void)setResponderDelegate: |
170 (NSObject<RenderWidgetHostViewMacDelegate>*)delegate; | 168 (NSObject<RenderWidgetHostViewMacDelegate>*)delegate; |
171 @end | 169 @end |
172 | 170 |
173 // A window subclass that allows the fullscreen window to become main and gain | 171 // A window subclass that allows the fullscreen window to become main and gain |
174 // keyboard focus. This is only used for pepper flash. Normal fullscreen is | 172 // keyboard focus. This is only used for pepper flash. Normal fullscreen is |
175 // handled by the browser. | 173 // handled by the browser. |
176 @interface PepperFlashFullscreenWindow : UnderlayOpenGLHostingWindow | 174 @interface PepperFlashFullscreenWindow : UnderlayOpenGLHostingWindow |
(...skipping 21 matching lines...) Expand all Loading... | |
198 @implementation RenderWidgetPopupWindow | 196 @implementation RenderWidgetPopupWindow |
199 | 197 |
200 - (id)initWithContentRect:(NSRect)contentRect | 198 - (id)initWithContentRect:(NSRect)contentRect |
201 styleMask:(NSUInteger)windowStyle | 199 styleMask:(NSUInteger)windowStyle |
202 backing:(NSBackingStoreType)bufferingType | 200 backing:(NSBackingStoreType)bufferingType |
203 defer:(BOOL)deferCreation { | 201 defer:(BOOL)deferCreation { |
204 if (self = [super initWithContentRect:contentRect | 202 if (self = [super initWithContentRect:contentRect |
205 styleMask:windowStyle | 203 styleMask:windowStyle |
206 backing:bufferingType | 204 backing:bufferingType |
207 defer:deferCreation]) { | 205 defer:deferCreation]) { |
208 DCHECK_EQ(content::CORE_ANIMATION_DISABLED, | |
209 content::GetCoreAnimationStatus()); | |
ccameron
2014/06/05 03:05:14
I think this DCHECK_EQ was added by accident.
Ken Russell (switch to Gerrit)
2014/06/05 17:49:44
I wonder why it wasn't noticed earlier.
| |
210 [self setOpaque:NO]; | 206 [self setOpaque:NO]; |
211 [self setBackgroundColor:[NSColor clearColor]]; | 207 [self setBackgroundColor:[NSColor clearColor]]; |
212 [self startObservingClicks]; | 208 [self startObservingClicks]; |
213 } | 209 } |
214 return self; | 210 return self; |
215 } | 211 } |
216 | 212 |
217 - (void)close { | 213 - (void)close { |
218 [self stopObservingClicks]; | 214 [self stopObservingClicks]; |
219 [super close]; | 215 [super close]; |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
485 void RenderWidgetHostViewBase::GetDefaultScreenInfo( | 481 void RenderWidgetHostViewBase::GetDefaultScreenInfo( |
486 blink::WebScreenInfo* results) { | 482 blink::WebScreenInfo* results) { |
487 *results = GetWebScreenInfo(NULL); | 483 *results = GetWebScreenInfo(NULL); |
488 } | 484 } |
489 | 485 |
490 /////////////////////////////////////////////////////////////////////////////// | 486 /////////////////////////////////////////////////////////////////////////////// |
491 // RenderWidgetHostViewMac, public: | 487 // RenderWidgetHostViewMac, public: |
492 | 488 |
493 RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) | 489 RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) |
494 : render_widget_host_(RenderWidgetHostImpl::From(widget)), | 490 : render_widget_host_(RenderWidgetHostImpl::From(widget)), |
495 last_frame_was_accelerated_(false), | |
496 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), | 491 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), |
497 can_compose_inline_(true), | 492 can_compose_inline_(true), |
498 allow_overlapping_views_(false), | |
499 use_core_animation_(false), | |
500 pending_latency_info_delay_(0), | 493 pending_latency_info_delay_(0), |
501 pending_latency_info_delay_weak_ptr_factory_(this), | 494 pending_latency_info_delay_weak_ptr_factory_(this), |
502 backing_store_scale_factor_(1), | 495 backing_store_scale_factor_(1), |
503 is_loading_(false), | 496 is_loading_(false), |
504 weak_factory_(this), | 497 weak_factory_(this), |
505 fullscreen_parent_host_view_(NULL), | 498 fullscreen_parent_host_view_(NULL), |
506 underlay_view_has_drawn_(false), | |
507 overlay_view_weak_factory_(this), | 499 overlay_view_weak_factory_(this), |
508 software_frame_weak_ptr_factory_(this) { | 500 software_frame_weak_ptr_factory_(this) { |
509 software_frame_manager_.reset(new SoftwareFrameManager( | 501 software_frame_manager_.reset(new SoftwareFrameManager( |
510 software_frame_weak_ptr_factory_.GetWeakPtr())); | 502 software_frame_weak_ptr_factory_.GetWeakPtr())); |
511 // |cocoa_view_| owns us and we will be deleted when |cocoa_view_| | 503 // |cocoa_view_| owns us and we will be deleted when |cocoa_view_| |
512 // goes away. Since we autorelease it, our caller must put | 504 // goes away. Since we autorelease it, our caller must put |
513 // |GetNativeView()| into the view hierarchy right after calling us. | 505 // |GetNativeView()| into the view hierarchy right after calling us. |
514 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] | 506 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] |
515 initWithRenderWidgetHostViewMac:this] autorelease]; | 507 initWithRenderWidgetHostViewMac:this] autorelease]; |
516 | 508 |
517 if (GetCoreAnimationStatus() == CORE_ANIMATION_ENABLED) { | 509 background_layer_.reset([[CALayer alloc] init]); |
518 use_core_animation_ = true; | 510 [background_layer_ |
519 background_layer_.reset([[CALayer alloc] init]); | 511 setBackgroundColor:CGColorGetConstantColor(kCGColorWhite)]; |
520 [background_layer_ | 512 [cocoa_view_ setLayer:background_layer_]; |
521 setBackgroundColor:CGColorGetConstantColor(kCGColorWhite)]; | 513 [cocoa_view_ setWantsLayer:YES]; |
522 [cocoa_view_ setLayer:background_layer_]; | |
523 [cocoa_view_ setWantsLayer:YES]; | |
524 } | |
525 | 514 |
526 render_widget_host_->SetView(this); | 515 render_widget_host_->SetView(this); |
527 } | 516 } |
528 | 517 |
529 RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { | 518 RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { |
530 // This is being called from |cocoa_view_|'s destructor, so invalidate the | 519 // This is being called from |cocoa_view_|'s destructor, so invalidate the |
531 // pointer. | 520 // pointer. |
532 cocoa_view_ = nil; | 521 cocoa_view_ = nil; |
533 | 522 |
534 UnlockMouse(); | 523 UnlockMouse(); |
535 | 524 |
536 // Make sure that the layer doesn't reach into the now-invalid object. | 525 // Make sure that the layer doesn't reach into the now-invalid object. |
537 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); | 526 DestroyCompositedIOSurfaceAndLayer(); |
538 DestroySoftwareLayer(); | 527 DestroySoftwareLayer(); |
539 | 528 |
540 // We are owned by RenderWidgetHostViewCocoa, so if we go away before the | 529 // 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 | 530 // RenderWidgetHost does we need to tell it not to hold a stale pointer to |
542 // us. | 531 // us. |
543 if (render_widget_host_) | 532 if (render_widget_host_) |
544 render_widget_host_->SetView(NULL); | 533 render_widget_host_->SetView(NULL); |
545 } | 534 } |
546 | 535 |
547 void RenderWidgetHostViewMac::SetDelegate( | 536 void RenderWidgetHostViewMac::SetDelegate( |
548 NSObject<RenderWidgetHostViewMacDelegate>* delegate) { | 537 NSObject<RenderWidgetHostViewMacDelegate>* delegate) { |
549 [cocoa_view_ setResponderDelegate:delegate]; | 538 [cocoa_view_ setResponderDelegate:delegate]; |
550 } | 539 } |
551 | 540 |
552 void RenderWidgetHostViewMac::SetAllowOverlappingViews(bool overlapping) { | 541 void RenderWidgetHostViewMac::SetAllowOverlappingViews(bool overlapping) { |
553 if (allow_overlapping_views_ == overlapping) | 542 // TODO(ccameron): Remove callers of this function. |
554 return; | |
555 allow_overlapping_views_ = overlapping; | |
556 [cocoa_view_ setNeedsDisplay:YES]; | |
557 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; | |
558 } | 543 } |
559 | 544 |
560 /////////////////////////////////////////////////////////////////////////////// | 545 /////////////////////////////////////////////////////////////////////////////// |
561 // RenderWidgetHostViewMac, RenderWidgetHostView implementation: | 546 // RenderWidgetHostViewMac, RenderWidgetHostView implementation: |
562 | 547 |
563 bool RenderWidgetHostViewMac::EnsureCompositedIOSurface() { | 548 bool RenderWidgetHostViewMac::EnsureCompositedIOSurface() { |
564 // If the context or the IOSurface's context has had an error, re-build | 549 // If the context or the IOSurface's context has had an error, re-build |
565 // everything from scratch. | 550 // everything from scratch. |
566 if (compositing_iosurface_context_ && | 551 if (compositing_iosurface_context_ && |
567 compositing_iosurface_context_->HasBeenPoisoned()) { | 552 compositing_iosurface_context_->HasBeenPoisoned()) { |
568 LOG(ERROR) << "Failing EnsureCompositedIOSurface because " | 553 LOG(ERROR) << "Failing EnsureCompositedIOSurface because " |
569 << "context was poisoned"; | 554 << "context was poisoned"; |
570 return false; | 555 return false; |
571 } | 556 } |
572 if (compositing_iosurface_ && | 557 if (compositing_iosurface_ && |
573 compositing_iosurface_->HasBeenPoisoned()) { | 558 compositing_iosurface_->HasBeenPoisoned()) { |
574 LOG(ERROR) << "Failing EnsureCompositedIOSurface because " | 559 LOG(ERROR) << "Failing EnsureCompositedIOSurface because " |
575 << "surface was poisoned"; | 560 << "surface was poisoned"; |
576 return false; | 561 return false; |
577 } | 562 } |
578 | 563 |
579 int current_window_number = use_core_animation_ ? | 564 int current_window_number = |
580 CompositingIOSurfaceContext::kOffscreenContextWindowNumber : | 565 CompositingIOSurfaceContext::kOffscreenContextWindowNumber; |
581 window_number(); | |
582 bool new_surface_needed = !compositing_iosurface_; | 566 bool new_surface_needed = !compositing_iosurface_; |
583 bool new_context_needed = | 567 bool new_context_needed = |
584 !compositing_iosurface_context_ || | 568 !compositing_iosurface_context_ || |
585 (compositing_iosurface_context_ && | 569 (compositing_iosurface_context_ && |
586 compositing_iosurface_context_->window_number() != | 570 compositing_iosurface_context_->window_number() != |
587 current_window_number); | 571 current_window_number); |
588 | 572 |
589 if (!new_surface_needed && !new_context_needed) | 573 if (!new_surface_needed && !new_context_needed) |
590 return true; | 574 return true; |
591 | 575 |
592 // Create the GL context and shaders. | 576 // Create the GL context and shaders. |
593 if (new_context_needed) { | 577 if (new_context_needed) { |
594 scoped_refptr<CompositingIOSurfaceContext> new_context = | 578 scoped_refptr<CompositingIOSurfaceContext> new_context = |
595 CompositingIOSurfaceContext::Get(current_window_number); | 579 CompositingIOSurfaceContext::Get(current_window_number); |
596 // Un-bind the GL context from this view before binding the new GL | 580 // Un-bind the GL context from this view before binding the new GL |
597 // context. Having two GL contexts bound to a view will result in | 581 // context. Having two GL contexts bound to a view will result in |
598 // crashes and corruption. | 582 // crashes and corruption. |
599 // http://crbug.com/230883 | 583 // http://crbug.com/230883 |
600 ClearBoundContextDrawable(); | |
601 if (!new_context) { | 584 if (!new_context) { |
602 LOG(ERROR) << "Failed to create CompositingIOSurfaceContext"; | 585 LOG(ERROR) << "Failed to create CompositingIOSurfaceContext"; |
603 return false; | 586 return false; |
604 } | 587 } |
605 compositing_iosurface_context_ = new_context; | 588 compositing_iosurface_context_ = new_context; |
606 } | 589 } |
607 | 590 |
608 // Create the IOSurface texture. | 591 // Create the IOSurface texture. |
609 if (new_surface_needed) { | 592 if (new_surface_needed) { |
610 compositing_iosurface_ = CompositingIOSurfaceMac::Create(); | 593 compositing_iosurface_ = CompositingIOSurfaceMac::Create(); |
611 if (!compositing_iosurface_) { | 594 if (!compositing_iosurface_) { |
612 LOG(ERROR) << "Failed to create CompositingIOSurface"; | 595 LOG(ERROR) << "Failed to create CompositingIOSurface"; |
613 return false; | 596 return false; |
614 } | 597 } |
615 } | 598 } |
616 | 599 |
617 return true; | 600 return true; |
618 } | 601 } |
619 | 602 |
620 void RenderWidgetHostViewMac::EnsureSoftwareLayer() { | 603 void RenderWidgetHostViewMac::EnsureSoftwareLayer() { |
621 TRACE_EVENT0("browser", "RenderWidgetHostViewMac::EnsureSoftwareLayer"); | 604 TRACE_EVENT0("browser", "RenderWidgetHostViewMac::EnsureSoftwareLayer"); |
622 if (software_layer_ || !use_core_animation_) | 605 if (software_layer_) |
623 return; | 606 return; |
624 | 607 |
625 software_layer_.reset([[SoftwareLayer alloc] init]); | 608 software_layer_.reset([[SoftwareLayer alloc] init]); |
626 DCHECK(software_layer_); | 609 DCHECK(software_layer_); |
627 | 610 |
628 // Disable the fade-in animation as the layer is added. | 611 // Disable the fade-in animation as the layer is added. |
629 ScopedCAActionDisabler disabler; | 612 ScopedCAActionDisabler disabler; |
630 [background_layer_ addSublayer:software_layer_]; | 613 [background_layer_ addSublayer:software_layer_]; |
631 } | 614 } |
632 | 615 |
633 void RenderWidgetHostViewMac::DestroySoftwareLayer() { | 616 void RenderWidgetHostViewMac::DestroySoftwareLayer() { |
634 if (!software_layer_) | 617 if (!software_layer_) |
635 return; | 618 return; |
636 | 619 |
637 // Disable the fade-out animation as the layer is removed. | 620 // Disable the fade-out animation as the layer is removed. |
638 ScopedCAActionDisabler disabler; | 621 ScopedCAActionDisabler disabler; |
639 [software_layer_ removeFromSuperlayer]; | 622 [software_layer_ removeFromSuperlayer]; |
640 software_layer_.reset(); | 623 software_layer_.reset(); |
641 } | 624 } |
642 | 625 |
643 void RenderWidgetHostViewMac::EnsureCompositedIOSurfaceLayer() { | 626 void RenderWidgetHostViewMac::EnsureCompositedIOSurfaceLayer() { |
644 TRACE_EVENT0("browser", | 627 TRACE_EVENT0("browser", |
645 "RenderWidgetHostViewMac::EnsureCompositedIOSurfaceLayer"); | 628 "RenderWidgetHostViewMac::EnsureCompositedIOSurfaceLayer"); |
646 DCHECK(compositing_iosurface_context_); | 629 DCHECK(compositing_iosurface_context_); |
647 if (compositing_iosurface_layer_ || !use_core_animation_) | 630 if (compositing_iosurface_layer_) |
648 return; | 631 return; |
649 | 632 |
650 compositing_iosurface_layer_.reset([[CompositingIOSurfaceLayer alloc] | 633 compositing_iosurface_layer_.reset([[CompositingIOSurfaceLayer alloc] |
651 initWithIOSurface:compositing_iosurface_ | 634 initWithIOSurface:compositing_iosurface_ |
652 withScaleFactor:compositing_iosurface_->scale_factor() | 635 withScaleFactor:compositing_iosurface_->scale_factor() |
653 withClient:this]); | 636 withClient:this]); |
654 DCHECK(compositing_iosurface_layer_); | 637 DCHECK(compositing_iosurface_layer_); |
655 | 638 |
656 // Disable the fade-in animation as the layer is added. | 639 // Disable the fade-in animation as the layer is added. |
657 ScopedCAActionDisabler disabler; | 640 ScopedCAActionDisabler disabler; |
658 [background_layer_ addSublayer:compositing_iosurface_layer_]; | 641 [background_layer_ addSublayer:compositing_iosurface_layer_]; |
659 } | 642 } |
660 | 643 |
661 void RenderWidgetHostViewMac::DestroyCompositedIOSurfaceLayer( | 644 void RenderWidgetHostViewMac::DestroyCompositedIOSurfaceLayer( |
662 DestroyCompositedIOSurfaceLayerBehavior destroy_layer_behavior) { | 645 DestroyCompositedIOSurfaceLayerBehavior destroy_layer_behavior) { |
663 if (!compositing_iosurface_layer_) | 646 if (!compositing_iosurface_layer_) |
664 return; | 647 return; |
665 | 648 |
666 if (destroy_layer_behavior == kRemoveLayerFromHierarchy) { | 649 if (destroy_layer_behavior == kRemoveLayerFromHierarchy) { |
667 // Disable the fade-out animation as the layer is removed. | 650 // Disable the fade-out animation as the layer is removed. |
668 ScopedCAActionDisabler disabler; | 651 ScopedCAActionDisabler disabler; |
669 [compositing_iosurface_layer_ removeFromSuperlayer]; | 652 [compositing_iosurface_layer_ removeFromSuperlayer]; |
670 } | 653 } |
671 [compositing_iosurface_layer_ resetClient]; | 654 [compositing_iosurface_layer_ resetClient]; |
672 compositing_iosurface_layer_.reset(); | 655 compositing_iosurface_layer_.reset(); |
673 } | 656 } |
674 | 657 |
675 void RenderWidgetHostViewMac::DestroyCompositedIOSurfaceAndLayer( | 658 void RenderWidgetHostViewMac::DestroyCompositedIOSurfaceAndLayer() { |
676 DestroyContextBehavior destroy_context_behavior) { | |
677 // Any pending frames will not be displayed, so ack them now. | 659 // Any pending frames will not be displayed, so ack them now. |
678 SendPendingSwapAck(); | 660 SendPendingSwapAck(); |
679 | 661 |
680 DestroyCompositedIOSurfaceLayer(kRemoveLayerFromHierarchy); | 662 DestroyCompositedIOSurfaceLayer(kRemoveLayerFromHierarchy); |
681 compositing_iosurface_ = NULL; | 663 compositing_iosurface_ = NULL; |
682 | 664 compositing_iosurface_context_ = NULL; |
683 switch (destroy_context_behavior) { | |
684 case kLeaveContextBoundToView: | |
685 break; | |
686 case kDestroyContext: | |
687 ClearBoundContextDrawable(); | |
688 compositing_iosurface_context_ = NULL; | |
689 break; | |
690 default: | |
691 NOTREACHED(); | |
692 break; | |
693 } | |
694 } | |
695 | |
696 void RenderWidgetHostViewMac::ClearBoundContextDrawable() { | |
697 if (use_core_animation_) | |
698 return; | |
699 | |
700 if (compositing_iosurface_context_ && | |
701 cocoa_view_ && | |
702 [[compositing_iosurface_context_->nsgl_context() view] | |
703 isEqual:cocoa_view_]) { | |
704 // Disable screen updates because removing the GL context from below can | |
705 // cause flashes. | |
706 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; | |
707 [compositing_iosurface_context_->nsgl_context() clearDrawable]; | |
708 } | |
709 } | 665 } |
710 | 666 |
711 bool RenderWidgetHostViewMac::OnMessageReceived(const IPC::Message& message) { | 667 bool RenderWidgetHostViewMac::OnMessageReceived(const IPC::Message& message) { |
712 bool handled = true; | 668 bool handled = true; |
713 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewMac, message) | 669 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewMac, message) |
714 IPC_MESSAGE_HANDLER(ViewHostMsg_PluginFocusChanged, OnPluginFocusChanged) | 670 IPC_MESSAGE_HANDLER(ViewHostMsg_PluginFocusChanged, OnPluginFocusChanged) |
715 IPC_MESSAGE_HANDLER(ViewHostMsg_StartPluginIme, OnStartPluginIme) | 671 IPC_MESSAGE_HANDLER(ViewHostMsg_StartPluginIme, OnStartPluginIme) |
716 IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeScrollbarsForMainFrame, | 672 IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeScrollbarsForMainFrame, |
717 OnDidChangeScrollbarsForMainFrame) | 673 OnDidChangeScrollbarsForMainFrame) |
718 IPC_MESSAGE_UNHANDLED(handled = false) | 674 IPC_MESSAGE_UNHANDLED(handled = false) |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
884 } | 840 } |
885 | 841 |
886 RenderWidgetHost* RenderWidgetHostViewMac::GetRenderWidgetHost() const { | 842 RenderWidgetHost* RenderWidgetHostViewMac::GetRenderWidgetHost() const { |
887 return render_widget_host_; | 843 return render_widget_host_; |
888 } | 844 } |
889 | 845 |
890 void RenderWidgetHostViewMac::WasShown() { | 846 void RenderWidgetHostViewMac::WasShown() { |
891 if (!render_widget_host_->is_hidden()) | 847 if (!render_widget_host_->is_hidden()) |
892 return; | 848 return; |
893 | 849 |
894 if (web_contents_switch_paint_time_.is_null()) | |
895 web_contents_switch_paint_time_ = base::TimeTicks::Now(); | |
896 render_widget_host_->WasShown(); | 850 render_widget_host_->WasShown(); |
897 software_frame_manager_->SetVisibility(true); | 851 software_frame_manager_->SetVisibility(true); |
898 if (delegated_frame_host_) | 852 if (delegated_frame_host_) |
899 delegated_frame_host_->WasShown(); | 853 delegated_frame_host_->WasShown(); |
900 | 854 |
901 // Call setNeedsDisplay before pausing for new frames to come in -- if any | 855 // Call setNeedsDisplay before pausing for new frames to come in -- if any |
902 // do, and are drawn, then the needsDisplay bit will be cleared. | 856 // do, and are drawn, then the needsDisplay bit will be cleared. |
903 [compositing_iosurface_layer_ setNeedsDisplay]; | 857 [compositing_iosurface_layer_ setNeedsDisplay]; |
904 PauseForPendingResizeOrRepaintsAndDraw(); | 858 PauseForPendingResizeOrRepaintsAndDraw(); |
905 | |
906 // We're messing with the window, so do this to ensure no flashes. | |
907 if (!use_core_animation_) | |
908 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; | |
909 } | 859 } |
910 | 860 |
911 void RenderWidgetHostViewMac::WasHidden() { | 861 void RenderWidgetHostViewMac::WasHidden() { |
912 if (render_widget_host_->is_hidden()) | 862 if (render_widget_host_->is_hidden()) |
913 return; | 863 return; |
914 | 864 |
915 // Any pending frames will not be displayed until this is shown again. Ack | 865 // Any pending frames will not be displayed until this is shown again. Ack |
916 // them now. | 866 // them now. |
917 SendPendingSwapAck(); | 867 SendPendingSwapAck(); |
918 PostReleaseBrowserCompositorLock(); | 868 PostReleaseBrowserCompositorLock(); |
919 | 869 |
920 // If we have a renderer, then inform it that we are being hidden so it can | 870 // If we have a renderer, then inform it that we are being hidden so it can |
921 // reduce its resource utilization. | 871 // reduce its resource utilization. |
922 render_widget_host_->WasHidden(); | 872 render_widget_host_->WasHidden(); |
923 software_frame_manager_->SetVisibility(false); | 873 software_frame_manager_->SetVisibility(false); |
924 if (delegated_frame_host_) | 874 if (delegated_frame_host_) |
925 delegated_frame_host_->WasHidden(); | 875 delegated_frame_host_->WasHidden(); |
926 | |
927 // There can be a transparent flash as this view is removed and the next is | |
928 // added, because of OSX windowing races between displaying the contents of | |
929 // the NSView and its corresponding OpenGL context. | |
930 // disableScreenUpdatesUntilFlush prevents the transparent flash by avoiding | |
931 // screen updates until the next tab draws. | |
932 if (!use_core_animation_) | |
933 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; | |
934 | |
935 web_contents_switch_paint_time_ = base::TimeTicks(); | |
936 } | 876 } |
937 | 877 |
938 void RenderWidgetHostViewMac::SetSize(const gfx::Size& size) { | 878 void RenderWidgetHostViewMac::SetSize(const gfx::Size& size) { |
939 gfx::Rect rect = GetViewBounds(); | 879 gfx::Rect rect = GetViewBounds(); |
940 rect.set_size(size); | 880 rect.set_size(size); |
941 SetBounds(rect); | 881 SetBounds(rect); |
942 } | 882 } |
943 | 883 |
944 void RenderWidgetHostViewMac::SetBounds(const gfx::Rect& rect) { | 884 void RenderWidgetHostViewMac::SetBounds(const gfx::Rect& rect) { |
945 // |rect.size()| is view coordinates, |rect.origin| is screen coordinates, | 885 // |rect.size()| is view coordinates, |rect.origin| is screen coordinates, |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1031 (compositing_iosurface_ && compositing_iosurface_->HasIOSurface()); | 971 (compositing_iosurface_ && compositing_iosurface_->HasIOSurface()); |
1032 } | 972 } |
1033 | 973 |
1034 void RenderWidgetHostViewMac::Show() { | 974 void RenderWidgetHostViewMac::Show() { |
1035 [cocoa_view_ setHidden:NO]; | 975 [cocoa_view_ setHidden:NO]; |
1036 | 976 |
1037 WasShown(); | 977 WasShown(); |
1038 } | 978 } |
1039 | 979 |
1040 void RenderWidgetHostViewMac::Hide() { | 980 void RenderWidgetHostViewMac::Hide() { |
1041 // We're messing with the window, so do this to ensure no flashes. | |
1042 if (!use_core_animation_) | |
1043 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; | |
1044 | |
1045 [cocoa_view_ setHidden:YES]; | 981 [cocoa_view_ setHidden:YES]; |
1046 | 982 |
1047 WasHidden(); | 983 WasHidden(); |
1048 } | 984 } |
1049 | 985 |
1050 bool RenderWidgetHostViewMac::IsShowing() { | 986 bool RenderWidgetHostViewMac::IsShowing() { |
1051 return ![cocoa_view_ isHidden]; | 987 return ![cocoa_view_ isHidden]; |
1052 } | 988 } |
1053 | 989 |
1054 gfx::Rect RenderWidgetHostViewMac::GetViewBounds() const { | 990 gfx::Rect RenderWidgetHostViewMac::GetViewBounds() const { |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1474 // If compositing_iosurface_ exists and has been poisoned, destroy it | 1410 // If compositing_iosurface_ exists and has been poisoned, destroy it |
1475 // and allow EnsureCompositedIOSurface to recreate it below. Keep a | 1411 // and allow EnsureCompositedIOSurface to recreate it below. Keep a |
1476 // reference to the destroyed layer around until after the below call | 1412 // reference to the destroyed layer around until after the below call |
1477 // to LayoutLayers, to avoid flickers. | 1413 // to LayoutLayers, to avoid flickers. |
1478 base::ScopedClosureRunner scoped_layer_remover; | 1414 base::ScopedClosureRunner scoped_layer_remover; |
1479 if (compositing_iosurface_context_ && | 1415 if (compositing_iosurface_context_ && |
1480 compositing_iosurface_context_->HasBeenPoisoned()) { | 1416 compositing_iosurface_context_->HasBeenPoisoned()) { |
1481 scoped_layer_remover.Reset( | 1417 scoped_layer_remover.Reset( |
1482 base::Bind(RemoveLayerFromSuperlayer, compositing_iosurface_layer_)); | 1418 base::Bind(RemoveLayerFromSuperlayer, compositing_iosurface_layer_)); |
1483 DestroyCompositedIOSurfaceLayer(kLeaveLayerInHierarchy); | 1419 DestroyCompositedIOSurfaceLayer(kLeaveLayerInHierarchy); |
1484 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); | 1420 DestroyCompositedIOSurfaceAndLayer(); |
1485 } | 1421 } |
1486 | 1422 |
1487 // Ensure compositing_iosurface_ and compositing_iosurface_context_ be | 1423 // Ensure compositing_iosurface_ and compositing_iosurface_context_ be |
1488 // allocated. | 1424 // allocated. |
1489 if (!EnsureCompositedIOSurface()) { | 1425 if (!EnsureCompositedIOSurface()) { |
1490 LOG(ERROR) << "Failed EnsureCompositingIOSurface"; | 1426 LOG(ERROR) << "Failed EnsureCompositingIOSurface"; |
1491 return; | 1427 return; |
1492 } | 1428 } |
1493 | 1429 |
1494 // Make the context current and update the IOSurface with the handle | 1430 // Make the context current and update the IOSurface with the handle |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1583 !([window occlusionState] & NSWindowOcclusionStateVisible); | 1519 !([window occlusionState] & NSWindowOcclusionStateVisible); |
1584 // Note that we aggressively ack even if this particular frame is not being | 1520 // Note that we aggressively ack even if this particular frame is not being |
1585 // captured. | 1521 // captured. |
1586 if (window_is_occluded && frame_subscriber_) | 1522 if (window_is_occluded && frame_subscriber_) |
1587 scoped_ack.Reset(); | 1523 scoped_ack.Reset(); |
1588 } | 1524 } |
1589 | 1525 |
1590 // If we reach here, then the frame will be displayed by a future draw | 1526 // If we reach here, then the frame will be displayed by a future draw |
1591 // call, so don't make the callback. | 1527 // call, so don't make the callback. |
1592 ignore_result(scoped_ack.Release()); | 1528 ignore_result(scoped_ack.Release()); |
1593 if (use_core_animation_) { | 1529 DCHECK(compositing_iosurface_layer_); |
1594 DCHECK(compositing_iosurface_layer_); | 1530 [compositing_iosurface_layer_ gotNewFrame]; |
1595 [compositing_iosurface_layer_ gotNewFrame]; | |
1596 } else { | |
1597 gfx::ScopedCGLSetCurrentContext scoped_set_current_context( | |
1598 compositing_iosurface_context_->cgl_context()); | |
1599 DrawIOSurfaceWithoutCoreAnimation(); | |
1600 } | |
1601 | 1531 |
1602 // Try to finish previous copy requests after draw to get better pipelining. | 1532 // Try to finish previous copy requests after draw to get better pipelining. |
1603 if (compositing_iosurface_) | 1533 if (compositing_iosurface_) |
1604 compositing_iosurface_->CheckIfAllCopiesAreFinished(false); | 1534 compositing_iosurface_->CheckIfAllCopiesAreFinished(false); |
1605 | 1535 |
1606 // The IOSurface's size may have changed, so re-layout the layers to take | 1536 // The IOSurface's size may have changed, so re-layout the layers to take |
1607 // this into account. This may force an immediate draw. | 1537 // this into account. This may force an immediate draw. |
1608 LayoutLayers(); | 1538 LayoutLayers(); |
1609 } | 1539 } |
1610 | 1540 |
1611 void RenderWidgetHostViewMac::DrawIOSurfaceWithoutCoreAnimation() { | |
1612 CHECK(!use_core_animation_); | |
1613 CHECK(compositing_iosurface_); | |
1614 | |
1615 // If there is a pending frame, it should be acked by the end of this | |
1616 // function. Note that the ack should happen only after all drawing is | |
1617 // complete, so that the ack happens after any blocking due to vsync. | |
1618 base::ScopedClosureRunner scoped_ack( | |
1619 base::Bind(&RenderWidgetHostViewMac::SendPendingSwapAck, | |
1620 weak_factory_.GetWeakPtr())); | |
1621 | |
1622 GLint old_gl_surface_order = 0; | |
1623 GLint new_gl_surface_order = allow_overlapping_views_ ? -1 : 1; | |
1624 [compositing_iosurface_context_->nsgl_context() | |
1625 getValues:&old_gl_surface_order | |
1626 forParameter:NSOpenGLCPSurfaceOrder]; | |
1627 if (old_gl_surface_order != new_gl_surface_order) { | |
1628 [compositing_iosurface_context_->nsgl_context() | |
1629 setValues:&new_gl_surface_order | |
1630 forParameter:NSOpenGLCPSurfaceOrder]; | |
1631 } | |
1632 | |
1633 // Instead of drawing, request that underlay view redraws. | |
1634 if (underlay_view_ && | |
1635 underlay_view_->compositing_iosurface_ && | |
1636 underlay_view_has_drawn_) { | |
1637 [underlay_view_->cocoa_view() setNeedsDisplayInRect:NSMakeRect(0, 0, 1, 1)]; | |
1638 return; | |
1639 } | |
1640 | |
1641 bool has_overlay = overlay_view_ && overlay_view_->compositing_iosurface_; | |
1642 if (has_overlay) { | |
1643 // Un-bind the overlay view's OpenGL context, since its content will be | |
1644 // drawn by this context. Not doing this can result in corruption. | |
1645 // http://crbug.com/330701 | |
1646 overlay_view_->ClearBoundContextDrawable(); | |
1647 } | |
1648 [compositing_iosurface_context_->nsgl_context() setView:cocoa_view_]; | |
1649 | |
1650 gfx::Rect view_rect(NSRectToCGRect([cocoa_view_ frame])); | |
1651 if (!compositing_iosurface_->DrawIOSurface( | |
1652 compositing_iosurface_context_, view_rect, | |
1653 ViewScaleFactor(), !has_overlay)) { | |
1654 GotAcceleratedCompositingError(); | |
1655 return; | |
1656 } | |
1657 | |
1658 if (has_overlay) { | |
1659 overlay_view_->underlay_view_has_drawn_ = true; | |
1660 gfx::Rect overlay_view_rect( | |
1661 NSRectToCGRect([overlay_view_->cocoa_view() frame])); | |
1662 overlay_view_rect.set_x(overlay_view_offset_.x()); | |
1663 overlay_view_rect.set_y(view_rect.height() - | |
1664 overlay_view_rect.height() - | |
1665 overlay_view_offset_.y()); | |
1666 if (!overlay_view_->compositing_iosurface_->DrawIOSurface( | |
1667 compositing_iosurface_context_, overlay_view_rect, | |
1668 overlay_view_->ViewScaleFactor(), true)) { | |
1669 GotAcceleratedCompositingError(); | |
1670 return; | |
1671 } | |
1672 } | |
1673 | |
1674 SendPendingLatencyInfoToHost(); | |
1675 } | |
1676 | |
1677 void RenderWidgetHostViewMac::GotAcceleratedCompositingError() { | 1541 void RenderWidgetHostViewMac::GotAcceleratedCompositingError() { |
1678 LOG(ERROR) << "Encountered accelerated compositing error"; | 1542 LOG(ERROR) << "Encountered accelerated compositing error"; |
1679 base::MessageLoop::current()->PostTask( | 1543 base::MessageLoop::current()->PostTask( |
1680 FROM_HERE, | 1544 FROM_HERE, |
1681 base::Bind(&RenderWidgetHostViewMac::DestroyCompositingStateOnError, | 1545 base::Bind(&RenderWidgetHostViewMac::DestroyCompositingStateOnError, |
1682 weak_factory_.GetWeakPtr())); | 1546 weak_factory_.GetWeakPtr())); |
1683 } | 1547 } |
1684 | 1548 |
1685 void RenderWidgetHostViewMac::DestroyCompositingStateOnError() { | 1549 void RenderWidgetHostViewMac::DestroyCompositingStateOnError() { |
1686 // This should be called with a clean stack. Make sure that no context is | 1550 // This should be called with a clean stack. Make sure that no context is |
1687 // current. | 1551 // current. |
1688 DCHECK(!CGLGetCurrentContext()); | 1552 DCHECK(!CGLGetCurrentContext()); |
1689 | 1553 |
1690 // The existing GL contexts may be in a bad state, so don't re-use any of the | 1554 // The existing GL contexts may be in a bad state, so don't re-use any of the |
1691 // existing ones anymore, rather, allocate new ones. | 1555 // existing ones anymore, rather, allocate new ones. |
1692 if (compositing_iosurface_context_) | 1556 if (compositing_iosurface_context_) |
1693 compositing_iosurface_context_->PoisonContextAndSharegroup(); | 1557 compositing_iosurface_context_->PoisonContextAndSharegroup(); |
1694 | 1558 |
1695 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); | 1559 DestroyCompositedIOSurfaceAndLayer(); |
1696 | 1560 |
1697 // Request that a new frame be generated and dirty the view. | 1561 // Request that a new frame be generated and dirty the view. |
1698 if (render_widget_host_) | 1562 if (render_widget_host_) |
1699 render_widget_host_->ScheduleComposite(); | 1563 render_widget_host_->ScheduleComposite(); |
1700 [cocoa_view_ setNeedsDisplay:YES]; | 1564 [cocoa_view_ setNeedsDisplay:YES]; |
1701 | 1565 |
1702 // Mark the last frame as not accelerated (so that the window is prepared for | |
1703 // an underlay next time an accelerated frame comes in). | |
1704 last_frame_was_accelerated_ = false; | |
1705 | |
1706 // TODO(ccameron): It may be a good idea to request that the renderer recreate | 1566 // TODO(ccameron): It may be a good idea to request that the renderer recreate |
1707 // its GL context as well, and fall back to software if this happens | 1567 // its GL context as well, and fall back to software if this happens |
1708 // repeatedly. | 1568 // repeatedly. |
1709 } | 1569 } |
1710 | 1570 |
1711 void RenderWidgetHostViewMac::SetOverlayView( | 1571 void RenderWidgetHostViewMac::SetOverlayView( |
1712 RenderWidgetHostViewMac* overlay, const gfx::Point& offset) { | 1572 RenderWidgetHostViewMac* overlay, const gfx::Point& offset) { |
1713 if (overlay_view_) | 1573 if (overlay_view_) |
1714 overlay_view_->underlay_view_.reset(); | 1574 overlay_view_->underlay_view_.reset(); |
1715 | 1575 |
1716 overlay_view_ = overlay->overlay_view_weak_factory_.GetWeakPtr(); | 1576 overlay_view_ = overlay->overlay_view_weak_factory_.GetWeakPtr(); |
1717 overlay_view_->underlay_view_ = overlay_view_weak_factory_.GetWeakPtr(); | 1577 overlay_view_->underlay_view_ = overlay_view_weak_factory_.GetWeakPtr(); |
1718 if (use_core_animation_) | |
1719 return; | |
1720 | |
1721 overlay_view_offset_ = offset; | |
1722 overlay_view_->underlay_view_has_drawn_ = false; | |
1723 | |
1724 [cocoa_view_ setNeedsDisplay:YES]; | |
1725 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; | |
1726 } | 1578 } |
1727 | 1579 |
1728 void RenderWidgetHostViewMac::RemoveOverlayView() { | 1580 void RenderWidgetHostViewMac::RemoveOverlayView() { |
1729 if (overlay_view_) { | 1581 if (overlay_view_) { |
1730 overlay_view_->underlay_view_.reset(); | 1582 overlay_view_->underlay_view_.reset(); |
1731 overlay_view_.reset(); | 1583 overlay_view_.reset(); |
1732 } | 1584 } |
1733 if (use_core_animation_) | |
1734 return; | |
1735 | |
1736 [cocoa_view_ setNeedsDisplay:YES]; | |
1737 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; | |
1738 } | 1585 } |
1739 | 1586 |
1740 bool RenderWidgetHostViewMac::GetLineBreakIndex( | 1587 bool RenderWidgetHostViewMac::GetLineBreakIndex( |
1741 const std::vector<gfx::Rect>& bounds, | 1588 const std::vector<gfx::Rect>& bounds, |
1742 const gfx::Range& range, | 1589 const gfx::Range& range, |
1743 size_t* line_break_point) { | 1590 size_t* line_break_point) { |
1744 DCHECK(line_break_point); | 1591 DCHECK(line_break_point); |
1745 if (range.start() >= bounds.size() || range.is_reversed() || range.is_empty()) | 1592 if (range.start() >= bounds.size() || range.is_reversed() || range.is_empty()) |
1746 return false; | 1593 return false; |
1747 | 1594 |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1903 params.surface_scale_factor, | 1750 params.surface_scale_factor, |
1904 params.latency_info); | 1751 params.latency_info); |
1905 } | 1752 } |
1906 | 1753 |
1907 void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() { | 1754 void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() { |
1908 if (compositing_iosurface_) | 1755 if (compositing_iosurface_) |
1909 compositing_iosurface_->UnrefIOSurface(); | 1756 compositing_iosurface_->UnrefIOSurface(); |
1910 } | 1757 } |
1911 | 1758 |
1912 void RenderWidgetHostViewMac::AcceleratedSurfaceRelease() { | 1759 void RenderWidgetHostViewMac::AcceleratedSurfaceRelease() { |
1913 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); | 1760 DestroyCompositedIOSurfaceAndLayer(); |
1914 } | 1761 } |
1915 | 1762 |
1916 bool RenderWidgetHostViewMac::HasAcceleratedSurface( | 1763 bool RenderWidgetHostViewMac::HasAcceleratedSurface( |
1917 const gfx::Size& desired_size) { | 1764 const gfx::Size& desired_size) { |
1918 if (last_frame_was_accelerated_) { | 1765 if (compositing_iosurface_) { |
1919 return compositing_iosurface_ && | 1766 return compositing_iosurface_->HasIOSurface() && |
1920 compositing_iosurface_->HasIOSurface() && | |
1921 (desired_size.IsEmpty() || | 1767 (desired_size.IsEmpty() || |
1922 compositing_iosurface_->dip_io_surface_size() == desired_size); | 1768 compositing_iosurface_->dip_io_surface_size() == desired_size); |
1923 } else { | 1769 } |
1924 return (software_frame_manager_->HasCurrentFrame() && | 1770 if (software_frame_manager_->HasCurrentFrame()) { |
1925 (desired_size.IsEmpty() || | 1771 return (desired_size.IsEmpty() || |
1926 software_frame_manager_->GetCurrentFrameSizeInDIP() == | 1772 software_frame_manager_->GetCurrentFrameSizeInDIP() == |
1927 desired_size)); | 1773 desired_size); |
1928 } | 1774 } |
1929 return false; | 1775 return false; |
1930 } | 1776 } |
1931 | 1777 |
1932 void RenderWidgetHostViewMac::OnSwapCompositorFrame( | 1778 void RenderWidgetHostViewMac::OnSwapCompositorFrame( |
1933 uint32 output_surface_id, scoped_ptr<cc::CompositorFrame> frame) { | 1779 uint32 output_surface_id, scoped_ptr<cc::CompositorFrame> frame) { |
1934 TRACE_EVENT0("browser", "RenderWidgetHostViewMac::OnSwapCompositorFrame"); | 1780 TRACE_EVENT0("browser", "RenderWidgetHostViewMac::OnSwapCompositorFrame"); |
1935 | 1781 |
1936 if (frame->delegated_frame_data) { | 1782 if (frame->delegated_frame_data) { |
1937 if (!browser_compositor_view_) { | 1783 if (!browser_compositor_view_) { |
(...skipping 23 matching lines...) Expand all Loading... | |
1961 frame->software_frame_data.get(), | 1807 frame->software_frame_data.get(), |
1962 frame->metadata.device_scale_factor, | 1808 frame->metadata.device_scale_factor, |
1963 render_widget_host_->GetProcess()->GetHandle())) { | 1809 render_widget_host_->GetProcess()->GetHandle())) { |
1964 render_widget_host_->GetProcess()->ReceivedBadMessage(); | 1810 render_widget_host_->GetProcess()->ReceivedBadMessage(); |
1965 return; | 1811 return; |
1966 } | 1812 } |
1967 | 1813 |
1968 // Add latency info to report when the frame finishes drawing. | 1814 // Add latency info to report when the frame finishes drawing. |
1969 AddPendingLatencyInfo(frame->metadata.latency_info); | 1815 AddPendingLatencyInfo(frame->metadata.latency_info); |
1970 | 1816 |
1971 if (use_core_animation_) { | 1817 const void* pixels = software_frame_manager_->GetCurrentFramePixels(); |
1972 const void* pixels = software_frame_manager_->GetCurrentFramePixels(); | 1818 gfx::Size size_in_pixels = |
1973 gfx::Size size_in_pixels = | 1819 software_frame_manager_->GetCurrentFrameSizeInPixels(); |
1974 software_frame_manager_->GetCurrentFrameSizeInPixels(); | |
1975 | 1820 |
1976 EnsureSoftwareLayer(); | 1821 EnsureSoftwareLayer(); |
1977 [software_layer_ setContentsToData:pixels | 1822 [software_layer_ setContentsToData:pixels |
1978 withRowBytes:4 * size_in_pixels.width() | 1823 withRowBytes:4 * size_in_pixels.width() |
1979 withPixelSize:size_in_pixels | 1824 withPixelSize:size_in_pixels |
1980 withScaleFactor:frame->metadata.device_scale_factor]; | 1825 withScaleFactor:frame->metadata.device_scale_factor]; |
1981 | 1826 |
1982 // Send latency information to the host immediately, as there will be no | 1827 // Send latency information to the host immediately, as there will be no |
1983 // subsequent draw call in which to do so. | 1828 // subsequent draw call in which to do so. |
1984 SendPendingLatencyInfoToHost(); | 1829 SendPendingLatencyInfoToHost(); |
1985 } | |
1986 | 1830 |
1987 GotSoftwareFrame(); | 1831 GotSoftwareFrame(); |
1988 | 1832 |
1989 cc::CompositorFrameAck ack; | 1833 cc::CompositorFrameAck ack; |
1990 RenderWidgetHostImpl::SendSwapCompositorFrameAck( | 1834 RenderWidgetHostImpl::SendSwapCompositorFrameAck( |
1991 render_widget_host_->GetRoutingID(), | 1835 render_widget_host_->GetRoutingID(), |
1992 software_frame_manager_->GetCurrentFrameOutputSurfaceId(), | 1836 software_frame_manager_->GetCurrentFrameOutputSurfaceId(), |
1993 render_widget_host_->GetProcess()->GetID(), | 1837 render_widget_host_->GetProcess()->GetID(), |
1994 ack); | 1838 ack); |
1995 software_frame_manager_->SwapToNewFrameComplete( | 1839 software_frame_manager_->SwapToNewFrameComplete( |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2108 | 1952 |
2109 void RenderWidgetHostViewMac::ShutdownHost() { | 1953 void RenderWidgetHostViewMac::ShutdownHost() { |
2110 weak_factory_.InvalidateWeakPtrs(); | 1954 weak_factory_.InvalidateWeakPtrs(); |
2111 render_widget_host_->Shutdown(); | 1955 render_widget_host_->Shutdown(); |
2112 // Do not touch any members at this point, |this| has been deleted. | 1956 // Do not touch any members at this point, |this| has been deleted. |
2113 } | 1957 } |
2114 | 1958 |
2115 void RenderWidgetHostViewMac::GotAcceleratedFrame() { | 1959 void RenderWidgetHostViewMac::GotAcceleratedFrame() { |
2116 EnsureCompositedIOSurfaceLayer(); | 1960 EnsureCompositedIOSurfaceLayer(); |
2117 SendVSyncParametersToRenderer(); | 1961 SendVSyncParametersToRenderer(); |
2118 if (!last_frame_was_accelerated_) { | |
2119 last_frame_was_accelerated_ = true; | |
2120 | 1962 |
2121 if (!use_core_animation_) { | 1963 // Delete software backingstore and layer. |
2122 // Need to wipe the software view with transparency to expose the GL | 1964 software_frame_manager_->DiscardCurrentFrame(); |
2123 // underlay. Invalidate the whole window to do that. | 1965 DestroySoftwareLayer(); |
2124 [cocoa_view_ setNeedsDisplay:YES]; | |
2125 } | |
2126 | |
2127 // Delete software backingstore and layer. | |
2128 software_frame_manager_->DiscardCurrentFrame(); | |
2129 DestroySoftwareLayer(); | |
2130 } | |
2131 } | 1966 } |
2132 | 1967 |
2133 void RenderWidgetHostViewMac::GotSoftwareFrame() { | 1968 void RenderWidgetHostViewMac::GotSoftwareFrame() { |
2134 TRACE_EVENT0("browser", "RenderWidgetHostViewMac::GotSoftwareFrame"); | 1969 TRACE_EVENT0("browser", "RenderWidgetHostViewMac::GotSoftwareFrame"); |
2135 | 1970 |
2136 if (!render_widget_host_) | 1971 if (!render_widget_host_) |
2137 return; | 1972 return; |
2138 | 1973 |
2139 EnsureSoftwareLayer(); | 1974 EnsureSoftwareLayer(); |
2140 LayoutLayers(); | 1975 LayoutLayers(); |
2141 SendVSyncParametersToRenderer(); | 1976 SendVSyncParametersToRenderer(); |
2142 | 1977 |
2143 // Draw the contents of the frame immediately. It is critical that this | 1978 // Draw the contents of the frame immediately. It is critical that this |
2144 // happen before the frame be acked, otherwise the new frame will likely be | 1979 // happen before the frame be acked, otherwise the new frame will likely be |
2145 // ready before the drawing is complete, thrashing the browser main thread. | 1980 // ready before the drawing is complete, thrashing the browser main thread. |
2146 if (use_core_animation_) { | 1981 [software_layer_ displayIfNeeded]; |
2147 [software_layer_ displayIfNeeded]; | |
2148 } else { | |
2149 [cocoa_view_ setNeedsDisplay:YES]; | |
2150 [cocoa_view_ displayIfNeeded]; | |
2151 } | |
2152 | 1982 |
2153 if (last_frame_was_accelerated_) { | 1983 DestroyCompositedIOSurfaceAndLayer(); |
2154 last_frame_was_accelerated_ = false; | |
2155 | |
2156 // If overlapping views are allowed, then don't unbind the context | |
2157 // from the view (that is, don't call clearDrawble -- just delete the | |
2158 // texture and IOSurface). Rather, let it sit behind the software frame | |
2159 // that will be put up in front. This will prevent transparent | |
2160 // flashes. | |
2161 // http://crbug.com/154531 | |
2162 // Also note that it is necessary that clearDrawable be called if | |
2163 // overlapping views are not allowed, e.g, for content shell. | |
2164 // http://crbug.com/178408 | |
2165 // Disable screen updates so that the changes of flashes is minimized. | |
2166 // http://crbug.com/279472 | |
2167 if (!use_core_animation_) | |
2168 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; | |
2169 if (allow_overlapping_views_) | |
2170 DestroyCompositedIOSurfaceAndLayer(kLeaveContextBoundToView); | |
2171 else | |
2172 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); | |
2173 } | |
2174 } | 1984 } |
2175 | 1985 |
2176 void RenderWidgetHostViewMac::SetActive(bool active) { | 1986 void RenderWidgetHostViewMac::SetActive(bool active) { |
2177 if (render_widget_host_) { | 1987 if (render_widget_host_) { |
2178 render_widget_host_->SetActive(active); | 1988 render_widget_host_->SetActive(active); |
2179 if (active) { | 1989 if (active) { |
2180 if (HasFocus()) | 1990 if (HasFocus()) |
2181 render_widget_host_->Focus(); | 1991 render_widget_host_->Focus(); |
2182 } else { | 1992 } else { |
2183 render_widget_host_->Blur(); | 1993 render_widget_host_->Blur(); |
(...skipping 13 matching lines...) Expand all Loading... | |
2197 render_widget_host_->GetRoutingID(), visible)); | 2007 render_widget_host_->GetRoutingID(), visible)); |
2198 } | 2008 } |
2199 } | 2009 } |
2200 | 2010 |
2201 void RenderWidgetHostViewMac::WindowFrameChanged() { | 2011 void RenderWidgetHostViewMac::WindowFrameChanged() { |
2202 if (render_widget_host_) { | 2012 if (render_widget_host_) { |
2203 render_widget_host_->Send(new ViewMsg_WindowFrameChanged( | 2013 render_widget_host_->Send(new ViewMsg_WindowFrameChanged( |
2204 render_widget_host_->GetRoutingID(), GetBoundsInRootWindow(), | 2014 render_widget_host_->GetRoutingID(), GetBoundsInRootWindow(), |
2205 GetViewBounds())); | 2015 GetViewBounds())); |
2206 } | 2016 } |
2207 | |
2208 if (compositing_iosurface_ && !use_core_animation_) { | |
2209 // This will migrate the context to the appropriate window. | |
2210 if (!EnsureCompositedIOSurface()) | |
2211 GotAcceleratedCompositingError(); | |
2212 } | |
2213 } | 2017 } |
2214 | 2018 |
2215 void RenderWidgetHostViewMac::ShowDefinitionForSelection() { | 2019 void RenderWidgetHostViewMac::ShowDefinitionForSelection() { |
2216 RenderWidgetHostViewMacDictionaryHelper helper(this); | 2020 RenderWidgetHostViewMacDictionaryHelper helper(this); |
2217 helper.ShowDefinitionForSelection(); | 2021 helper.ShowDefinitionForSelection(); |
2218 } | 2022 } |
2219 | 2023 |
2220 void RenderWidgetHostViewMac::SetBackgroundOpaque(bool opaque) { | 2024 void RenderWidgetHostViewMac::SetBackgroundOpaque(bool opaque) { |
2221 RenderWidgetHostViewBase::SetBackgroundOpaque(opaque); | 2025 RenderWidgetHostViewBase::SetBackgroundOpaque(opaque); |
2222 if (render_widget_host_) | 2026 if (render_widget_host_) |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2321 | 2125 |
2322 return gfx::ToEnclosingRect(gfx::ScaleRect(src_gl_subrect, | 2126 return gfx::ToEnclosingRect(gfx::ScaleRect(src_gl_subrect, |
2323 ViewScaleFactor())); | 2127 ViewScaleFactor())); |
2324 } | 2128 } |
2325 | 2129 |
2326 void RenderWidgetHostViewMac::AddPendingLatencyInfo( | 2130 void RenderWidgetHostViewMac::AddPendingLatencyInfo( |
2327 const std::vector<ui::LatencyInfo>& latency_info) { | 2131 const std::vector<ui::LatencyInfo>& latency_info) { |
2328 // If a screenshot is being taken when using CoreAnimation, send a few extra | 2132 // If a screenshot is being taken when using CoreAnimation, send a few extra |
2329 // calls to setNeedsDisplay and wait for their resulting display calls, | 2133 // calls to setNeedsDisplay and wait for their resulting display calls, |
2330 // before reporting that the frame has reached the screen. | 2134 // before reporting that the frame has reached the screen. |
2331 if (use_core_animation_) { | 2135 bool should_defer = false; |
2332 bool should_defer = false; | 2136 for (size_t i = 0; i < latency_info.size(); i++) { |
2333 for (size_t i = 0; i < latency_info.size(); i++) { | 2137 if (latency_info[i].FindLatency( |
2334 if (latency_info[i].FindLatency( | 2138 ui::WINDOW_SNAPSHOT_FRAME_NUMBER_COMPONENT, |
2335 ui::WINDOW_SNAPSHOT_FRAME_NUMBER_COMPONENT, | 2139 render_widget_host_->GetLatencyComponentId(), |
2336 render_widget_host_->GetLatencyComponentId(), | 2140 NULL)) { |
2337 NULL)) { | 2141 should_defer = true; |
2338 should_defer = true; | |
2339 } | |
2340 } | 2142 } |
2341 if (should_defer) { | 2143 } |
2342 // Multiple pending screenshot requests will work, but if every frame | 2144 if (should_defer) { |
2343 // requests a screenshot, then the delay will never expire. Assert this | 2145 // Multiple pending screenshot requests will work, but if every frame |
2344 // here to avoid this. | 2146 // requests a screenshot, then the delay will never expire. Assert this |
2345 CHECK_EQ(pending_latency_info_delay_, 0u); | 2147 // here to avoid this. |
2346 // Wait a fixed number of frames (calls to CALayer::display) before | 2148 CHECK_EQ(pending_latency_info_delay_, 0u); |
2347 // claiming that the screenshot has reached the screen. This number | 2149 // Wait a fixed number of frames (calls to CALayer::display) before |
2348 // comes from taking the first number where tests didn't fail (six), | 2150 // claiming that the screenshot has reached the screen. This number |
2349 // and doubling it. | 2151 // comes from taking the first number where tests didn't fail (six), |
2350 const uint32 kScreenshotLatencyDelayInFrames = 12; | 2152 // and doubling it. |
2351 pending_latency_info_delay_ = kScreenshotLatencyDelayInFrames; | 2153 const uint32 kScreenshotLatencyDelayInFrames = 12; |
2352 TickPendingLatencyInfoDelay(); | 2154 pending_latency_info_delay_ = kScreenshotLatencyDelayInFrames; |
2353 } | 2155 TickPendingLatencyInfoDelay(); |
2354 } | 2156 } |
2355 | 2157 |
2356 for (size_t i = 0; i < latency_info.size(); i++) { | 2158 for (size_t i = 0; i < latency_info.size(); i++) { |
2357 pending_latency_info_.push_back(latency_info[i]); | 2159 pending_latency_info_.push_back(latency_info[i]); |
2358 } | 2160 } |
2359 } | 2161 } |
2360 | 2162 |
2361 void RenderWidgetHostViewMac::SendPendingLatencyInfoToHost() { | 2163 void RenderWidgetHostViewMac::SendPendingLatencyInfoToHost() { |
2362 if (pending_latency_info_delay_) { | 2164 if (pending_latency_info_delay_) { |
2363 pending_latency_info_delay_ -= 1; | 2165 pending_latency_info_delay_ -= 1; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2435 render_widget_host_->PauseForPendingResizeOrRepaints(); | 2237 render_widget_host_->PauseForPendingResizeOrRepaints(); |
2436 | 2238 |
2437 // Immediately draw any frames that haven't been drawn yet. This is necessary | 2239 // Immediately draw any frames that haven't been drawn yet. This is necessary |
2438 // to keep the window and the window's contents in sync. | 2240 // to keep the window and the window's contents in sync. |
2439 [cocoa_view_ displayIfNeeded]; | 2241 [cocoa_view_ displayIfNeeded]; |
2440 [software_layer_ displayIfNeeded]; | 2242 [software_layer_ displayIfNeeded]; |
2441 [compositing_iosurface_layer_ displayIfNeeded]; | 2243 [compositing_iosurface_layer_ displayIfNeeded]; |
2442 } | 2244 } |
2443 | 2245 |
2444 void RenderWidgetHostViewMac::LayoutLayers() { | 2246 void RenderWidgetHostViewMac::LayoutLayers() { |
2445 if (!use_core_animation_) | |
2446 return; | |
2447 | |
2448 if (browser_compositor_view_) { | 2247 if (browser_compositor_view_) { |
2449 [browser_compositor_view_ layoutLayers]; | 2248 [browser_compositor_view_ layoutLayers]; |
2450 return; | 2249 return; |
2451 } | 2250 } |
2452 | 2251 |
2453 // Disable animation of the layer's resizing or change in contents scale. | 2252 // Disable animation of the layer's resizing or change in contents scale. |
2454 ScopedCAActionDisabler disabler; | 2253 ScopedCAActionDisabler disabler; |
2455 | 2254 |
2456 CGRect new_background_frame = NSRectToCGRect([cocoa_view() bounds]); | 2255 CGRect new_background_frame = NSRectToCGRect([cocoa_view() bounds]); |
2457 | 2256 |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2553 ui::GetScaleFactorForNativeView(self); | 2352 ui::GetScaleFactorForNativeView(self); |
2554 | 2353 |
2555 // OpenGL support: | 2354 // OpenGL support: |
2556 if ([self respondsToSelector: | 2355 if ([self respondsToSelector: |
2557 @selector(setWantsBestResolutionOpenGLSurface:)]) { | 2356 @selector(setWantsBestResolutionOpenGLSurface:)]) { |
2558 [self setWantsBestResolutionOpenGLSurface:YES]; | 2357 [self setWantsBestResolutionOpenGLSurface:YES]; |
2559 } | 2358 } |
2560 handlingGlobalFrameDidChange_ = NO; | 2359 handlingGlobalFrameDidChange_ = NO; |
2561 [[NSNotificationCenter defaultCenter] | 2360 [[NSNotificationCenter defaultCenter] |
2562 addObserver:self | 2361 addObserver:self |
2563 selector:@selector(globalFrameDidChange:) | |
2564 name:NSViewGlobalFrameDidChangeNotification | |
2565 object:self]; | |
2566 [[NSNotificationCenter defaultCenter] | |
2567 addObserver:self | |
2568 selector:@selector(didChangeScreenParameters:) | 2362 selector:@selector(didChangeScreenParameters:) |
2569 name:NSApplicationDidChangeScreenParametersNotification | 2363 name:NSApplicationDidChangeScreenParametersNotification |
2570 object:nil]; | 2364 object:nil]; |
2571 } | 2365 } |
2572 return self; | 2366 return self; |
2573 } | 2367 } |
2574 | 2368 |
2575 - (void)dealloc { | 2369 - (void)dealloc { |
2576 // Unbind the GL context from this view. If this is not done before super's | 2370 // Unbind the GL context from this view. If this is not done before super's |
2577 // dealloc is called then the GL context will crash when it reaches into | 2371 // dealloc is called then the GL context will crash when it reaches into |
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3192 // it for anything yet. | 2986 // it for anything yet. |
3193 const WebGestureEvent& webEvent = | 2987 const WebGestureEvent& webEvent = |
3194 WebInputEventFactory::gestureEvent(event, self); | 2988 WebInputEventFactory::gestureEvent(event, self); |
3195 renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(webEvent); | 2989 renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(webEvent); |
3196 } | 2990 } |
3197 } | 2991 } |
3198 | 2992 |
3199 - (void)viewWillMoveToWindow:(NSWindow*)newWindow { | 2993 - (void)viewWillMoveToWindow:(NSWindow*)newWindow { |
3200 NSWindow* oldWindow = [self window]; | 2994 NSWindow* oldWindow = [self window]; |
3201 | 2995 |
3202 // We're messing with the window, so do this to ensure no flashes. This one | |
3203 // prevents a flash when the current tab is closed. | |
3204 if (!renderWidgetHostView_->use_core_animation_) | |
3205 [oldWindow disableScreenUpdatesUntilFlush]; | |
3206 | |
3207 NSNotificationCenter* notificationCenter = | 2996 NSNotificationCenter* notificationCenter = |
3208 [NSNotificationCenter defaultCenter]; | 2997 [NSNotificationCenter defaultCenter]; |
3209 | 2998 |
3210 // Backing property notifications crash on 10.6 when building with the 10.7 | 2999 // Backing property notifications crash on 10.6 when building with the 10.7 |
3211 // SDK, see http://crbug.com/260595. | 3000 // SDK, see http://crbug.com/260595. |
3212 static BOOL supportsBackingPropertiesNotification = | 3001 static BOOL supportsBackingPropertiesNotification = |
3213 SupportsBackingPropertiesChangedNotification(); | 3002 SupportsBackingPropertiesChangedNotification(); |
3214 | 3003 |
3215 if (oldWindow) { | 3004 if (oldWindow) { |
3216 if (supportsBackingPropertiesNotification) { | 3005 if (supportsBackingPropertiesNotification) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3261 | 3050 |
3262 // Allocating a CGLayerRef with the current scale factor immediately from | 3051 // Allocating a CGLayerRef with the current scale factor immediately from |
3263 // this handler doesn't work. Schedule the backing store update on the | 3052 // this handler doesn't work. Schedule the backing store update on the |
3264 // next runloop cycle, then things are read for CGLayerRef allocations to | 3053 // next runloop cycle, then things are read for CGLayerRef allocations to |
3265 // work. | 3054 // work. |
3266 [self performSelector:@selector(updateScreenProperties) | 3055 [self performSelector:@selector(updateScreenProperties) |
3267 withObject:nil | 3056 withObject:nil |
3268 afterDelay:0]; | 3057 afterDelay:0]; |
3269 } | 3058 } |
3270 | 3059 |
3271 - (void)globalFrameDidChange:(NSNotification*)notification { | |
3272 if (handlingGlobalFrameDidChange_) | |
3273 return; | |
3274 | |
3275 handlingGlobalFrameDidChange_ = YES; | |
3276 if (!renderWidgetHostView_->use_core_animation_ && | |
3277 renderWidgetHostView_->compositing_iosurface_context_) { | |
3278 [renderWidgetHostView_->compositing_iosurface_context_->nsgl_context() | |
3279 update]; | |
3280 } | |
3281 handlingGlobalFrameDidChange_ = NO; | |
3282 } | |
3283 | |
3284 - (void)windowChangedGlobalFrame:(NSNotification*)notification { | 3060 - (void)windowChangedGlobalFrame:(NSNotification*)notification { |
3285 renderWidgetHostView_->UpdateScreenInfo( | 3061 renderWidgetHostView_->UpdateScreenInfo( |
3286 renderWidgetHostView_->GetNativeView()); | 3062 renderWidgetHostView_->GetNativeView()); |
3287 } | 3063 } |
3288 | 3064 |
3289 - (void)setFrameSize:(NSSize)newSize { | 3065 - (void)setFrameSize:(NSSize)newSize { |
3290 TRACE_EVENT0("browser", "RenderWidgetHostViewCocoa::setFrameSize"); | 3066 TRACE_EVENT0("browser", "RenderWidgetHostViewCocoa::setFrameSize"); |
3291 | 3067 |
3292 // NB: -[NSView setFrame:] calls through -setFrameSize:, so overriding | 3068 // NB: -[NSView setFrame:] calls through -setFrameSize:, so overriding |
3293 // -setFrame: isn't neccessary. | 3069 // -setFrame: isn't neccessary. |
(...skipping 12 matching lines...) Expand all Loading... | |
3306 if (renderWidgetHostView_->delegated_frame_host_) | 3082 if (renderWidgetHostView_->delegated_frame_host_) |
3307 renderWidgetHostView_->delegated_frame_host_->WasResized(); | 3083 renderWidgetHostView_->delegated_frame_host_->WasResized(); |
3308 | 3084 |
3309 // Wait for the frame that WasResize might have requested. If the view is | 3085 // Wait for the frame that WasResize might have requested. If the view is |
3310 // being made visible at a new size, then this call will have no effect | 3086 // being made visible at a new size, then this call will have no effect |
3311 // because the view widget is still hidden, and the pause call in WasShown | 3087 // because the view widget is still hidden, and the pause call in WasShown |
3312 // will have this effect for us. | 3088 // will have this effect for us. |
3313 renderWidgetHostView_->PauseForPendingResizeOrRepaintsAndDraw(); | 3089 renderWidgetHostView_->PauseForPendingResizeOrRepaintsAndDraw(); |
3314 } | 3090 } |
3315 | 3091 |
3316 // Fills with white the parts of the area to the right and bottom for |rect| | |
3317 // that intersect |damagedRect|. | |
3318 - (void)fillBottomRightRemainderOfRect:(gfx::Rect)rect | |
3319 dirtyRect:(gfx::Rect)damagedRect | |
3320 inContext:(CGContextRef)context { | |
3321 if (damagedRect.right() > rect.right()) { | |
3322 int x = std::max(rect.right(), damagedRect.x()); | |
3323 int y = std::min(rect.bottom(), damagedRect.bottom()); | |
3324 int width = damagedRect.right() - x; | |
3325 int height = damagedRect.y() - y; | |
3326 | |
3327 // Extra fun to get around the fact that gfx::Rects can't have | |
3328 // negative sizes. | |
3329 if (width < 0) { | |
3330 x += width; | |
3331 width = -width; | |
3332 } | |
3333 if (height < 0) { | |
3334 y += height; | |
3335 height = -height; | |
3336 } | |
3337 | |
3338 NSRect r = [self flipRectToNSRect:gfx::Rect(x, y, width, height)]; | |
3339 CGContextSetFillColorWithColor(context, | |
3340 CGColorGetConstantColor(kCGColorWhite)); | |
3341 CGContextFillRect(context, NSRectToCGRect(r)); | |
3342 } | |
3343 if (damagedRect.bottom() > rect.bottom()) { | |
3344 int x = damagedRect.x(); | |
3345 int y = damagedRect.bottom(); | |
3346 int width = damagedRect.right() - x; | |
3347 int height = std::max(rect.bottom(), damagedRect.y()) - y; | |
3348 | |
3349 // Extra fun to get around the fact that gfx::Rects can't have | |
3350 // negative sizes. | |
3351 if (width < 0) { | |
3352 x += width; | |
3353 width = -width; | |
3354 } | |
3355 if (height < 0) { | |
3356 y += height; | |
3357 height = -height; | |
3358 } | |
3359 | |
3360 NSRect r = [self flipRectToNSRect:gfx::Rect(x, y, width, height)]; | |
3361 CGContextSetFillColorWithColor(context, | |
3362 CGColorGetConstantColor(kCGColorWhite)); | |
3363 CGContextFillRect(context, NSRectToCGRect(r)); | |
3364 } | |
3365 } | |
3366 | |
3367 - (void)drawRect:(NSRect)dirtyRect { | |
3368 TRACE_EVENT0("browser", "RenderWidgetHostViewCocoa::drawRect"); | |
3369 DCHECK(!renderWidgetHostView_->use_core_animation_); | |
3370 | |
3371 if (!renderWidgetHostView_->render_widget_host_) { | |
3372 // When using CoreAnimation, this path is used to paint the contents area | |
3373 // white before any frames come in. When layers to draw frames exist, this | |
3374 // is not hit. | |
3375 [[NSColor whiteColor] set]; | |
3376 NSRectFill(dirtyRect); | |
3377 return; | |
3378 } | |
3379 | |
3380 const gfx::Rect damagedRect([self flipNSRectToRect:dirtyRect]); | |
3381 | |
3382 if (renderWidgetHostView_->last_frame_was_accelerated_ && | |
3383 renderWidgetHostView_->compositing_iosurface_) { | |
3384 if (renderWidgetHostView_->allow_overlapping_views_) { | |
3385 // If overlapping views need to be allowed, punch a hole in the window | |
3386 // to expose the GL underlay. | |
3387 TRACE_EVENT2("gpu", "NSRectFill clear", "w", damagedRect.width(), | |
3388 "h", damagedRect.height()); | |
3389 // NSRectFill is extremely slow (15ms for a window on a fast MacPro), so | |
3390 // this is only done when it's a real invalidation from window damage (not | |
3391 // when a BuffersSwapped was received). Note that even a 1x1 NSRectFill | |
3392 // can take many milliseconds sometimes (!) so this is skipped completely | |
3393 // for drawRects that are triggered by BuffersSwapped messages. | |
3394 [[NSColor clearColor] set]; | |
3395 NSRectFill(dirtyRect); | |
3396 } | |
3397 | |
3398 gfx::ScopedCGLSetCurrentContext scoped_set_current_context( | |
3399 renderWidgetHostView_->compositing_iosurface_context_->cgl_context()); | |
3400 renderWidgetHostView_->DrawIOSurfaceWithoutCoreAnimation(); | |
3401 return; | |
3402 } | |
3403 | |
3404 CGContextRef context = static_cast<CGContextRef>( | |
3405 [[NSGraphicsContext currentContext] graphicsPort]); | |
3406 [self drawWithDirtyRect:NSRectToCGRect(dirtyRect) | |
3407 inContext:context]; | |
3408 } | |
3409 | |
3410 - (void)drawWithDirtyRect:(CGRect)dirtyRect | |
3411 inContext:(CGContextRef)context { | |
3412 content::SoftwareFrameManager* software_frame_manager = | |
3413 renderWidgetHostView_->software_frame_manager_.get(); | |
3414 if (software_frame_manager->HasCurrentFrame()) { | |
3415 // Note: All coordinates are in view units, not pixels. | |
3416 gfx::Rect bitmapRect( | |
3417 software_frame_manager->GetCurrentFrameSizeInDIP()); | |
3418 | |
3419 // Specify the proper y offset to ensure that the view is rooted to the | |
3420 // upper left corner. This can be negative, if the window was resized | |
3421 // smaller and the renderer hasn't yet repainted. | |
3422 int yOffset = NSHeight([self bounds]) - bitmapRect.height(); | |
3423 | |
3424 NSRect nsDirtyRect = NSRectFromCGRect(dirtyRect); | |
3425 const gfx::Rect damagedRect([self flipNSRectToRect:nsDirtyRect]); | |
3426 | |
3427 gfx::Rect paintRect = gfx::IntersectRects(bitmapRect, damagedRect); | |
3428 if (!paintRect.IsEmpty()) { | |
3429 gfx::Size sizeInPixels = | |
3430 software_frame_manager->GetCurrentFrameSizeInPixels(); | |
3431 base::ScopedCFTypeRef<CGDataProviderRef> dataProvider( | |
3432 CGDataProviderCreateWithData( | |
3433 NULL, | |
3434 software_frame_manager->GetCurrentFramePixels(), | |
3435 4 * sizeInPixels.width() * sizeInPixels.height(), | |
3436 NULL)); | |
3437 base::ScopedCFTypeRef<CGImageRef> image( | |
3438 CGImageCreate( | |
3439 sizeInPixels.width(), | |
3440 sizeInPixels.height(), | |
3441 8, | |
3442 32, | |
3443 4 * sizeInPixels.width(), | |
3444 base::mac::GetSystemColorSpace(), | |
3445 kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, | |
3446 dataProvider, | |
3447 NULL, | |
3448 false, | |
3449 kCGRenderingIntentDefault)); | |
3450 CGRect imageRect = bitmapRect.ToCGRect(); | |
3451 imageRect.origin.y = yOffset; | |
3452 CGContextDrawImage(context, imageRect, image); | |
3453 } | |
3454 | |
3455 renderWidgetHostView_->SendPendingLatencyInfoToHost(); | |
3456 | |
3457 // Fill the remaining portion of the damagedRect with white | |
3458 [self fillBottomRightRemainderOfRect:bitmapRect | |
3459 dirtyRect:damagedRect | |
3460 inContext:context]; | |
3461 | |
3462 if (!renderWidgetHostView_->whiteout_start_time_.is_null()) { | |
3463 base::TimeDelta whiteout_duration = base::TimeTicks::Now() - | |
3464 renderWidgetHostView_->whiteout_start_time_; | |
3465 UMA_HISTOGRAM_TIMES("MPArch.RWHH_WhiteoutDuration", whiteout_duration); | |
3466 | |
3467 // Reset the start time to 0 so that we start recording again the next | |
3468 // time the backing store is NULL... | |
3469 renderWidgetHostView_->whiteout_start_time_ = base::TimeTicks(); | |
3470 } | |
3471 if (!renderWidgetHostView_->web_contents_switch_paint_time_.is_null()) { | |
3472 base::TimeDelta web_contents_switch_paint_duration = | |
3473 base::TimeTicks::Now() - | |
3474 renderWidgetHostView_->web_contents_switch_paint_time_; | |
3475 UMA_HISTOGRAM_TIMES("MPArch.RWH_TabSwitchPaintDuration", | |
3476 web_contents_switch_paint_duration); | |
3477 // Reset contents_switch_paint_time_ to 0 so future tab selections are | |
3478 // recorded. | |
3479 renderWidgetHostView_->web_contents_switch_paint_time_ = | |
3480 base::TimeTicks(); | |
3481 } | |
3482 } else { | |
3483 CGContextSetFillColorWithColor(context, | |
3484 CGColorGetConstantColor(kCGColorWhite)); | |
3485 CGContextFillRect(context, dirtyRect); | |
3486 if (renderWidgetHostView_->whiteout_start_time_.is_null()) | |
3487 renderWidgetHostView_->whiteout_start_time_ = base::TimeTicks::Now(); | |
3488 } | |
3489 } | |
3490 | |
3491 - (BOOL)canBecomeKeyView { | 3092 - (BOOL)canBecomeKeyView { |
3492 if (!renderWidgetHostView_->render_widget_host_) | 3093 if (!renderWidgetHostView_->render_widget_host_) |
3493 return NO; | 3094 return NO; |
3494 | 3095 |
3495 return canBeKeyView_; | 3096 return canBeKeyView_; |
3496 } | 3097 } |
3497 | 3098 |
3498 - (BOOL)acceptsFirstResponder { | 3099 - (BOOL)acceptsFirstResponder { |
3499 if (!renderWidgetHostView_->render_widget_host_) | 3100 if (!renderWidgetHostView_->render_widget_host_) |
3500 return NO; | 3101 return NO; |
(...skipping 909 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4410 if (!string) return NO; | 4011 if (!string) return NO; |
4411 | 4012 |
4412 // If the user is currently using an IME, confirm the IME input, | 4013 // If the user is currently using an IME, confirm the IME input, |
4413 // and then insert the text from the service, the same as TextEdit and Safari. | 4014 // and then insert the text from the service, the same as TextEdit and Safari. |
4414 [self confirmComposition]; | 4015 [self confirmComposition]; |
4415 [self insertText:string]; | 4016 [self insertText:string]; |
4416 return YES; | 4017 return YES; |
4417 } | 4018 } |
4418 | 4019 |
4419 - (BOOL)isOpaque { | 4020 - (BOOL)isOpaque { |
4420 if (renderWidgetHostView_->use_core_animation_) | 4021 return YES; |
4421 return YES; | |
4422 return [super isOpaque]; | |
4423 } | 4022 } |
4424 | 4023 |
4425 // "-webkit-app-region: drag | no-drag" is implemented on Mac by excluding | 4024 // "-webkit-app-region: drag | no-drag" is implemented on Mac by excluding |
4426 // regions that are not draggable. (See ControlRegionView in | 4025 // regions that are not draggable. (See ControlRegionView in |
4427 // native_app_window_cocoa.mm). This requires the render host view to be | 4026 // native_app_window_cocoa.mm). This requires the render host view to be |
4428 // draggable by default. | 4027 // draggable by default. |
4429 - (BOOL)mouseDownCanMoveWindow { | 4028 - (BOOL)mouseDownCanMoveWindow { |
4430 return YES; | 4029 return YES; |
4431 } | 4030 } |
4432 | 4031 |
4433 @end | 4032 @end |
OLD | NEW |