Chromium Code Reviews| Index: content/renderer/render_widget.cc |
| diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc |
| index 5c82eda23832f6bf500bb5cb2975ce53e2c71cbd..289d7c852e72978ef37505795bf2b249332830ca 100644 |
| --- a/content/renderer/render_widget.cc |
| +++ b/content/renderer/render_widget.cc |
| @@ -36,6 +36,7 @@ |
| #include "content/renderer/gpu/compositor_output_surface.h" |
| #include "content/renderer/gpu/compositor_software_output_device.h" |
| #include "content/renderer/gpu/delegated_compositor_output_surface.h" |
| +#include "content/renderer/gpu/frame_swap_message_queue.h" |
| #include "content/renderer/gpu/mailbox_output_surface.h" |
| #include "content/renderer/gpu/render_widget_compositor.h" |
| #include "content/renderer/ime_event_guard.h" |
| @@ -153,6 +154,43 @@ ui::TextInputMode ConvertInputMode(const blink::WebString& input_mode) { |
| // be spent in input hanlders before input starts getting throttled. |
| const int kInputHandlingTimeThrottlingThresholdMicroseconds = 4166; |
| +class SendMessageOnSwapPromise : public cc::SwapPromise { |
| + public: |
| + SendMessageOnSwapPromise( |
| + scoped_refptr<IPC::SyncMessageFilter> message_sender, |
| + scoped_refptr<content::FrameSwapMessageQueue> message_queue, |
| + IPC::Message* msg) |
| + : message_sender_(message_sender), |
| + message_queue_(message_queue), |
| + msg_(msg) { |
| + DCHECK(message_sender_.get()); |
| + DCHECK(message_queue_.get()); |
| + DCHECK(msg); |
| + } |
| + |
| + virtual ~SendMessageOnSwapPromise() { |
| + // The promise should be either fulfilled or broken before it's deleted. |
| + DCHECK(!msg_); |
| + } |
| + |
| + virtual void DidSwap(cc::CompositorFrameMetadata* metadata) OVERRIDE { |
| + if (!message_queue_->TryQueueMessage(metadata->source_frame_number, msg_)) { |
| + message_sender_->Send(msg_); |
| + } |
| + msg_ = NULL; |
| + } |
| + |
| + virtual void DidNotSwap(DidNotSwapReason reason) OVERRIDE { |
| + message_sender_->Send(msg_); |
| + msg_ = NULL; |
| + } |
| + |
| + private: |
| + scoped_refptr<IPC::SyncMessageFilter> message_sender_; |
| + scoped_refptr<content::FrameSwapMessageQueue> message_queue_; |
| + IPC::Message* msg_; |
| +}; |
| + |
| } // namespace |
| namespace content { |
| @@ -397,6 +435,7 @@ RenderWidget::RenderWidget(blink::WebPopupType popup_type, |
| cached_has_main_frame_vertical_scrollbar_(false), |
| #endif |
| popup_origin_scale_for_emulation_(0.f), |
| + frame_swap_message_queue_(new FrameSwapMessageQueue()), |
| resizing_mode_selector_(new ResizingModeSelector()), |
| context_menu_source_type_(ui::MENU_SOURCE_MOUSE) { |
| if (!swapped_out) |
| @@ -811,10 +850,12 @@ scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface(bool fallback) { |
| // never get a request for a cc::OutputSurface. |
| DCHECK(!never_visible_); |
| + |
| #if defined(OS_ANDROID) |
| if (SynchronousCompositorFactory* factory = |
| SynchronousCompositorFactory::GetInstance()) { |
| - return factory->CreateOutputSurface(routing_id()); |
| + return factory->CreateOutputSurface(routing_id(), |
| + frame_swap_message_queue_); |
| } |
| #endif |
| @@ -833,6 +874,7 @@ scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface(bool fallback) { |
| } |
| } |
| + |
| uint32 output_surface_id = next_output_surface_id_++; |
| if (command_line.HasSwitch(switches::kEnableDelegatedRenderer)) { |
| DCHECK(is_threaded_compositing_enabled_); |
| @@ -840,7 +882,8 @@ scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface(bool fallback) { |
| new DelegatedCompositorOutputSurface( |
| routing_id(), |
| output_surface_id, |
| - context_provider)); |
| + context_provider, |
| + frame_swap_message_queue_)); |
| } |
| if (!context_provider.get()) { |
| scoped_ptr<cc::SoftwareOutputDevice> software_device( |
| @@ -851,6 +894,7 @@ scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface(bool fallback) { |
| output_surface_id, |
| NULL, |
| software_device.Pass(), |
| + frame_swap_message_queue_, |
| true)); |
| } |
| @@ -871,6 +915,7 @@ scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface(bool fallback) { |
| output_surface_id, |
| context_provider, |
| scoped_ptr<cc::SoftwareOutputDevice>(), |
| + frame_swap_message_queue_, |
| format)); |
| } |
| bool use_swap_compositor_frame_message = false; |
| @@ -880,6 +925,7 @@ scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface(bool fallback) { |
| output_surface_id, |
| context_provider, |
| scoped_ptr<cc::SoftwareOutputDevice>(), |
| + frame_swap_message_queue_, |
| use_swap_compositor_frame_message)); |
| } |
| @@ -1208,6 +1254,22 @@ void RenderWidget::DidCommitCompositorFrame() { |
| DidCommitCompositorFrame()); |
| } |
| +namespace { |
| + |
| +} // namespace |
| + |
| +void RenderWidget::QueueMessage(IPC::Message* msg) { |
| + if (!compositor_ || !compositor_->commitRequested()) { |
|
piman
2014/05/20 19:54:05
I think I would move the commitRequested() logic t
mkosiba (inactive)
2014/05/22 17:40:24
Originally I was thinking of having an enum specif
|
| + Send(msg); |
| + } else { |
| + scoped_ptr<cc::SwapPromise> promise(new SendMessageOnSwapPromise( |
| + RenderThreadImpl::current()->sync_message_filter(), |
| + frame_swap_message_queue_, |
| + msg)); |
| + compositor_->QueueSwapPromise(promise.Pass()); |
|
piman
2014/05/20 19:54:05
I still have concerns about the arbitrary limit in
mkosiba (inactive)
2014/05/22 17:40:24
ok, I removed the limit. I can add miletus@ to the
|
| + } |
| +} |
| + |
| void RenderWidget::didCommitAndDrawCompositorFrame() { |
| TRACE_EVENT0("gpu", "RenderWidget::didCommitAndDrawCompositorFrame"); |
| // Accelerated FPS tick for performance tests. See |