Chromium Code Reviews| 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/renderer/render_widget.h" | 5 #include "content/renderer/render_widget.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
| 10 #include "base/debug/trace_event_synthetic_delay.h" | 10 #include "base/debug/trace_event_synthetic_delay.h" |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 29 #include "content/common/input_messages.h" | 29 #include "content/common/input_messages.h" |
| 30 #include "content/common/swapped_out_messages.h" | 30 #include "content/common/swapped_out_messages.h" |
| 31 #include "content/common/view_messages.h" | 31 #include "content/common/view_messages.h" |
| 32 #include "content/public/common/content_switches.h" | 32 #include "content/public/common/content_switches.h" |
| 33 #include "content/public/common/context_menu_params.h" | 33 #include "content/public/common/context_menu_params.h" |
| 34 #include "content/renderer/cursor_utils.h" | 34 #include "content/renderer/cursor_utils.h" |
| 35 #include "content/renderer/external_popup_menu.h" | 35 #include "content/renderer/external_popup_menu.h" |
| 36 #include "content/renderer/gpu/compositor_output_surface.h" | 36 #include "content/renderer/gpu/compositor_output_surface.h" |
| 37 #include "content/renderer/gpu/compositor_software_output_device.h" | 37 #include "content/renderer/gpu/compositor_software_output_device.h" |
| 38 #include "content/renderer/gpu/delegated_compositor_output_surface.h" | 38 #include "content/renderer/gpu/delegated_compositor_output_surface.h" |
| 39 #include "content/renderer/gpu/frame_swap_message_queue.h" | |
| 39 #include "content/renderer/gpu/mailbox_output_surface.h" | 40 #include "content/renderer/gpu/mailbox_output_surface.h" |
| 40 #include "content/renderer/gpu/render_widget_compositor.h" | 41 #include "content/renderer/gpu/render_widget_compositor.h" |
| 41 #include "content/renderer/ime_event_guard.h" | 42 #include "content/renderer/ime_event_guard.h" |
| 42 #include "content/renderer/input/input_handler_manager.h" | 43 #include "content/renderer/input/input_handler_manager.h" |
| 43 #include "content/renderer/pepper/pepper_plugin_instance_impl.h" | 44 #include "content/renderer/pepper/pepper_plugin_instance_impl.h" |
| 44 #include "content/renderer/render_frame_impl.h" | 45 #include "content/renderer/render_frame_impl.h" |
| 45 #include "content/renderer/render_process.h" | 46 #include "content/renderer/render_process.h" |
| 46 #include "content/renderer/render_thread_impl.h" | 47 #include "content/renderer/render_thread_impl.h" |
| 47 #include "content/renderer/renderer_webkitplatformsupport_impl.h" | 48 #include "content/renderer/renderer_webkitplatformsupport_impl.h" |
| 48 #include "content/renderer/resizing_mode_selector.h" | 49 #include "content/renderer/resizing_mode_selector.h" |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 146 return ui::TEXT_INPUT_MODE_DEFAULT; | 147 return ui::TEXT_INPUT_MODE_DEFAULT; |
| 147 return it->second; | 148 return it->second; |
| 148 } | 149 } |
| 149 | 150 |
| 150 // TODO(brianderson): Replace the hard-coded threshold with a fraction of | 151 // TODO(brianderson): Replace the hard-coded threshold with a fraction of |
| 151 // the BeginMainFrame interval. | 152 // the BeginMainFrame interval. |
| 152 // 4166us will allow 1/4 of a 60Hz interval or 1/2 of a 120Hz interval to | 153 // 4166us will allow 1/4 of a 60Hz interval or 1/2 of a 120Hz interval to |
| 153 // be spent in input hanlders before input starts getting throttled. | 154 // be spent in input hanlders before input starts getting throttled. |
| 154 const int kInputHandlingTimeThrottlingThresholdMicroseconds = 4166; | 155 const int kInputHandlingTimeThrottlingThresholdMicroseconds = 4166; |
| 155 | 156 |
| 157 class QueueMessageSwapPromise : public cc::SwapPromise { | |
| 158 public: | |
| 159 QueueMessageSwapPromise( | |
| 160 scoped_refptr<IPC::SyncMessageFilter> message_sender, | |
| 161 scoped_refptr<content::FrameSwapMessageQueue> message_queue, | |
| 162 IPC::Message* msg) | |
| 163 : message_sender_(message_sender), | |
| 164 message_queue_(message_queue), | |
| 165 msg_(msg) { | |
| 166 DCHECK(message_sender_.get()); | |
| 167 DCHECK(message_queue_.get()); | |
| 168 DCHECK(msg); | |
| 169 } | |
| 170 | |
| 171 virtual ~QueueMessageSwapPromise() { | |
| 172 // Should only happen when the compositor is being deleted. | |
| 173 delete msg_; | |
|
piman
2014/05/22 23:32:01
Maybe we should have LayerTreeHost / LayerTreeImpl
mkosiba (inactive)
2014/05/23 15:50:38
Done.
| |
| 174 } | |
| 175 | |
| 176 virtual void DidSwap(int source_frame_number, | |
| 177 cc::CompositorFrameMetadata* metadata) OVERRIDE { | |
| 178 if (!message_queue_->TryQueueMessage(source_frame_number, msg_)) { | |
|
piman
2014/05/22 23:32:01
So, I don't think this can ever fail.
SwapPromise
mkosiba (inactive)
2014/05/23 15:50:38
yes, you're right. This simplifies things a bit.
| |
| 179 message_sender_->Send(msg_); | |
| 180 } | |
| 181 msg_ = NULL; | |
| 182 } | |
| 183 | |
| 184 virtual void DidNotSwap(DidNotSwapReason reason) OVERRIDE { | |
| 185 message_sender_->Send(msg_); | |
| 186 msg_ = NULL; | |
| 187 } | |
| 188 | |
| 189 private: | |
| 190 scoped_refptr<IPC::SyncMessageFilter> message_sender_; | |
| 191 scoped_refptr<content::FrameSwapMessageQueue> message_queue_; | |
| 192 IPC::Message* msg_; | |
| 193 }; | |
| 194 | |
| 156 } // namespace | 195 } // namespace |
| 157 | 196 |
| 158 namespace content { | 197 namespace content { |
| 159 | 198 |
| 160 // RenderWidget::ScreenMetricsEmulator ---------------------------------------- | 199 // RenderWidget::ScreenMetricsEmulator ---------------------------------------- |
| 161 | 200 |
| 162 class RenderWidget::ScreenMetricsEmulator { | 201 class RenderWidget::ScreenMetricsEmulator { |
| 163 public: | 202 public: |
| 164 ScreenMetricsEmulator( | 203 ScreenMetricsEmulator( |
| 165 RenderWidget* widget, | 204 RenderWidget* widget, |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 390 #if defined(OS_ANDROID) | 429 #if defined(OS_ANDROID) |
| 391 text_field_is_dirty_(false), | 430 text_field_is_dirty_(false), |
| 392 outstanding_ime_acks_(0), | 431 outstanding_ime_acks_(0), |
| 393 body_background_color_(SK_ColorWHITE), | 432 body_background_color_(SK_ColorWHITE), |
| 394 #endif | 433 #endif |
| 395 #if defined(OS_MACOSX) | 434 #if defined(OS_MACOSX) |
| 396 cached_has_main_frame_horizontal_scrollbar_(false), | 435 cached_has_main_frame_horizontal_scrollbar_(false), |
| 397 cached_has_main_frame_vertical_scrollbar_(false), | 436 cached_has_main_frame_vertical_scrollbar_(false), |
| 398 #endif | 437 #endif |
| 399 popup_origin_scale_for_emulation_(0.f), | 438 popup_origin_scale_for_emulation_(0.f), |
| 439 frame_swap_message_queue_(new FrameSwapMessageQueue()), | |
| 400 resizing_mode_selector_(new ResizingModeSelector()), | 440 resizing_mode_selector_(new ResizingModeSelector()), |
| 401 context_menu_source_type_(ui::MENU_SOURCE_MOUSE) { | 441 context_menu_source_type_(ui::MENU_SOURCE_MOUSE) { |
| 402 if (!swapped_out) | 442 if (!swapped_out) |
| 403 RenderProcess::current()->AddRefProcess(); | 443 RenderProcess::current()->AddRefProcess(); |
| 404 DCHECK(RenderThread::Get()); | 444 DCHECK(RenderThread::Get()); |
| 405 is_threaded_compositing_enabled_ = | 445 is_threaded_compositing_enabled_ = |
| 406 CommandLine::ForCurrentProcess()->HasSwitch( | 446 CommandLine::ForCurrentProcess()->HasSwitch( |
| 407 switches::kEnableThreadedCompositing); | 447 switches::kEnableThreadedCompositing); |
| 408 } | 448 } |
| 409 | 449 |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 807 } | 847 } |
| 808 | 848 |
| 809 scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface(bool fallback) { | 849 scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface(bool fallback) { |
| 810 // For widgets that are never visible, we don't start the compositor, so we | 850 // For widgets that are never visible, we don't start the compositor, so we |
| 811 // never get a request for a cc::OutputSurface. | 851 // never get a request for a cc::OutputSurface. |
| 812 DCHECK(!never_visible_); | 852 DCHECK(!never_visible_); |
| 813 | 853 |
| 814 #if defined(OS_ANDROID) | 854 #if defined(OS_ANDROID) |
| 815 if (SynchronousCompositorFactory* factory = | 855 if (SynchronousCompositorFactory* factory = |
| 816 SynchronousCompositorFactory::GetInstance()) { | 856 SynchronousCompositorFactory::GetInstance()) { |
| 817 return factory->CreateOutputSurface(routing_id()); | 857 return factory->CreateOutputSurface(routing_id(), |
| 858 frame_swap_message_queue_); | |
| 818 } | 859 } |
| 819 #endif | 860 #endif |
| 820 | 861 |
| 821 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 862 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| 822 bool use_software = fallback; | 863 bool use_software = fallback; |
| 823 if (command_line.HasSwitch(switches::kDisableGpuCompositing)) | 864 if (command_line.HasSwitch(switches::kDisableGpuCompositing)) |
| 824 use_software = true; | 865 use_software = true; |
| 825 | 866 |
| 826 scoped_refptr<ContextProviderCommandBuffer> context_provider; | 867 scoped_refptr<ContextProviderCommandBuffer> context_provider; |
| 827 if (!use_software) { | 868 if (!use_software) { |
| 828 context_provider = ContextProviderCommandBuffer::Create( | 869 context_provider = ContextProviderCommandBuffer::Create( |
| 829 CreateGraphicsContext3D(), "RenderCompositor"); | 870 CreateGraphicsContext3D(), "RenderCompositor"); |
| 830 if (!context_provider.get()) { | 871 if (!context_provider.get()) { |
| 831 // Cause the compositor to wait and try again. | 872 // Cause the compositor to wait and try again. |
| 832 return scoped_ptr<cc::OutputSurface>(); | 873 return scoped_ptr<cc::OutputSurface>(); |
| 833 } | 874 } |
| 834 } | 875 } |
| 835 | 876 |
| 836 uint32 output_surface_id = next_output_surface_id_++; | 877 uint32 output_surface_id = next_output_surface_id_++; |
| 837 if (command_line.HasSwitch(switches::kEnableDelegatedRenderer)) { | 878 if (command_line.HasSwitch(switches::kEnableDelegatedRenderer)) { |
| 838 DCHECK(is_threaded_compositing_enabled_); | 879 DCHECK(is_threaded_compositing_enabled_); |
| 839 return scoped_ptr<cc::OutputSurface>( | 880 return scoped_ptr<cc::OutputSurface>( |
| 840 new DelegatedCompositorOutputSurface( | 881 new DelegatedCompositorOutputSurface(routing_id(), |
| 841 routing_id(), | 882 output_surface_id, |
| 842 output_surface_id, | 883 context_provider, |
| 843 context_provider)); | 884 frame_swap_message_queue_)); |
| 844 } | 885 } |
| 845 if (!context_provider.get()) { | 886 if (!context_provider.get()) { |
| 846 scoped_ptr<cc::SoftwareOutputDevice> software_device( | 887 scoped_ptr<cc::SoftwareOutputDevice> software_device( |
| 847 new CompositorSoftwareOutputDevice()); | 888 new CompositorSoftwareOutputDevice()); |
| 848 | 889 |
| 849 return scoped_ptr<cc::OutputSurface>(new CompositorOutputSurface( | 890 return scoped_ptr<cc::OutputSurface>( |
| 850 routing_id(), | 891 new CompositorOutputSurface(routing_id(), |
| 851 output_surface_id, | 892 output_surface_id, |
| 852 NULL, | 893 NULL, |
| 853 software_device.Pass(), | 894 software_device.Pass(), |
| 854 true)); | 895 frame_swap_message_queue_, |
| 896 true)); | |
| 855 } | 897 } |
| 856 | 898 |
| 857 if (command_line.HasSwitch(cc::switches::kCompositeToMailbox)) { | 899 if (command_line.HasSwitch(cc::switches::kCompositeToMailbox)) { |
| 858 // Composite-to-mailbox is currently used for layout tests in order to cause | 900 // Composite-to-mailbox is currently used for layout tests in order to cause |
| 859 // them to draw inside in the renderer to do the readback there. This should | 901 // them to draw inside in the renderer to do the readback there. This should |
| 860 // no longer be the case when crbug.com/311404 is fixed. | 902 // no longer be the case when crbug.com/311404 is fixed. |
| 861 DCHECK(is_threaded_compositing_enabled_ || | 903 DCHECK(is_threaded_compositing_enabled_ || |
| 862 RenderThreadImpl::current()->layout_test_mode()); | 904 RenderThreadImpl::current()->layout_test_mode()); |
| 863 cc::ResourceFormat format = cc::RGBA_8888; | 905 cc::ResourceFormat format = cc::RGBA_8888; |
| 864 #if defined(OS_ANDROID) | 906 #if defined(OS_ANDROID) |
| 865 if (base::android::SysUtils::IsLowEndDevice()) | 907 if (base::android::SysUtils::IsLowEndDevice()) |
| 866 format = cc::RGB_565; | 908 format = cc::RGB_565; |
| 867 #endif | 909 #endif |
| 868 return scoped_ptr<cc::OutputSurface>( | 910 return scoped_ptr<cc::OutputSurface>( |
| 869 new MailboxOutputSurface( | 911 new MailboxOutputSurface(routing_id(), |
| 870 routing_id(), | 912 output_surface_id, |
| 871 output_surface_id, | 913 context_provider, |
| 872 context_provider, | 914 scoped_ptr<cc::SoftwareOutputDevice>(), |
| 873 scoped_ptr<cc::SoftwareOutputDevice>(), | 915 frame_swap_message_queue_, |
| 874 format)); | 916 format)); |
| 875 } | 917 } |
| 876 bool use_swap_compositor_frame_message = false; | 918 bool use_swap_compositor_frame_message = false; |
| 877 return scoped_ptr<cc::OutputSurface>( | 919 return scoped_ptr<cc::OutputSurface>( |
| 878 new CompositorOutputSurface( | 920 new CompositorOutputSurface(routing_id(), |
| 879 routing_id(), | 921 output_surface_id, |
| 880 output_surface_id, | 922 context_provider, |
| 881 context_provider, | 923 scoped_ptr<cc::SoftwareOutputDevice>(), |
| 882 scoped_ptr<cc::SoftwareOutputDevice>(), | 924 frame_swap_message_queue_, |
| 883 use_swap_compositor_frame_message)); | 925 use_swap_compositor_frame_message)); |
| 884 } | 926 } |
| 885 | 927 |
| 886 void RenderWidget::OnSwapBuffersAborted() { | 928 void RenderWidget::OnSwapBuffersAborted() { |
| 887 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersAborted"); | 929 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersAborted"); |
| 888 // Schedule another frame so the compositor learns about it. | 930 // Schedule another frame so the compositor learns about it. |
| 889 scheduleComposite(); | 931 scheduleComposite(); |
| 890 } | 932 } |
| 891 | 933 |
| 892 void RenderWidget::OnSwapBuffersPosted() { | 934 void RenderWidget::OnSwapBuffersPosted() { |
| 893 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersPosted"); | 935 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersPosted"); |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1201 void RenderWidget::didBecomeReadyForAdditionalInput() { | 1243 void RenderWidget::didBecomeReadyForAdditionalInput() { |
| 1202 TRACE_EVENT0("renderer", "RenderWidget::didBecomeReadyForAdditionalInput"); | 1244 TRACE_EVENT0("renderer", "RenderWidget::didBecomeReadyForAdditionalInput"); |
| 1203 FlushPendingInputEventAck(); | 1245 FlushPendingInputEventAck(); |
| 1204 } | 1246 } |
| 1205 | 1247 |
| 1206 void RenderWidget::DidCommitCompositorFrame() { | 1248 void RenderWidget::DidCommitCompositorFrame() { |
| 1207 FOR_EACH_OBSERVER(RenderFrameImpl, swapped_out_frames_, | 1249 FOR_EACH_OBSERVER(RenderFrameImpl, swapped_out_frames_, |
| 1208 DidCommitCompositorFrame()); | 1250 DidCommitCompositorFrame()); |
| 1209 } | 1251 } |
| 1210 | 1252 |
| 1253 namespace {} // namespace | |
| 1254 | |
| 1255 void RenderWidget::QueueMessage(IPC::Message* msg, | |
| 1256 MessageDeliveryPolicy policy) { | |
| 1257 if (policy == MESSAGE_DELIVERY_POLICY_WITH_NEXT_SWAP) { | |
| 1258 frame_swap_message_queue_->QueueMessage(msg); | |
| 1259 return; | |
| 1260 } | |
| 1261 | |
| 1262 if (!compositor_ || (policy == MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE && | |
| 1263 !compositor_->commitRequested())) { | |
| 1264 Send(msg); | |
| 1265 return; | |
| 1266 } | |
| 1267 DCHECK(policy == MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE || | |
| 1268 policy == MESSAGE_DELIVERY_POLICY_WITH_NEXT_COMMIT); | |
| 1269 | |
| 1270 scoped_ptr<cc::SwapPromise> promise(new QueueMessageSwapPromise( | |
| 1271 RenderThreadImpl::current()->sync_message_filter(), | |
| 1272 frame_swap_message_queue_, | |
| 1273 msg)); | |
| 1274 compositor_->QueueSwapPromise(promise.Pass()); | |
| 1275 } | |
| 1276 | |
| 1211 void RenderWidget::didCommitAndDrawCompositorFrame() { | 1277 void RenderWidget::didCommitAndDrawCompositorFrame() { |
| 1212 TRACE_EVENT0("gpu", "RenderWidget::didCommitAndDrawCompositorFrame"); | 1278 TRACE_EVENT0("gpu", "RenderWidget::didCommitAndDrawCompositorFrame"); |
| 1213 // Accelerated FPS tick for performance tests. See | 1279 // Accelerated FPS tick for performance tests. See |
| 1214 // tab_capture_performancetest.cc. NOTE: Tests may break if this event is | 1280 // tab_capture_performancetest.cc. NOTE: Tests may break if this event is |
| 1215 // renamed or moved. | 1281 // renamed or moved. |
| 1216 UNSHIPPED_TRACE_EVENT_INSTANT0("test_fps", "TestFrameTickGPU", | 1282 UNSHIPPED_TRACE_EVENT_INSTANT0("test_fps", "TestFrameTickGPU", |
| 1217 TRACE_EVENT_SCOPE_THREAD); | 1283 TRACE_EVENT_SCOPE_THREAD); |
| 1218 // Notify subclasses that we initiated the paint operation. | 1284 // Notify subclasses that we initiated the paint operation. |
| 1219 DidInitiatePaint(); | 1285 DidInitiatePaint(); |
| 1220 } | 1286 } |
| (...skipping 853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2074 | 2140 |
| 2075 void RenderWidget::RegisterSwappedOutChildFrame(RenderFrameImpl* frame) { | 2141 void RenderWidget::RegisterSwappedOutChildFrame(RenderFrameImpl* frame) { |
| 2076 swapped_out_frames_.AddObserver(frame); | 2142 swapped_out_frames_.AddObserver(frame); |
| 2077 } | 2143 } |
| 2078 | 2144 |
| 2079 void RenderWidget::UnregisterSwappedOutChildFrame(RenderFrameImpl* frame) { | 2145 void RenderWidget::UnregisterSwappedOutChildFrame(RenderFrameImpl* frame) { |
| 2080 swapped_out_frames_.RemoveObserver(frame); | 2146 swapped_out_frames_.RemoveObserver(frame); |
| 2081 } | 2147 } |
| 2082 | 2148 |
| 2083 } // namespace content | 2149 } // namespace content |
| OLD | NEW |