OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
567 HandleDelayedGpuViewHiding(); | 567 HandleDelayedGpuViewHiding(); |
568 } | 568 } |
569 | 569 |
570 void RenderWidgetHostViewMac::RenderViewGone(base::TerminationStatus status, | 570 void RenderWidgetHostViewMac::RenderViewGone(base::TerminationStatus status, |
571 int error_code) { | 571 int error_code) { |
572 // TODO(darin): keep this around, and draw sad-tab into it. | 572 // TODO(darin): keep this around, and draw sad-tab into it. |
573 Destroy(); | 573 Destroy(); |
574 } | 574 } |
575 | 575 |
576 void RenderWidgetHostViewMac::Destroy() { | 576 void RenderWidgetHostViewMac::Destroy() { |
| 577 TRACE_EVENT0("browser", "RenderWidgetHostViewMac::Destroy"); |
577 // On Windows, popups are implemented with a popup window style, so that when | 578 // On Windows, popups are implemented with a popup window style, so that when |
578 // an event comes in that would "cancel" it, it receives the OnCancelMode | 579 // an event comes in that would "cancel" it, it receives the OnCancelMode |
579 // message and can kill itself. Alas, on the Mac, views cannot capture events | 580 // message and can kill itself. Alas, on the Mac, views cannot capture events |
580 // outside of themselves. On Windows, if Destroy is being called on a view, | 581 // outside of themselves. On Windows, if Destroy is being called on a view, |
581 // then the event causing the destroy had also cancelled any popups by the | 582 // then the event causing the destroy had also cancelled any popups by the |
582 // time Destroy() was called. On the Mac we have to destroy all the popups | 583 // time Destroy() was called. On the Mac we have to destroy all the popups |
583 // ourselves. | 584 // ourselves. |
584 | 585 |
585 // Depth-first destroy all popups. Use ShutdownHost() to enforce | 586 // Depth-first destroy all popups. Use ShutdownHost() to enforce |
586 // deepest-first ordering. | 587 // deepest-first ordering. |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
696 | 697 |
697 // |render_widget_host_| is set to NULL when |RWHVMac::Destroy()| has | 698 // |render_widget_host_| is set to NULL when |RWHVMac::Destroy()| has |
698 // completed. If |AllocateFakePluginWindowHandle()| is called after that, | 699 // completed. If |AllocateFakePluginWindowHandle()| is called after that, |
699 // we will crash when the AcceleratedPluginView we allocate below is | 700 // we will crash when the AcceleratedPluginView we allocate below is |
700 // destroyed. | 701 // destroyed. |
701 DCHECK(render_widget_host_); | 702 DCHECK(render_widget_host_); |
702 | 703 |
703 // Create an NSView to host the plugin's/compositor's pixels. | 704 // Create an NSView to host the plugin's/compositor's pixels. |
704 gfx::PluginWindowHandle handle = | 705 gfx::PluginWindowHandle handle = |
705 plugin_container_manager_.AllocateFakePluginWindowHandle(opaque, root); | 706 plugin_container_manager_.AllocateFakePluginWindowHandle(opaque, root); |
| 707 TRACE_EVENT1("browser", |
| 708 "RenderWidgetHostViewMac::AllocateFakePluginWindowHandle", |
| 709 "window", handle); |
706 | 710 |
707 scoped_nsobject<AcceleratedPluginView> plugin_view( | 711 scoped_nsobject<AcceleratedPluginView> plugin_view( |
708 [[AcceleratedPluginView alloc] initWithRenderWidgetHostViewMac:this | 712 [[AcceleratedPluginView alloc] initWithRenderWidgetHostViewMac:this |
709 pluginHandle:handle]); | 713 pluginHandle:handle]); |
710 [plugin_view setHidden:YES]; | 714 [plugin_view setHidden:YES]; |
711 | 715 |
712 [cocoa_view_ addSubview:plugin_view]; | 716 [cocoa_view_ addSubview:plugin_view]; |
713 plugin_views_[handle] = plugin_view; | 717 plugin_views_[handle] = plugin_view; |
714 | 718 |
715 return handle; | 719 return handle; |
716 } | 720 } |
717 | 721 |
718 void RenderWidgetHostViewMac::DestroyFakePluginWindowHandle( | 722 void RenderWidgetHostViewMac::DestroyFakePluginWindowHandle( |
719 gfx::PluginWindowHandle window) { | 723 gfx::PluginWindowHandle window) { |
720 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 724 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 725 TRACE_EVENT1("browser", |
| 726 "RenderWidgetHostViewMac::DestroyFakePluginWindowHandle", |
| 727 "window", window); |
721 PluginViewMap::iterator it = plugin_views_.find(window); | 728 PluginViewMap::iterator it = plugin_views_.find(window); |
722 DCHECK(plugin_views_.end() != it); | 729 DCHECK(plugin_views_.end() != it); |
723 if (plugin_views_.end() == it) { | 730 if (plugin_views_.end() == it) { |
724 return; | 731 return; |
725 } | 732 } |
726 [it->second removeFromSuperview]; | 733 [it->second removeFromSuperview]; |
727 plugin_views_.erase(it); | 734 plugin_views_.erase(it); |
728 | 735 |
729 // The view's dealloc will call DeallocFakePluginWindowHandle(), which will | 736 // The view's dealloc will call DeallocFakePluginWindowHandle(), which will |
730 // remove the handle from |plugin_container_manager_|. This code path is | 737 // remove the handle from |plugin_container_manager_|. This code path is |
731 // taken if a plugin is removed, but the RWHVMac itself stays alive. | 738 // taken if a plugin is removed, but the RWHVMac itself stays alive. |
732 } | 739 } |
733 | 740 |
734 // This is called by AcceleratedPluginView's -dealloc. | 741 // This is called by AcceleratedPluginView's -dealloc. |
735 void RenderWidgetHostViewMac::DeallocFakePluginWindowHandle( | 742 void RenderWidgetHostViewMac::DeallocFakePluginWindowHandle( |
736 gfx::PluginWindowHandle window) { | 743 gfx::PluginWindowHandle window) { |
| 744 TRACE_EVENT1("browser", |
| 745 "RenderWidgetHostViewMac::DeallocFakePluginWindowHandle", |
| 746 "window", window); |
737 // When a browser window with a GpuScheduler is closed, the render process | 747 // When a browser window with a GpuScheduler is closed, the render process |
738 // will attempt to finish all GL commands. It will busy-wait on the GPU | 748 // will attempt to finish all GL commands. It will busy-wait on the GPU |
739 // process until the command queue is empty. If a paint is pending, the GPU | 749 // process until the command queue is empty. If a paint is pending, the GPU |
740 // process won't process any GL commands until the browser sends a paint ack, | 750 // process won't process any GL commands until the browser sends a paint ack, |
741 // but since the browser window is already closed, it will never arrive. | 751 // but since the browser window is already closed, it will never arrive. |
742 // To resolve this we ask the GPU process to destroy the command buffer | 752 // To resolve this we ask the GPU process to destroy the command buffer |
743 // associated with the given render widget. Once the command buffer is | 753 // associated with the given render widget. Once the command buffer is |
744 // destroyed, all GL commands from the renderer will immediately receive | 754 // destroyed, all GL commands from the renderer will immediately receive |
745 // channel error. | 755 // channel error. |
746 if (render_widget_host_ && | 756 if (render_widget_host_ && |
747 plugin_container_manager_.IsRootContainer(window)) { | 757 plugin_container_manager_.IsRootContainer(window)) { |
748 GpuProcessHost::SendOnIO( | 758 GpuProcessHost::SendOnIO( |
749 render_widget_host_->process()->id(), | 759 render_widget_host_->process()->id(), |
750 content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH, | 760 content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH, |
751 new GpuMsg_DestroyCommandBuffer( | 761 new GpuMsg_DestroyCommandBuffer( |
752 render_widget_host_->process()->id(), | 762 render_widget_host_->process()->id(), |
753 render_widget_host_->routing_id())); | 763 render_widget_host_->routing_id())); |
754 } | 764 } |
755 | 765 |
756 plugin_container_manager_.DestroyFakePluginWindowHandle(window); | 766 plugin_container_manager_.DestroyFakePluginWindowHandle(window); |
757 } | 767 } |
758 | 768 |
759 AcceleratedPluginView* RenderWidgetHostViewMac::ViewForPluginWindowHandle( | 769 AcceleratedPluginView* RenderWidgetHostViewMac::ViewForPluginWindowHandle( |
760 gfx::PluginWindowHandle window) { | 770 gfx::PluginWindowHandle window) { |
761 PluginViewMap::iterator it = plugin_views_.find(window); | 771 PluginViewMap::iterator it = plugin_views_.find(window); |
762 DCHECK(plugin_views_.end() != it); | |
763 if (plugin_views_.end() == it) | 772 if (plugin_views_.end() == it) |
764 return nil; | 773 return nil; |
765 return it->second; | 774 return it->second; |
766 } | 775 } |
767 | 776 |
768 void RenderWidgetHostViewMac::AcceleratedSurfaceSetIOSurface( | 777 void RenderWidgetHostViewMac::AcceleratedSurfaceSetIOSurface( |
769 gfx::PluginWindowHandle window, | 778 gfx::PluginWindowHandle window, |
770 int32 width, | 779 int32 width, |
771 int32 height, | 780 int32 height, |
772 uint64 io_surface_identifier) { | 781 uint64 io_surface_identifier) { |
(...skipping 30 matching lines...) Expand all Loading... |
803 transport_dib); | 812 transport_dib); |
804 } | 813 } |
805 | 814 |
806 void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped( | 815 void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped( |
807 gfx::PluginWindowHandle window, | 816 gfx::PluginWindowHandle window, |
808 uint64 surface_id, | 817 uint64 surface_id, |
809 int renderer_id, | 818 int renderer_id, |
810 int32 route_id, | 819 int32 route_id, |
811 int gpu_host_id, | 820 int gpu_host_id, |
812 uint64 swap_buffers_count) { | 821 uint64 swap_buffers_count) { |
813 TRACE_EVENT0("browser", | |
814 "RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped"); | |
815 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 822 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 823 TRACE_EVENT2("browser", |
| 824 "RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped", |
| 825 "window", window, |
| 826 "frame", swap_buffers_count); |
| 827 |
816 AcceleratedPluginView* view = ViewForPluginWindowHandle(window); | 828 AcceleratedPluginView* view = ViewForPluginWindowHandle(window); |
817 DCHECK(view); | 829 if (!view) { |
818 if (!view) | 830 // TODO: Fix the root cause of invalid PluginWindowHandles. |
819 return; | 831 LOG(ERROR) << "ViewForPluginWindowHandle returned NULL. " |
| 832 << "Did the renderer specify an invalid PluginWindowHandle?"; |
| 833 } else { |
| 834 plugin_container_manager_.SetSurfaceWasPaintedTo(window, surface_id); |
820 | 835 |
821 plugin_container_manager_.SetSurfaceWasPaintedTo(window, surface_id); | 836 // The surface is hidden until its first paint, to not show gargabe. |
| 837 if (plugin_container_manager_.SurfaceShouldBeVisible(window)) |
| 838 [view setHidden:NO]; |
822 | 839 |
823 // The surface is hidden until its first paint, to not show gargabe. | 840 // Present the frame. |
824 if (plugin_container_manager_.SurfaceShouldBeVisible(window)) | 841 [view drawView]; |
825 [view setHidden:NO]; | 842 } |
826 [view updateSwapBuffersCount:swap_buffers_count | 843 |
827 fromRenderer:renderer_id | 844 // Always acknowledge swap buffers to avoid renderer->GPU deadlocks. |
828 routeId:route_id | 845 if (renderer_id != 0 || route_id != 0) |
829 gpuHostId:gpu_host_id]; | 846 AcknowledgeSwapBuffers(renderer_id, |
| 847 route_id, |
| 848 gpu_host_id, |
| 849 swap_buffers_count); |
830 } | 850 } |
831 | 851 |
832 void RenderWidgetHostViewMac::UpdateRootGpuViewVisibility( | 852 void RenderWidgetHostViewMac::UpdateRootGpuViewVisibility( |
833 bool show_gpu_widget) { | 853 bool show_gpu_widget) { |
834 // Plugins are destroyed on page navigate. The compositor layer on the other | 854 // Plugins are destroyed on page navigate. The compositor layer on the other |
835 // hand is created on demand and then stays alive until its renderer process | 855 // hand is created on demand and then stays alive until its renderer process |
836 // dies (usually on cross-domain navigation). Instead, only a flag | 856 // dies (usually on cross-domain navigation). Instead, only a flag |
837 // |is_accelerated_compositing_active()| is flipped when the compositor output | 857 // |is_accelerated_compositing_active()| is flipped when the compositor output |
838 // should be shown/hidden. | 858 // should be shown/hidden. |
839 // Show/hide the view belonging to the compositor here. | 859 // Show/hide the view belonging to the compositor here. |
(...skipping 16 matching lines...) Expand all Loading... |
856 UpdateRootGpuViewVisibility(false); | 876 UpdateRootGpuViewVisibility(false); |
857 needs_gpu_visibility_update_after_repaint_ = false; | 877 needs_gpu_visibility_update_after_repaint_ = false; |
858 } | 878 } |
859 } | 879 } |
860 | 880 |
861 void RenderWidgetHostViewMac::AcknowledgeSwapBuffers( | 881 void RenderWidgetHostViewMac::AcknowledgeSwapBuffers( |
862 int renderer_id, | 882 int renderer_id, |
863 int32 route_id, | 883 int32 route_id, |
864 int gpu_host_id, | 884 int gpu_host_id, |
865 uint64 swap_buffers_count) { | 885 uint64 swap_buffers_count) { |
866 TRACE_EVENT1("gpu", "RenderWidgetHostViewMac::AcknowledgeSwapBuffers", | 886 TRACE_EVENT1("browser", "RenderWidgetHostViewMac::AcknowledgeSwapBuffers", |
867 "swap_buffers_count", swap_buffers_count); | 887 "frame", swap_buffers_count); |
868 // Called on the display link thread. Hand actual work off to the IO thread, | 888 // Called on the display link thread. Hand actual work off to the IO thread, |
869 // because |GpuProcessHost::Get()| can only be called there. | 889 // because |GpuProcessHost::Get()| can only be called there. |
870 // Currently, this is never called for plugins. | 890 // Currently, this is never called for plugins. |
871 if (render_widget_host_) { | 891 if (render_widget_host_) { |
872 DCHECK_EQ(render_widget_host_->process()->id(), renderer_id); | 892 DCHECK_EQ(render_widget_host_->process()->id(), renderer_id); |
873 // |render_widget_host_->routing_id()| and |route_id| are usually not | 893 // |render_widget_host_->routing_id()| and |route_id| are usually not |
874 // equal: The former identifies the channel from the RWH in the browser | 894 // equal: The former identifies the channel from the RWH in the browser |
875 // process to the corresponding render widget in the renderer process, while | 895 // process to the corresponding render widget in the renderer process, while |
876 // the latter identifies the channel from the GpuCommandBufferStub in the | 896 // the latter identifies the channel from the GpuCommandBufferStub in the |
877 // GPU process to the corresponding command buffer client in the renderer. | 897 // GPU process to the corresponding command buffer client in the renderer. |
(...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1538 gfx::Rect gpuRect; | 1558 gfx::Rect gpuRect; |
1539 | 1559 |
1540 gfx::PluginWindowHandle root_handle = | 1560 gfx::PluginWindowHandle root_handle = |
1541 renderWidgetHostView_->plugin_container_manager_.root_container_handle(); | 1561 renderWidgetHostView_->plugin_container_manager_.root_container_handle(); |
1542 if (root_handle != gfx::kNullPluginWindow) { | 1562 if (root_handle != gfx::kNullPluginWindow) { |
1543 AcceleratedPluginView* view = | 1563 AcceleratedPluginView* view = |
1544 renderWidgetHostView_->ViewForPluginWindowHandle(root_handle); | 1564 renderWidgetHostView_->ViewForPluginWindowHandle(root_handle); |
1545 DCHECK(view); | 1565 DCHECK(view); |
1546 if (view && ![view isHidden]) { | 1566 if (view && ![view isHidden]) { |
1547 NSRect frame = [view frame]; | 1567 NSRect frame = [view frame]; |
1548 frame.size = [view cachedSize]; | |
1549 gpuRect = [self flipNSRectToRect:frame]; | 1568 gpuRect = [self flipNSRectToRect:frame]; |
1550 } | 1569 } |
1551 } | 1570 } |
1552 | 1571 |
1553 [self fillBottomRightRemainderOfRect:gpuRect dirtyRect:damagedRect]; | 1572 [self fillBottomRightRemainderOfRect:gpuRect dirtyRect:damagedRect]; |
1554 return; | 1573 return; |
1555 } | 1574 } |
1556 | 1575 |
1557 DCHECK(!renderWidgetHostView_->about_to_validate_and_paint_); | 1576 DCHECK(!renderWidgetHostView_->about_to_validate_and_paint_); |
1558 | 1577 |
(...skipping 1010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2569 if (!string) return NO; | 2588 if (!string) return NO; |
2570 | 2589 |
2571 // If the user is currently using an IME, confirm the IME input, | 2590 // If the user is currently using an IME, confirm the IME input, |
2572 // and then insert the text from the service, the same as TextEdit and Safari. | 2591 // and then insert the text from the service, the same as TextEdit and Safari. |
2573 [self confirmComposition]; | 2592 [self confirmComposition]; |
2574 [self insertText:string]; | 2593 [self insertText:string]; |
2575 return YES; | 2594 return YES; |
2576 } | 2595 } |
2577 | 2596 |
2578 @end | 2597 @end |
OLD | NEW |