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 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
513 compositing_iosurface_.reset(CompositingIOSurfaceMac::Create()); | 513 compositing_iosurface_.reset(CompositingIOSurfaceMac::Create()); |
514 if (!compositing_iosurface_) { | 514 if (!compositing_iosurface_) { |
515 LOG(ERROR) << "Failed to create CompositingIOSurface"; | 515 LOG(ERROR) << "Failed to create CompositingIOSurface"; |
516 return false; | 516 return false; |
517 } | 517 } |
518 } | 518 } |
519 | 519 |
520 return true; | 520 return true; |
521 } | 521 } |
522 | 522 |
523 void RenderWidgetHostViewMac::CreateSoftwareLayerAndDestroyCompositedLayer() { | 523 void RenderWidgetHostViewMac::CreateSoftwareLayer() { |
524 TRACE_EVENT0( | 524 TRACE_EVENT0("browser", "RenderWidgetHostViewMac::CreateSoftwareLayer"); |
525 "browser", | |
526 "RenderWidgetHostViewMac::CreateSoftwareLayerAndDestroyCompositedLayer"); | |
527 | |
528 if (software_layer_ || !use_core_animation_) | 525 if (software_layer_ || !use_core_animation_) |
529 return; | 526 return; |
530 | 527 |
531 ScopedCAActionDisabler disabler; | 528 ScopedCAActionDisabler disabler; |
532 | 529 |
533 // Create the layer. | 530 // Create the layer. |
534 software_layer_.reset([[SoftwareLayer alloc] | 531 software_layer_.reset([[SoftwareLayer alloc] |
535 initWithRenderWidgetHostViewMac:this]); | 532 initWithRenderWidgetHostViewMac:this]); |
536 if (!software_layer_) { | 533 if (!software_layer_) { |
537 LOG(ERROR) << "Failed to create CALayer for software rendering"; | 534 LOG(ERROR) << "Failed to create CALayer for software rendering"; |
538 return; | 535 return; |
539 } | 536 } |
540 | 537 |
541 // Make the layer current and get rid of the old layer, if there is one. | 538 // Make the layer visible. |
542 [cocoa_view_ setLayer:software_layer_]; | 539 [background_layer_ addSublayer:software_layer_]; |
543 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); | |
544 } | 540 } |
545 | 541 |
546 void RenderWidgetHostViewMac::DestroySoftwareLayer() { | 542 void RenderWidgetHostViewMac::DestroySoftwareLayer() { |
547 if (!software_layer_) | 543 if (!software_layer_) |
548 return; | 544 return; |
549 | 545 |
550 ScopedCAActionDisabler disabler; | 546 ScopedCAActionDisabler disabler; |
551 | |
552 if ([cocoa_view_ layer] == software_layer_.get()) | |
553 [cocoa_view_ setLayer:background_layer_]; | |
554 [software_layer_ removeFromSuperlayer]; | 547 [software_layer_ removeFromSuperlayer]; |
555 [software_layer_ disableRendering]; | 548 [software_layer_ disableRendering]; |
556 software_layer_.reset(); | 549 software_layer_.reset(); |
557 } | 550 } |
558 | 551 |
559 bool RenderWidgetHostViewMac::CreateCompositedLayerAndDestroySoftwareLayer() { | 552 bool RenderWidgetHostViewMac::CreateCompositedIOSurfaceLayer() { |
560 TRACE_EVENT0( | 553 TRACE_EVENT0("browser", |
561 "browser", | 554 "RenderWidgetHostViewMac::CreateCompositedIOSurfaceLayer"); |
562 "RenderWidgetHostViewMac::CreateCompositedLayerAndDestroySoftwareLayer"); | |
563 | |
564 if (compositing_iosurface_layer_ || !use_core_animation_) | 555 if (compositing_iosurface_layer_ || !use_core_animation_) |
565 return true; | 556 return true; |
566 | 557 |
567 ScopedCAActionDisabler disabler; | 558 ScopedCAActionDisabler disabler; |
568 | 559 |
569 // Create the layer. | 560 // Create the layer. |
570 compositing_iosurface_layer_.reset([[CompositingIOSurfaceLayer alloc] | 561 compositing_iosurface_layer_.reset([[CompositingIOSurfaceLayer alloc] |
571 initWithRenderWidgetHostViewMac:this]); | 562 initWithRenderWidgetHostViewMac:this]); |
572 if (!compositing_iosurface_layer_) { | 563 if (!compositing_iosurface_layer_) { |
573 LOG(ERROR) << "Failed to create CALayer for IOSurface"; | 564 LOG(ERROR) << "Failed to create CALayer for IOSurface"; |
574 return false; | 565 return false; |
575 } | 566 } |
576 | 567 |
577 // Make the layer current and get rid of the old layer, if there is one. | 568 // Make the layer visible. |
578 [cocoa_view_ setLayer:compositing_iosurface_layer_]; | 569 [background_layer_ addSublayer:compositing_iosurface_layer_]; |
579 DestroySoftwareLayer(); | |
580 | 570 |
581 // Creating the CompositingIOSurfaceLayer may attempt to draw in setLayer, | 571 // Creating the CompositingIOSurfaceLayer may attempt to draw inside |
582 // which, if it fails, will promptly tear down everything that was just | 572 // addSublayer, which, if it fails, will promptly tear down everything that |
583 // created. If that happened, return failure. | 573 // was just created. If that happened, return failure. |
584 return compositing_iosurface_layer_; | 574 return compositing_iosurface_layer_; |
585 } | 575 } |
586 | 576 |
577 void RenderWidgetHostViewMac::DestroyCompositedIOSurfaceLayer() { | |
578 if (!compositing_iosurface_layer_) | |
579 return; | |
580 | |
581 ScopedCAActionDisabler disabler; | |
582 [compositing_iosurface_layer_ removeFromSuperlayer]; | |
583 [compositing_iosurface_layer_ disableCompositing]; | |
584 compositing_iosurface_layer_.reset(); | |
585 } | |
586 | |
587 void RenderWidgetHostViewMac::DestroyCompositedIOSurfaceAndLayer( | 587 void RenderWidgetHostViewMac::DestroyCompositedIOSurfaceAndLayer( |
588 DestroyContextBehavior destroy_context_behavior) { | 588 DestroyContextBehavior destroy_context_behavior) { |
589 // Any pending frames will not be displayed, so ack them now. | 589 // Any pending frames will not be displayed, so ack them now. |
590 SendPendingSwapAck(); | 590 SendPendingSwapAck(); |
591 | 591 |
592 ScopedCAActionDisabler disabler; | 592 DestroyCompositedIOSurfaceLayer(); |
593 compositing_iosurface_.reset(); | |
593 | 594 |
594 compositing_iosurface_.reset(); | |
595 if (compositing_iosurface_layer_) { | |
596 if ([cocoa_view_ layer] == compositing_iosurface_layer_.get()) | |
597 [cocoa_view_ setLayer:background_layer_]; | |
598 [compositing_iosurface_layer_ removeFromSuperlayer]; | |
599 [compositing_iosurface_layer_ disableCompositing]; | |
600 compositing_iosurface_layer_.reset(); | |
601 } | |
602 switch (destroy_context_behavior) { | 595 switch (destroy_context_behavior) { |
603 case kLeaveContextBoundToView: | 596 case kLeaveContextBoundToView: |
604 break; | 597 break; |
605 case kDestroyContext: | 598 case kDestroyContext: |
606 ClearBoundContextDrawable(); | 599 ClearBoundContextDrawable(); |
607 compositing_iosurface_context_ = NULL; | 600 compositing_iosurface_context_ = NULL; |
608 break; | 601 break; |
609 default: | 602 default: |
610 NOTREACHED(); | 603 NOTREACHED(); |
611 break; | 604 break; |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
779 backing_store_scale_factor_ = new_scale_factor; | 772 backing_store_scale_factor_ = new_scale_factor; |
780 | 773 |
781 BackingStoreMac* backing_store = static_cast<BackingStoreMac*>( | 774 BackingStoreMac* backing_store = static_cast<BackingStoreMac*>( |
782 render_widget_host_->GetBackingStore(false)); | 775 render_widget_host_->GetBackingStore(false)); |
783 if (backing_store) | 776 if (backing_store) |
784 backing_store->ScaleFactorChanged(backing_store_scale_factor_); | 777 backing_store->ScaleFactorChanged(backing_store_scale_factor_); |
785 | 778 |
786 ScopedCAActionDisabler disabler; | 779 ScopedCAActionDisabler disabler; |
787 | 780 |
788 if (software_layer_) { | 781 if (software_layer_) { |
789 [software_layer_ disableRendering]; | 782 DestroySoftwareLayer(); |
790 software_layer_.reset(); | 783 CreateSoftwareLayer(); |
791 CreateSoftwareLayerAndDestroyCompositedLayer(); | |
792 } | 784 } |
793 | 785 |
794 // Dynamically calling setContentsScale on a CAOpenGLLayer for which | 786 // Dynamically calling setContentsScale on a CAOpenGLLayer for which |
795 // setAsynchronous is dynamically toggled can result in flashes of corrupt | 787 // setAsynchronous is dynamically toggled can result in flashes of corrupt |
796 // content. Work around this by replacing the entire layer when the scale | 788 // content. Work around this by replacing the entire layer when the scale |
797 // factor changes. | 789 // factor changes. |
798 if (compositing_iosurface_layer_) { | 790 if (compositing_iosurface_layer_) { |
799 [compositing_iosurface_layer_ disableCompositing]; | 791 DestroyCompositedIOSurfaceLayer(); |
800 compositing_iosurface_layer_.reset(); | 792 CreateCompositedIOSurfaceLayer(); |
801 CreateCompositedLayerAndDestroySoftwareLayer(); | |
802 } | 793 } |
803 | 794 |
804 render_widget_host_->NotifyScreenInfoChanged(); | 795 render_widget_host_->NotifyScreenInfoChanged(); |
805 } | 796 } |
806 | 797 |
807 RenderWidgetHost* RenderWidgetHostViewMac::GetRenderWidgetHost() const { | 798 RenderWidgetHost* RenderWidgetHostViewMac::GetRenderWidgetHost() const { |
808 return render_widget_host_; | 799 return render_widget_host_; |
809 } | 800 } |
810 | 801 |
811 void RenderWidgetHostViewMac::WasShown() { | 802 void RenderWidgetHostViewMac::WasShown() { |
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1480 compositing_iosurface_->CopyToVideoFrame( | 1471 compositing_iosurface_->CopyToVideoFrame( |
1481 gfx::Rect(size), frame, | 1472 gfx::Rect(size), frame, |
1482 base::Bind(callback, present_time)); | 1473 base::Bind(callback, present_time)); |
1483 DCHECK_EQ(CGLGetCurrentContext(), | 1474 DCHECK_EQ(CGLGetCurrentContext(), |
1484 compositing_iosurface_context_->cgl_context()); | 1475 compositing_iosurface_context_->cgl_context()); |
1485 } | 1476 } |
1486 } | 1477 } |
1487 | 1478 |
1488 // Create the layer for the composited content only after the IOSurface has | 1479 // Create the layer for the composited content only after the IOSurface has |
1489 // been initialized. | 1480 // been initialized. |
1490 if (!CreateCompositedLayerAndDestroySoftwareLayer()) { | 1481 if (!CreateCompositedIOSurfaceLayer()) { |
Ken Russell (switch to Gerrit)
2014/03/07 00:29:56
Who takes care of deleting the software layer in t
ccameron
2014/03/07 07:30:01
I moved this to where the software frame and backi
| |
1491 LOG(ERROR) << "Failed to create CompositingIOSurface layer"; | 1482 LOG(ERROR) << "Failed to create CompositingIOSurface layer"; |
1492 GotAcceleratedCompositingError(); | 1483 GotAcceleratedCompositingError(); |
1493 return; | 1484 return; |
1494 } | 1485 } |
1495 | 1486 |
1496 GotAcceleratedFrame(); | 1487 GotAcceleratedFrame(); |
1497 | 1488 |
1498 gfx::Size window_size(NSSizeToCGSize([cocoa_view_ frame].size)); | 1489 gfx::Size window_size(NSSizeToCGSize([cocoa_view_ frame].size)); |
1499 if (window_size.IsEmpty()) { | 1490 if (window_size.IsEmpty()) { |
1500 // setNeedsDisplay will never display and we'll never ack if the window is | 1491 // setNeedsDisplay will never display and we'll never ack if the window is |
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1978 SendVSyncParametersToRenderer(); | 1969 SendVSyncParametersToRenderer(); |
1979 if (!last_frame_was_accelerated_) { | 1970 if (!last_frame_was_accelerated_) { |
1980 last_frame_was_accelerated_ = true; | 1971 last_frame_was_accelerated_ = true; |
1981 | 1972 |
1982 if (!use_core_animation_) { | 1973 if (!use_core_animation_) { |
1983 // Need to wipe the software view with transparency to expose the GL | 1974 // Need to wipe the software view with transparency to expose the GL |
1984 // underlay. Invalidate the whole window to do that. | 1975 // underlay. Invalidate the whole window to do that. |
1985 [cocoa_view_ setNeedsDisplay:YES]; | 1976 [cocoa_view_ setNeedsDisplay:YES]; |
1986 } | 1977 } |
1987 | 1978 |
1988 // Delete software backingstore. | 1979 // Delete software backingstore and layer. |
1989 BackingStoreManager::RemoveBackingStore(render_widget_host_); | 1980 BackingStoreManager::RemoveBackingStore(render_widget_host_); |
1990 software_frame_manager_->DiscardCurrentFrame(); | 1981 software_frame_manager_->DiscardCurrentFrame(); |
1982 DestroySoftwareLayer(); | |
ccameron
2014/03/07 07:30:01
[1] from above.
| |
1991 } | 1983 } |
1992 } | 1984 } |
1993 | 1985 |
1994 void RenderWidgetHostViewMac::GotSoftwareFrame() { | 1986 void RenderWidgetHostViewMac::GotSoftwareFrame() { |
1995 CreateSoftwareLayerAndDestroyCompositedLayer(); | 1987 CreateSoftwareLayer(); |
Ken Russell (switch to Gerrit)
2014/03/07 00:29:56
Who takes care of deleting the composited IOSurfac
ccameron
2014/03/07 07:30:01
This is done further down in the if (last_frame_wa
| |
1996 [software_layer_ setNeedsDisplay]; | 1988 [software_layer_ setNeedsDisplay]; |
1997 SendVSyncParametersToRenderer(); | 1989 SendVSyncParametersToRenderer(); |
1998 | 1990 |
1999 if (last_frame_was_accelerated_) { | 1991 if (last_frame_was_accelerated_) { |
2000 last_frame_was_accelerated_ = false; | 1992 last_frame_was_accelerated_ = false; |
2001 | 1993 |
2002 // If overlapping views are allowed, then don't unbind the context | 1994 // If overlapping views are allowed, then don't unbind the context |
2003 // from the view (that is, don't call clearDrawble -- just delete the | 1995 // from the view (that is, don't call clearDrawble -- just delete the |
2004 // texture and IOSurface). Rather, let it sit behind the software frame | 1996 // texture and IOSurface). Rather, let it sit behind the software frame |
2005 // that will be put up in front. This will prevent transparent | 1997 // that will be put up in front. This will prevent transparent |
(...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2938 renderWidgetHostView_->render_widget_host_->SendScreenRects(); | 2930 renderWidgetHostView_->render_widget_host_->SendScreenRects(); |
2939 renderWidgetHostView_->render_widget_host_->WasResized(); | 2931 renderWidgetHostView_->render_widget_host_->WasResized(); |
2940 } | 2932 } |
2941 | 2933 |
2942 // This call is necessary to make the window wait for a new frame at the new | 2934 // This call is necessary to make the window wait for a new frame at the new |
2943 // size to be available before the resize completes. Calling only | 2935 // size to be available before the resize completes. Calling only |
2944 // setLayerContentsRedrawPolicy:NSViewLayerContentsRedrawOnSetNeedsDisplay on | 2936 // setLayerContentsRedrawPolicy:NSViewLayerContentsRedrawOnSetNeedsDisplay on |
2945 // this is not sufficient. | 2937 // this is not sufficient. |
2946 ScopedCAActionDisabler disabler; | 2938 ScopedCAActionDisabler disabler; |
2947 CGRect frame = NSRectToCGRect([renderWidgetHostView_->cocoa_view() bounds]); | 2939 CGRect frame = NSRectToCGRect([renderWidgetHostView_->cocoa_view() bounds]); |
2948 [[self layer] setFrame:frame]; | 2940 [renderWidgetHostView_->software_layer_ setFrame:frame]; |
2949 [[self layer] setNeedsDisplay]; | 2941 [renderWidgetHostView_->software_layer_ setNeedsDisplay]; |
2942 [renderWidgetHostView_->compositing_iosurface_layer_ setFrame:frame]; | |
2943 [renderWidgetHostView_->compositing_iosurface_layer_ setNeedsDisplay]; | |
2950 } | 2944 } |
2951 | 2945 |
2952 - (void)callSetNeedsDisplayInRect { | 2946 - (void)callSetNeedsDisplayInRect { |
2953 DCHECK([NSThread isMainThread]); | 2947 DCHECK([NSThread isMainThread]); |
2954 DCHECK(renderWidgetHostView_->call_set_needs_display_in_rect_pending_); | 2948 DCHECK(renderWidgetHostView_->call_set_needs_display_in_rect_pending_); |
2955 [self setNeedsDisplayInRect:renderWidgetHostView_->invalid_rect_]; | 2949 [self setNeedsDisplayInRect:renderWidgetHostView_->invalid_rect_]; |
2956 renderWidgetHostView_->call_set_needs_display_in_rect_pending_ = false; | 2950 renderWidgetHostView_->call_set_needs_display_in_rect_pending_ = false; |
2957 renderWidgetHostView_->invalid_rect_ = NSZeroRect; | 2951 renderWidgetHostView_->invalid_rect_ = NSZeroRect; |
2958 | 2952 |
2959 [[self layer] setNeedsDisplay]; | 2953 [renderWidgetHostView_->software_layer_ setNeedsDisplay]; |
2954 [renderWidgetHostView_->compositing_iosurface_layer_ setNeedsDisplay]; | |
2960 } | 2955 } |
2961 | 2956 |
2962 // Fills with white the parts of the area to the right and bottom for |rect| | 2957 // Fills with white the parts of the area to the right and bottom for |rect| |
2963 // that intersect |damagedRect|. | 2958 // that intersect |damagedRect|. |
2964 - (void)fillBottomRightRemainderOfRect:(gfx::Rect)rect | 2959 - (void)fillBottomRightRemainderOfRect:(gfx::Rect)rect |
2965 dirtyRect:(gfx::Rect)damagedRect | 2960 dirtyRect:(gfx::Rect)damagedRect |
2966 inContext:(CGContextRef)context { | 2961 inContext:(CGContextRef)context { |
2967 if (damagedRect.right() > rect.right()) { | 2962 if (damagedRect.right() > rect.right()) { |
2968 int x = std::max(rect.right(), damagedRect.x()); | 2963 int x = std::max(rect.right(), damagedRect.x()); |
2969 int y = std::min(rect.bottom(), damagedRect.bottom()); | 2964 int y = std::min(rect.bottom(), damagedRect.bottom()); |
(...skipping 972 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3942 WebMouseEvent event; | 3937 WebMouseEvent event; |
3943 event.type = WebInputEvent::MouseUp; | 3938 event.type = WebInputEvent::MouseUp; |
3944 event.button = WebMouseEvent::ButtonLeft; | 3939 event.button = WebMouseEvent::ButtonLeft; |
3945 renderWidgetHostView_->ForwardMouseEvent(event); | 3940 renderWidgetHostView_->ForwardMouseEvent(event); |
3946 | 3941 |
3947 hasOpenMouseDown_ = NO; | 3942 hasOpenMouseDown_ = NO; |
3948 } | 3943 } |
3949 | 3944 |
3950 // Resize the view's layers to match the new window size. | 3945 // Resize the view's layers to match the new window size. |
3951 ScopedCAActionDisabler disabler; | 3946 ScopedCAActionDisabler disabler; |
3952 [[self layer] setFrame:NSRectToCGRect([self bounds])]; | 3947 [renderWidgetHostView_->software_layer_ |
3948 setFrame:NSRectToCGRect([self bounds])]; | |
3949 [renderWidgetHostView_->compositing_iosurface_layer_ | |
3950 setFrame:NSRectToCGRect([self bounds])]; | |
3953 } | 3951 } |
3954 | 3952 |
3955 - (void)undo:(id)sender { | 3953 - (void)undo:(id)sender { |
3956 if (renderWidgetHostView_->render_widget_host_->IsRenderView()) { | 3954 if (renderWidgetHostView_->render_widget_host_->IsRenderView()) { |
3957 static_cast<RenderViewHostImpl*>( | 3955 static_cast<RenderViewHostImpl*>( |
3958 renderWidgetHostView_->render_widget_host_)->Undo(); | 3956 renderWidgetHostView_->render_widget_host_)->Undo(); |
3959 } | 3957 } |
3960 } | 3958 } |
3961 | 3959 |
3962 - (void)redo:(id)sender { | 3960 - (void)redo:(id)sender { |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4246 CGColorGetConstantColor(kCGColorWhite)); | 4244 CGColorGetConstantColor(kCGColorWhite)); |
4247 CGContextFillRect(context, clipRect); | 4245 CGContextFillRect(context, clipRect); |
4248 } | 4246 } |
4249 } | 4247 } |
4250 | 4248 |
4251 - (void)disableRendering { | 4249 - (void)disableRendering { |
4252 renderWidgetHostView_ = NULL; | 4250 renderWidgetHostView_ = NULL; |
4253 } | 4251 } |
4254 | 4252 |
4255 @end // implementation SoftwareLayer | 4253 @end // implementation SoftwareLayer |
OLD | NEW |