Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Side by Side Diff: content/renderer/render_widget.cc

Issue 240163005: Deliver IPC messages together with SwapCompositorFrame (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: don't use unknown to break the promise on deletion Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/auto_reset.h" 7 #include "base/auto_reset.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
(...skipping 19 matching lines...) Expand all
30 #include "content/common/input_messages.h" 30 #include "content/common/input_messages.h"
31 #include "content/common/swapped_out_messages.h" 31 #include "content/common/swapped_out_messages.h"
32 #include "content/common/view_messages.h" 32 #include "content/common/view_messages.h"
33 #include "content/public/common/content_switches.h" 33 #include "content/public/common/content_switches.h"
34 #include "content/public/common/context_menu_params.h" 34 #include "content/public/common/context_menu_params.h"
35 #include "content/renderer/cursor_utils.h" 35 #include "content/renderer/cursor_utils.h"
36 #include "content/renderer/external_popup_menu.h" 36 #include "content/renderer/external_popup_menu.h"
37 #include "content/renderer/gpu/compositor_output_surface.h" 37 #include "content/renderer/gpu/compositor_output_surface.h"
38 #include "content/renderer/gpu/compositor_software_output_device.h" 38 #include "content/renderer/gpu/compositor_software_output_device.h"
39 #include "content/renderer/gpu/delegated_compositor_output_surface.h" 39 #include "content/renderer/gpu/delegated_compositor_output_surface.h"
40 #include "content/renderer/gpu/frame_swap_message_queue.h"
40 #include "content/renderer/gpu/mailbox_output_surface.h" 41 #include "content/renderer/gpu/mailbox_output_surface.h"
41 #include "content/renderer/gpu/render_widget_compositor.h" 42 #include "content/renderer/gpu/render_widget_compositor.h"
42 #include "content/renderer/ime_event_guard.h" 43 #include "content/renderer/ime_event_guard.h"
43 #include "content/renderer/input/input_handler_manager.h" 44 #include "content/renderer/input/input_handler_manager.h"
44 #include "content/renderer/pepper/pepper_plugin_instance_impl.h" 45 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
45 #include "content/renderer/render_frame_impl.h" 46 #include "content/renderer/render_frame_impl.h"
46 #include "content/renderer/render_process.h" 47 #include "content/renderer/render_process.h"
47 #include "content/renderer/render_thread_impl.h" 48 #include "content/renderer/render_thread_impl.h"
48 #include "content/renderer/renderer_webkitplatformsupport_impl.h" 49 #include "content/renderer/renderer_webkitplatformsupport_impl.h"
49 #include "content/renderer/resizing_mode_selector.h" 50 #include "content/renderer/resizing_mode_selector.h"
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 return ui::TEXT_INPUT_MODE_DEFAULT; 148 return ui::TEXT_INPUT_MODE_DEFAULT;
148 return it->second; 149 return it->second;
149 } 150 }
150 151
151 // TODO(brianderson): Replace the hard-coded threshold with a fraction of 152 // TODO(brianderson): Replace the hard-coded threshold with a fraction of
152 // the BeginMainFrame interval. 153 // the BeginMainFrame interval.
153 // 4166us will allow 1/4 of a 60Hz interval or 1/2 of a 120Hz interval to 154 // 4166us will allow 1/4 of a 60Hz interval or 1/2 of a 120Hz interval to
154 // be spent in input hanlders before input starts getting throttled. 155 // be spent in input hanlders before input starts getting throttled.
155 const int kInputHandlingTimeThrottlingThresholdMicroseconds = 4166; 156 const int kInputHandlingTimeThrottlingThresholdMicroseconds = 4166;
156 157
158 class QueueMessageSwapPromise : public cc::SwapPromise {
159 public:
160 QueueMessageSwapPromise(
161 scoped_refptr<IPC::SyncMessageFilter> message_sender,
162 scoped_refptr<content::FrameSwapMessageQueue> message_queue,
163 int source_frame_number)
164 : message_sender_(message_sender),
165 message_queue_(message_queue),
166 source_frame_number_(source_frame_number),
167 completed_(false) {
168 DCHECK(message_sender_.get());
169 DCHECK(message_queue_.get());
170 }
171
172 virtual ~QueueMessageSwapPromise() {
173 // The promise should have either been kept or broken before it's deleted.
174 DCHECK(completed_);
175 }
176
177 virtual void DidSwap(cc::CompositorFrameMetadata* metadata) OVERRIDE {
178 DCHECK(!completed_);
179 message_queue_->AdvanceToFrame(source_frame_number_);
180 // The OutputSurface will take care of the Drain+Send.
181 completed_ = true;
182 }
183
184 virtual void DidNotSwap(DidNotSwapReason reason) OVERRIDE {
185 DCHECK(!completed_);
186 // This will also send messages explicitly queued with the WITH_NEXT_SWAP
187 // policy. It makes sense to send them if reason == SWAP_FAILS, but they may
188 // end up being sent prematurely if reason == COMMIT_FAILS.
mkosiba (inactive) 2014/06/18 14:58:02 Locally I have a CL which adds policy-specific sub
piman 2014/06/19 23:02:29 SWAP_FAILS happens when we went all the way to dra
mkosiba (inactive) 2014/06/24 18:29:54 If I'm reading that right it means there are cases
piman 2014/06/24 19:35:53 I don't think that would happen. The visibility is
189 std::vector<IPC::Message> messages;
190 message_queue_->AdvanceToFrame(source_frame_number_);
191 scoped_ptr<content::FrameSwapMessageQueue::SendMessageScope>
192 send_message_scope = message_queue_->AcquireSendMessageScope();
193 message_queue_->DrainMessages(&messages);
194 for (std::vector<IPC::Message>::iterator i = messages.begin();
195 i != messages.end();
196 ++i) {
197 message_sender_->Send(&*i);
piman 2014/06/19 23:02:29 Send is supposed to take ownership of the IPC::Mes
mkosiba (inactive) 2014/06/24 18:29:54 argh, right right
198 }
199 completed_ = true;
200 }
201
202 private:
203 scoped_refptr<IPC::SyncMessageFilter> message_sender_;
204 scoped_refptr<content::FrameSwapMessageQueue> message_queue_;
205 int source_frame_number_;
206 bool completed_;
piman 2014/06/19 23:02:29 Is this used only for DCHECKs? Should it be in #if
mkosiba (inactive) 2014/06/24 18:29:54 Done.
207 };
208
157 } // namespace 209 } // namespace
158 210
159 namespace content { 211 namespace content {
160 212
161 // RenderWidget::ScreenMetricsEmulator ---------------------------------------- 213 // RenderWidget::ScreenMetricsEmulator ----------------------------------------
162 214
163 class RenderWidget::ScreenMetricsEmulator { 215 class RenderWidget::ScreenMetricsEmulator {
164 public: 216 public:
165 ScreenMetricsEmulator( 217 ScreenMetricsEmulator(
166 RenderWidget* widget, 218 RenderWidget* widget,
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 device_scale_factor_(screen_info_.deviceScaleFactor), 442 device_scale_factor_(screen_info_.deviceScaleFactor),
391 is_threaded_compositing_enabled_(false), 443 is_threaded_compositing_enabled_(false),
392 current_event_latency_info_(NULL), 444 current_event_latency_info_(NULL),
393 next_output_surface_id_(0), 445 next_output_surface_id_(0),
394 #if defined(OS_ANDROID) 446 #if defined(OS_ANDROID)
395 text_field_is_dirty_(false), 447 text_field_is_dirty_(false),
396 outstanding_ime_acks_(0), 448 outstanding_ime_acks_(0),
397 body_background_color_(SK_ColorWHITE), 449 body_background_color_(SK_ColorWHITE),
398 #endif 450 #endif
399 popup_origin_scale_for_emulation_(0.f), 451 popup_origin_scale_for_emulation_(0.f),
452 frame_swap_message_queue_(new FrameSwapMessageQueue()),
400 resizing_mode_selector_(new ResizingModeSelector()), 453 resizing_mode_selector_(new ResizingModeSelector()),
401 context_menu_source_type_(ui::MENU_SOURCE_MOUSE) { 454 context_menu_source_type_(ui::MENU_SOURCE_MOUSE) {
402 if (!swapped_out) 455 if (!swapped_out)
403 RenderProcess::current()->AddRefProcess(); 456 RenderProcess::current()->AddRefProcess();
404 DCHECK(RenderThread::Get()); 457 DCHECK(RenderThread::Get());
405 is_threaded_compositing_enabled_ = 458 is_threaded_compositing_enabled_ =
406 CommandLine::ForCurrentProcess()->HasSwitch( 459 CommandLine::ForCurrentProcess()->HasSwitch(
407 switches::kEnableThreadedCompositing); 460 switches::kEnableThreadedCompositing);
408 } 461 }
409 462
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 } 858 }
806 859
807 scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface(bool fallback) { 860 scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface(bool fallback) {
808 // For widgets that are never visible, we don't start the compositor, so we 861 // For widgets that are never visible, we don't start the compositor, so we
809 // never get a request for a cc::OutputSurface. 862 // never get a request for a cc::OutputSurface.
810 DCHECK(!never_visible_); 863 DCHECK(!never_visible_);
811 864
812 #if defined(OS_ANDROID) 865 #if defined(OS_ANDROID)
813 if (SynchronousCompositorFactory* factory = 866 if (SynchronousCompositorFactory* factory =
814 SynchronousCompositorFactory::GetInstance()) { 867 SynchronousCompositorFactory::GetInstance()) {
815 return factory->CreateOutputSurface(routing_id()); 868 return factory->CreateOutputSurface(routing_id(),
869 frame_swap_message_queue_);
816 } 870 }
817 #endif 871 #endif
818 872
819 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 873 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
820 bool use_software = fallback; 874 bool use_software = fallback;
821 if (command_line.HasSwitch(switches::kDisableGpuCompositing)) 875 if (command_line.HasSwitch(switches::kDisableGpuCompositing))
822 use_software = true; 876 use_software = true;
823 877
824 scoped_refptr<ContextProviderCommandBuffer> context_provider; 878 scoped_refptr<ContextProviderCommandBuffer> context_provider;
825 if (!use_software) { 879 if (!use_software) {
826 context_provider = ContextProviderCommandBuffer::Create( 880 context_provider = ContextProviderCommandBuffer::Create(
827 CreateGraphicsContext3D(), "RenderCompositor"); 881 CreateGraphicsContext3D(), "RenderCompositor");
828 if (!context_provider.get()) { 882 if (!context_provider.get()) {
829 // Cause the compositor to wait and try again. 883 // Cause the compositor to wait and try again.
830 return scoped_ptr<cc::OutputSurface>(); 884 return scoped_ptr<cc::OutputSurface>();
831 } 885 }
832 } 886 }
833 887
834 uint32 output_surface_id = next_output_surface_id_++; 888 uint32 output_surface_id = next_output_surface_id_++;
835 if (command_line.HasSwitch(switches::kEnableDelegatedRenderer)) { 889 if (command_line.HasSwitch(switches::kEnableDelegatedRenderer)) {
836 DCHECK(is_threaded_compositing_enabled_); 890 DCHECK(is_threaded_compositing_enabled_);
837 return scoped_ptr<cc::OutputSurface>( 891 return scoped_ptr<cc::OutputSurface>(
838 new DelegatedCompositorOutputSurface( 892 new DelegatedCompositorOutputSurface(routing_id(),
839 routing_id(), 893 output_surface_id,
840 output_surface_id, 894 context_provider,
841 context_provider)); 895 frame_swap_message_queue_));
842 } 896 }
843 if (!context_provider.get()) { 897 if (!context_provider.get()) {
844 scoped_ptr<cc::SoftwareOutputDevice> software_device( 898 scoped_ptr<cc::SoftwareOutputDevice> software_device(
845 new CompositorSoftwareOutputDevice()); 899 new CompositorSoftwareOutputDevice());
846 900
847 return scoped_ptr<cc::OutputSurface>(new CompositorOutputSurface( 901 return scoped_ptr<cc::OutputSurface>(
848 routing_id(), 902 new CompositorOutputSurface(routing_id(),
849 output_surface_id, 903 output_surface_id,
850 NULL, 904 NULL,
851 software_device.Pass(), 905 software_device.Pass(),
852 true)); 906 frame_swap_message_queue_,
907 true));
853 } 908 }
854 909
855 if (command_line.HasSwitch(cc::switches::kCompositeToMailbox)) { 910 if (command_line.HasSwitch(cc::switches::kCompositeToMailbox)) {
856 // Composite-to-mailbox is currently used for layout tests in order to cause 911 // Composite-to-mailbox is currently used for layout tests in order to cause
857 // them to draw inside in the renderer to do the readback there. This should 912 // them to draw inside in the renderer to do the readback there. This should
858 // no longer be the case when crbug.com/311404 is fixed. 913 // no longer be the case when crbug.com/311404 is fixed.
859 DCHECK(is_threaded_compositing_enabled_ || 914 DCHECK(is_threaded_compositing_enabled_ ||
860 RenderThreadImpl::current()->layout_test_mode()); 915 RenderThreadImpl::current()->layout_test_mode());
861 cc::ResourceFormat format = cc::RGBA_8888; 916 cc::ResourceFormat format = cc::RGBA_8888;
862 #if defined(OS_ANDROID) 917 #if defined(OS_ANDROID)
863 if (base::android::SysUtils::IsLowEndDevice()) 918 if (base::android::SysUtils::IsLowEndDevice())
864 format = cc::RGB_565; 919 format = cc::RGB_565;
865 #endif 920 #endif
866 return scoped_ptr<cc::OutputSurface>( 921 return scoped_ptr<cc::OutputSurface>(
867 new MailboxOutputSurface( 922 new MailboxOutputSurface(routing_id(),
868 routing_id(), 923 output_surface_id,
869 output_surface_id, 924 context_provider,
870 context_provider, 925 scoped_ptr<cc::SoftwareOutputDevice>(),
871 scoped_ptr<cc::SoftwareOutputDevice>(), 926 frame_swap_message_queue_,
872 format)); 927 format));
873 } 928 }
874 bool use_swap_compositor_frame_message = false; 929 bool use_swap_compositor_frame_message = false;
875 return scoped_ptr<cc::OutputSurface>( 930 return scoped_ptr<cc::OutputSurface>(
876 new CompositorOutputSurface( 931 new CompositorOutputSurface(routing_id(),
877 routing_id(), 932 output_surface_id,
878 output_surface_id, 933 context_provider,
879 context_provider, 934 scoped_ptr<cc::SoftwareOutputDevice>(),
880 scoped_ptr<cc::SoftwareOutputDevice>(), 935 frame_swap_message_queue_,
881 use_swap_compositor_frame_message)); 936 use_swap_compositor_frame_message));
882 } 937 }
883 938
884 void RenderWidget::OnSwapBuffersAborted() { 939 void RenderWidget::OnSwapBuffersAborted() {
885 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersAborted"); 940 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersAborted");
886 // Schedule another frame so the compositor learns about it. 941 // Schedule another frame so the compositor learns about it.
887 scheduleComposite(); 942 scheduleComposite();
888 } 943 }
889 944
890 void RenderWidget::OnSwapBuffersPosted() { 945 void RenderWidget::OnSwapBuffersPosted() {
891 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersPosted"); 946 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersPosted");
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1211 ObserverListBase<RenderFrameImpl>::Iterator iter(video_hole_frames_); 1266 ObserverListBase<RenderFrameImpl>::Iterator iter(video_hole_frames_);
1212 RenderFrameImpl* frame; 1267 RenderFrameImpl* frame;
1213 while ((frame = iter.GetNext()) != NULL) { 1268 while ((frame = iter.GetNext()) != NULL) {
1214 // Prevent duplicate notification of DidCommitCompositorFrame(). 1269 // Prevent duplicate notification of DidCommitCompositorFrame().
1215 if (!swapped_out_frames_.HasObserver(frame)) 1270 if (!swapped_out_frames_.HasObserver(frame))
1216 frame->DidCommitCompositorFrame(); 1271 frame->DidCommitCompositorFrame();
1217 } 1272 }
1218 #endif // defined(VIDEO_HOLE) 1273 #endif // defined(VIDEO_HOLE)
1219 } 1274 }
1220 1275
1276 namespace {} // namespace
1277
1278 void RenderWidget::QueueMessage(IPC::Message* msg,
1279 MessageDeliveryPolicy policy) {
1280 if (!compositor_) {
1281 Send(msg);
1282 return;
1283 }
1284
1285 if (policy == MESSAGE_DELIVERY_POLICY_WITH_NEXT_SWAP) {
1286 frame_swap_message_queue_->QueueMessage(msg);
1287 return;
1288 }
1289
1290 if (policy == MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE &&
1291 // No need for lock: this gets changed only on this thread.
1292 !compositor_->commitRequested() &&
1293 // No need for lock: Messages are only enqueued from this thread, if we
1294 // don't have any now, no other thread will add any.
1295 !frame_swap_message_queue_->Empty()) {
mkosiba (inactive) 2014/06/18 14:58:03 so this should handle FIFO ordering correctly now.
piman 2014/06/19 23:02:29 Did you mean && frame_swap_message_queue_->Empty()
piman 2014/06/19 23:02:29 For that case, you may want to force a commit if !
mkosiba (inactive) 2014/06/24 18:29:54 yes, right, I had this method called HasMessages b
mkosiba (inactive) 2014/06/24 18:29:54 Done.
1296 Send(msg);
1297 return;
1298 }
1299
1300 DCHECK(policy == MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE ||
1301 policy == MESSAGE_DELIVERY_POLICY_WITH_NEXT_COMMIT);
1302 const int source_frame_number = compositor_->GetSourceFrameNumber();
1303 bool first_message_for_frame = false;
1304 frame_swap_message_queue_->QueueMessage(
1305 source_frame_number, msg, &first_message_for_frame);
1306 if (first_message_for_frame) {
1307 scoped_ptr<cc::SwapPromise> promise(new QueueMessageSwapPromise(
1308 RenderThreadImpl::current()->sync_message_filter(),
1309 frame_swap_message_queue_,
1310 source_frame_number));
mkosiba (inactive) 2014/06/18 14:58:03 This way uses less memory since we'll use at most
1311 compositor_->QueueSwapPromise(promise.Pass());
1312 }
1313 }
1314
1221 void RenderWidget::didCommitAndDrawCompositorFrame() { 1315 void RenderWidget::didCommitAndDrawCompositorFrame() {
1222 // NOTE: Tests may break if this event is renamed or moved. See 1316 // NOTE: Tests may break if this event is renamed or moved. See
1223 // tab_capture_performancetest.cc. 1317 // tab_capture_performancetest.cc.
1224 TRACE_EVENT0("gpu", "RenderWidget::didCommitAndDrawCompositorFrame"); 1318 TRACE_EVENT0("gpu", "RenderWidget::didCommitAndDrawCompositorFrame");
1225 // Notify subclasses that we initiated the paint operation. 1319 // Notify subclasses that we initiated the paint operation.
1226 DidInitiatePaint(); 1320 DidInitiatePaint();
1227 } 1321 }
1228 1322
1229 void RenderWidget::didCompleteSwapBuffers() { 1323 void RenderWidget::didCompleteSwapBuffers() {
1230 TRACE_EVENT0("renderer", "RenderWidget::didCompleteSwapBuffers"); 1324 TRACE_EVENT0("renderer", "RenderWidget::didCompleteSwapBuffers");
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
2070 void RenderWidget::RegisterVideoHoleFrame(RenderFrameImpl* frame) { 2164 void RenderWidget::RegisterVideoHoleFrame(RenderFrameImpl* frame) {
2071 video_hole_frames_.AddObserver(frame); 2165 video_hole_frames_.AddObserver(frame);
2072 } 2166 }
2073 2167
2074 void RenderWidget::UnregisterVideoHoleFrame(RenderFrameImpl* frame) { 2168 void RenderWidget::UnregisterVideoHoleFrame(RenderFrameImpl* frame) {
2075 video_hole_frames_.RemoveObserver(frame); 2169 video_hole_frames_.RemoveObserver(frame);
2076 } 2170 }
2077 #endif // defined(VIDEO_HOLE) 2171 #endif // defined(VIDEO_HOLE)
2078 2172
2079 } // namespace content 2173 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698