Index: content/renderer/render_widget.cc |
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc |
index fb1c011b7c0520d5dfaf8f6aa100f226f6da108f..ad1cb2fba5d435e93164d0f7e81a4e25936d0da0 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" |
@@ -400,6 +401,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) |
@@ -820,6 +822,7 @@ 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()) { |
@@ -842,6 +845,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_); |
@@ -849,7 +853,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( |
@@ -860,6 +865,7 @@ scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface(bool fallback) { |
output_surface_id, |
NULL, |
software_device.Pass(), |
+ frame_swap_message_queue_, |
true)); |
} |
@@ -880,6 +886,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; |
@@ -889,6 +896,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)); |
} |
@@ -1233,6 +1241,59 @@ void RenderWidget::DidCommitCompositorFrame() { |
DidCommitCompositorFrame()); |
} |
+namespace { |
+ |
+// TODO(mkosiba): move most of this to RenderWidgetCompositor, although |
mkosiba (inactive)
2014/05/13 19:15:26
..although it might be best to have this as a sepa
|
+class RWSwapPromise : public cc::SwapPromise { |
+ public: |
+ RWSwapPromise(scoped_refptr<IPC::SyncMessageFilter> message_sender, |
+ scoped_refptr<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 ~RWSwapPromise() { |
+ // 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_)) { |
mkosiba (inactive)
2014/05/14 10:08:08
the interesting case is how to handle messages tha
mkosiba (inactive)
2014/05/15 17:11:49
Simpler option: acquire lock on FrameSwapMessageQu
|
+ 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<FrameSwapMessageQueue> message_queue_; |
+ IPC::Message* msg_; |
+}; |
+ |
+} // namespace |
+ |
+void RenderWidget::QueueMessage(IPC::Message* msg) { |
+ if (!compositor_ || !compositor_->commitRequested()) { |
+ Send(msg); |
+ } else { |
+ scoped_ptr<cc::SwapPromise> promise( |
+ new RWSwapPromise(RenderThreadImpl::current()->sync_message_filter(), |
+ frame_swap_message_queue_, |
+ msg)); |
+ compositor_->QueueSwapPromise(promise.Pass()); |
+ } |
+} |
+ |
void RenderWidget::didCommitAndDrawCompositorFrame() { |
TRACE_EVENT0("gpu", "RenderWidget::didCommitAndDrawCompositorFrame"); |
// Accelerated FPS tick for performance tests. See |