Chromium Code Reviews| Index: content/renderer/android/synchronous_compositor_proxy.cc |
| diff --git a/content/renderer/android/synchronous_compositor_proxy.cc b/content/renderer/android/synchronous_compositor_proxy.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..f344171d0e5aabfeaa18c2eb75d915e667915fc9 |
| --- /dev/null |
| +++ b/content/renderer/android/synchronous_compositor_proxy.cc |
| @@ -0,0 +1,249 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "content/renderer/android/synchronous_compositor_proxy.h" |
| + |
| +#include "content/common/android/sync_compositor_messages.h" |
| +#include "content/common/cc_messages.h" |
| +#include "ipc/ipc_message.h" |
| +#include "ipc/ipc_sender.h" |
| +#include "ui/events/latency_info.h" |
| + |
| +namespace content { |
| + |
| +class SynchronousCompositorProxy::ScopedInsideReceive { |
|
no sievers
2015/10/29 01:37:01
nit:: base::AutoReset<bool> scoped_inside_receive(
boliu
2015/10/29 04:24:44
Done
Can't remember why I didn't go with AutoRese
|
| + public: |
| + ScopedInsideReceive(SynchronousCompositorProxy* compositor) |
| + : compositor_(compositor) { |
| + DCHECK(!compositor_->inside_receive_); |
| + compositor_->inside_receive_ = true; |
| + } |
| + ~ScopedInsideReceive() { |
| + DCHECK(compositor_->inside_receive_); |
| + compositor_->inside_receive_ = false; |
| + } |
| + |
| + private: |
| + SynchronousCompositorProxy* compositor_; |
| +}; |
| + |
| +SynchronousCompositorProxy::SynchronousCompositorProxy( |
| + int routing_id, |
| + IPC::Sender* sender, |
| + SynchronousCompositorOutputSurface* output_surface, |
| + SynchronousCompositorExternalBeginFrameSource* begin_frame_source, |
| + SynchronousInputHandlerProxy* input_handler_proxy, |
| + InputHandlerManagerClient::Handler* handler) |
| + : routing_id_(routing_id), |
| + sender_(sender), |
| + output_surface_(output_surface), |
| + begin_frame_source_(begin_frame_source), |
| + input_handler_proxy_(input_handler_proxy), |
| + input_handler_(handler), |
| + inside_receive_(false), |
| + bytes_limit_(0u), |
| + version_(0u), |
| + page_scale_factor_(0.f), |
| + min_page_scale_factor_(0.f), |
| + max_page_scale_factor_(0.f), |
| + need_animate_scroll_(false), |
| + need_invalidate_(false), |
| + need_begin_frame_(false), |
| + did_activate_pending_tree_(false) { |
| + DCHECK(output_surface_); |
| + DCHECK(begin_frame_source_); |
| + DCHECK(input_handler_proxy_); |
| + DCHECK(input_handler_); |
| + output_surface_->SetSyncClient(this); |
| + output_surface_->SetTreeActivationCallback( |
| + base::Bind(&SynchronousCompositorProxy::DidActivatePendingTree, |
| + base::Unretained(this))); |
| + begin_frame_source_->SetClient(this); |
| + input_handler_proxy_->SetOnlySynchronouslyAnimateRootFlings(this); |
| +} |
| + |
| +SynchronousCompositorProxy::~SynchronousCompositorProxy() { |
| + output_surface_->SetSyncClient(nullptr); |
| + output_surface_->SetTreeActivationCallback(base::Closure()); |
| + begin_frame_source_->SetClient(nullptr); |
| + input_handler_proxy_->SetOnlySynchronouslyAnimateRootFlings(nullptr); |
| +} |
| + |
| +void SynchronousCompositorProxy::SetNeedsSynchronousAnimateInput() { |
| + need_animate_scroll_ = true; |
| + Invalidate(); |
| +} |
| + |
| +void SynchronousCompositorProxy::UpdateRootLayerState( |
| + const gfx::ScrollOffset& total_scroll_offset, |
| + const gfx::ScrollOffset& max_scroll_offset, |
| + const gfx::SizeF& scrollable_size, |
| + float page_scale_factor, |
| + float min_page_scale_factor, |
| + float max_page_scale_factor) { |
| + if (total_scroll_offset_ != total_scroll_offset || |
| + max_scroll_offset_ != max_scroll_offset || |
| + scrollable_size_ != scrollable_size || |
| + page_scale_factor_ != page_scale_factor || |
| + min_page_scale_factor_ != min_page_scale_factor || |
| + max_page_scale_factor_ != max_page_scale_factor) { |
| + total_scroll_offset_ = total_scroll_offset; |
| + max_scroll_offset_ = max_scroll_offset; |
| + scrollable_size_ = scrollable_size; |
| + page_scale_factor_ = page_scale_factor; |
| + min_page_scale_factor_ = min_page_scale_factor; |
| + max_page_scale_factor_ = max_page_scale_factor; |
| + |
| + if (!inside_receive_) { |
| + CommonRendererParams params; |
| + ConstructCommonParams(¶ms); |
| + Send(new SyncCompositorHostMsg_UpdateState(routing_id_, params)); |
| + } |
| + } |
| +} |
| + |
| +void SynchronousCompositorProxy::OnNeedsBeginFramesChange( |
| + bool needs_begin_frames) { |
| + if (need_begin_frame_ == needs_begin_frames) |
| + return; |
| + need_begin_frame_ = needs_begin_frames; |
| + if (!inside_receive_) { |
|
no sievers
2015/10/29 01:37:01
can this all be one helper function?
boliu
2015/10/29 04:24:44
Done. I think I had a TODO for this :)
|
| + CommonRendererParams params; |
| + ConstructCommonParams(¶ms); |
| + Send(new SyncCompositorHostMsg_UpdateState(routing_id_, params)); |
| + } |
| +} |
| + |
| +void SynchronousCompositorProxy::Invalidate() { |
| + need_invalidate_ = true; |
| + if (!inside_receive_) { |
| + CommonRendererParams params; |
| + ConstructCommonParams(¶ms); |
| + Send(new SyncCompositorHostMsg_UpdateState(routing_id_, params)); |
| + } |
| +} |
| + |
| +void SynchronousCompositorProxy::DidActivatePendingTree() { |
| + did_activate_pending_tree_ = true; |
| + if (!inside_receive_) { |
| + CommonRendererParams params; |
| + ConstructCommonParams(¶ms); |
| + Send(new SyncCompositorHostMsg_UpdateState(routing_id_, params)); |
| + } |
| + DeliverMessages(); |
| +} |
| + |
| +void SynchronousCompositorProxy::DeliverMessages() { |
| + ScopedVector<IPC::Message> messages; |
| + output_surface_->GetMessagesToDeliver(&messages); |
| + std::vector<IPC::Message*> released_messages; |
| + messages.release(&released_messages); |
| + for (size_t i = 0; i < released_messages.size(); ++i) { |
| + Send(released_messages[i]); |
| + released_messages[i] = nullptr; |
| + } |
| +} |
| + |
| +void SynchronousCompositorProxy::ConstructCommonParams( |
| + CommonRendererParams* params) { |
| + *params = CommonRendererParams( |
| + ++version_, total_scroll_offset_, max_scroll_offset_, scrollable_size_, |
| + page_scale_factor_, min_page_scale_factor_, max_page_scale_factor_, |
| + need_animate_scroll_, need_invalidate_, need_begin_frame_, |
| + did_activate_pending_tree_); |
| + need_invalidate_ = false; |
| + did_activate_pending_tree_ = false; |
| + // TODO(boliu): double check begin frame? |
| +} |
| + |
| +void SynchronousCompositorProxy::OnMessageReceived( |
| + const IPC::Message& message) { |
| + ScopedInsideReceive inside(this); |
| + IPC_BEGIN_MESSAGE_MAP(SynchronousCompositorProxy, message) |
| + IPC_MESSAGE_HANDLER(SyncCompositorMsg_HandleInputEvent, HandleInputEvent) |
| + IPC_MESSAGE_HANDLER(SyncCompositorMsg_BeginFrame, BeginFrame) |
| + IPC_MESSAGE_HANDLER(SyncCompositorMsg_ComputeScroll, OnComputeScroll) |
| + IPC_MESSAGE_HANDLER(SyncCompositorMsg_DemandDrawHw, DemandDrawHw) |
| + IPC_END_MESSAGE_MAP() |
| +} |
| + |
| +bool SynchronousCompositorProxy::Send(IPC::Message* message) { |
| + return sender_->Send(message); |
| +} |
| + |
| +void SynchronousCompositorProxy::HandleInputEvent( |
| + const CommonBrowserParams& common_params, |
| + const blink::WebInputEvent* event, |
| + CommonRendererParams* common_renderer_params, |
| + InputEventAckState* ack) { |
| + ProcessCommonParams(common_params); |
| + DCHECK(!input_handler_->is_null()); |
| + ui::LatencyInfo latency; |
| + *ack = input_handler_->Run(routing_id_, event, &latency); |
| + ConstructCommonParams(common_renderer_params); |
| +} |
| + |
| +void SynchronousCompositorProxy::BeginFrame( |
| + const CommonBrowserParams& common_params, |
| + const cc::BeginFrameArgs& args, |
| + CommonRendererParams* common_renderer_params) { |
| + ProcessCommonParams(common_params); |
| + if (need_begin_frame_) { |
| + begin_frame_source_->BeginFrame(args); |
| + } |
| + ConstructCommonParams(common_renderer_params); |
| +} |
| + |
| +void SynchronousCompositorProxy::DemandDrawHw( |
| + const CommonBrowserParams& common_params, |
| + const DemandDrawHwParams& params, |
| + CommonRendererParams* common_renderer_params, |
| + cc::CompositorFrame* frame) { |
| + DCHECK(frame); |
| + ProcessCommonParams(common_params); |
| + scoped_ptr<cc::CompositorFrame> frame_ptr = output_surface_->DemandDrawHw( |
| + params.surface_size, params.transform, params.viewport, params.clip, |
| + params.viewport_rect_for_tile_priority, |
| + params.transform_for_tile_priority); |
| + if (frame_ptr.get()) { |
| + frame_ptr->AssignTo(frame); |
| + DeliverMessages(); // TODO(boliu): software too. |
| + } |
| + ConstructCommonParams(common_renderer_params); |
| +} |
| + |
| +void SynchronousCompositorProxy::OnComputeScroll( |
| + const CommonBrowserParams& common_params, |
| + base::TimeTicks animation_time, |
| + CommonRendererParams* common_renderer_params) { |
| + ProcessCommonParams(common_params); |
| + if (need_animate_scroll_) { |
| + need_animate_scroll_ = false; // TODO(boliu): helper |
| + input_handler_proxy_->SynchronouslyAnimate(animation_time); |
| + } |
| + ConstructCommonParams(common_renderer_params); |
| +} |
| + |
| +void SynchronousCompositorProxy::ProcessCommonParams( |
| + const CommonBrowserParams& common_params) { |
| + if (bytes_limit_ != common_params.bytes_limit) { |
| + bytes_limit_ = common_params.bytes_limit; |
| + output_surface_->SetMemoryPolicy(bytes_limit_); |
| + } |
| + if (total_scroll_offset_ != common_params.root_scroll_offset) { |
| + total_scroll_offset_ = common_params.root_scroll_offset; |
| + input_handler_proxy_->SynchronouslySetRootScrollOffset( |
| + total_scroll_offset_); |
| + } |
| + if (!common_params.resources.empty()) { |
| + cc::CompositorFrameAck frame_ack; |
| + // TODO(boliu): mutable and swap? |
| + frame_ack.resources.insert(frame_ack.resources.end(), |
| + common_params.resources.begin(), |
| + common_params.resources.end()); |
| + output_surface_->ReturnResources(frame_ack); |
| + } |
| +} |
| + |
| +} // namespace content |