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)); |
816 AcceleratedPluginView* view = ViewForPluginWindowHandle(window); | 823 AcceleratedPluginView* view = ViewForPluginWindowHandle(window); |
817 DCHECK(view); | 824 TRACE_EVENT1("browser", |
818 if (!view) | 825 "RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped", |
826 "view", view); | |
827 if (!view) { | |
828 // This happens, and we can't let the GPU go without an ack. | |
829 // TODO: Why does this happen? Does it matter? | |
jbates
2011/06/07 16:47:52
Looks like this may be a recent ToT bug. It does n
| |
830 AcknowledgeSwapBuffers(renderer_id, | |
831 route_id, | |
832 gpu_host_id, | |
833 swap_buffers_count); | |
819 return; | 834 return; |
835 } | |
820 | 836 |
821 plugin_container_manager_.SetSurfaceWasPaintedTo(window, surface_id); | 837 plugin_container_manager_.SetSurfaceWasPaintedTo(window, surface_id); |
822 | 838 |
823 // The surface is hidden until its first paint, to not show gargabe. | 839 // The surface is hidden until its first paint, to not show gargabe. |
824 if (plugin_container_manager_.SurfaceShouldBeVisible(window)) | 840 if (plugin_container_manager_.SurfaceShouldBeVisible(window)) |
825 [view setHidden:NO]; | 841 [view setHidden:NO]; |
826 [view updateSwapBuffersCount:swap_buffers_count | 842 [view updateSwapBuffersCount:swap_buffers_count |
827 fromRenderer:renderer_id | 843 fromRenderer:renderer_id |
828 routeId:route_id | 844 routeId:route_id |
829 gpuHostId:gpu_host_id]; | 845 gpuHostId:gpu_host_id]; |
(...skipping 26 matching lines...) Expand all Loading... | |
856 UpdateRootGpuViewVisibility(false); | 872 UpdateRootGpuViewVisibility(false); |
857 needs_gpu_visibility_update_after_repaint_ = false; | 873 needs_gpu_visibility_update_after_repaint_ = false; |
858 } | 874 } |
859 } | 875 } |
860 | 876 |
861 void RenderWidgetHostViewMac::AcknowledgeSwapBuffers( | 877 void RenderWidgetHostViewMac::AcknowledgeSwapBuffers( |
862 int renderer_id, | 878 int renderer_id, |
863 int32 route_id, | 879 int32 route_id, |
864 int gpu_host_id, | 880 int gpu_host_id, |
865 uint64 swap_buffers_count) { | 881 uint64 swap_buffers_count) { |
866 TRACE_EVENT1("gpu", "RenderWidgetHostViewMac::AcknowledgeSwapBuffers", | 882 TRACE_EVENT1("browser", "RenderWidgetHostViewMac::AcknowledgeSwapBuffers", |
867 "swap_buffers_count", swap_buffers_count); | 883 "swap_buffers_count", swap_buffers_count); |
868 // Called on the display link thread. Hand actual work off to the IO thread, | 884 // Called on the display link thread. Hand actual work off to the IO thread, |
869 // because |GpuProcessHost::Get()| can only be called there. | 885 // because |GpuProcessHost::Get()| can only be called there. |
870 // Currently, this is never called for plugins. | 886 // Currently, this is never called for plugins. |
871 if (render_widget_host_) { | 887 if (render_widget_host_) { |
872 DCHECK_EQ(render_widget_host_->process()->id(), renderer_id); | 888 DCHECK_EQ(render_widget_host_->process()->id(), renderer_id); |
873 // |render_widget_host_->routing_id()| and |route_id| are usually not | 889 // |render_widget_host_->routing_id()| and |route_id| are usually not |
874 // equal: The former identifies the channel from the RWH in the browser | 890 // equal: The former identifies the channel from the RWH in the browser |
875 // process to the corresponding render widget in the renderer process, while | 891 // process to the corresponding render widget in the renderer process, while |
876 // the latter identifies the channel from the GpuCommandBufferStub in the | 892 // the latter identifies the channel from the GpuCommandBufferStub in the |
(...skipping 1692 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2569 if (!string) return NO; | 2585 if (!string) return NO; |
2570 | 2586 |
2571 // If the user is currently using an IME, confirm the IME input, | 2587 // 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. | 2588 // and then insert the text from the service, the same as TextEdit and Safari. |
2573 [self confirmComposition]; | 2589 [self confirmComposition]; |
2574 [self insertText:string]; | 2590 [self insertText:string]; |
2575 return YES; | 2591 return YES; |
2576 } | 2592 } |
2577 | 2593 |
2578 @end | 2594 @end |
OLD | NEW |