Chromium Code Reviews| 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 |