| OLD | NEW |
| (Empty) |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "content/browser/android/synchronous_compositor_observer.h" | |
| 6 | |
| 7 #include <map> | |
| 8 | |
| 9 #include "base/lazy_instance.h" | |
| 10 #include "base/stl_util.h" | |
| 11 #include "content/browser/android/synchronous_compositor_host.h" | |
| 12 #include "content/browser/bad_message.h" | |
| 13 #include "content/common/android/sync_compositor_messages.h" | |
| 14 #include "content/public/browser/render_process_host.h" | |
| 15 #include "ui/android/window_android.h" | |
| 16 | |
| 17 namespace content { | |
| 18 | |
| 19 SynchronousCompositorObserver::SynchronousCompositorObserver(int process_id) | |
| 20 : BrowserMessageFilter(SyncCompositorMsgStart), | |
| 21 render_process_host_(RenderProcessHost::FromID(process_id)), | |
| 22 window_android_in_vsync_(nullptr) { | |
| 23 DCHECK(render_process_host_); | |
| 24 } | |
| 25 | |
| 26 SynchronousCompositorObserver::~SynchronousCompositorObserver() { | |
| 27 DCHECK(compositor_host_pending_renderer_state_.empty()); | |
| 28 // TODO(boliu): signal pending frames. | |
| 29 } | |
| 30 | |
| 31 void SynchronousCompositorObserver::SyncStateAfterVSync( | |
| 32 ui::WindowAndroid* window_android, | |
| 33 SynchronousCompositorHost* compositor_host) { | |
| 34 DCHECK(!window_android_in_vsync_ || | |
| 35 window_android_in_vsync_ == window_android) | |
| 36 << !!window_android_in_vsync_; | |
| 37 DCHECK(compositor_host); | |
| 38 DCHECK(!base::ContainsValue(compositor_host_pending_renderer_state_, | |
| 39 compositor_host)); | |
| 40 compositor_host_pending_renderer_state_.push_back(compositor_host); | |
| 41 if (window_android_in_vsync_) | |
| 42 return; | |
| 43 window_android_in_vsync_ = window_android; | |
| 44 window_android_in_vsync_->AddObserver(this); | |
| 45 } | |
| 46 | |
| 47 bool SynchronousCompositorObserver::OnMessageReceived( | |
| 48 const IPC::Message& message) { | |
| 49 bool handled = true; | |
| 50 IPC_BEGIN_MESSAGE_MAP(SynchronousCompositorObserver, message) | |
| 51 IPC_MESSAGE_HANDLER_GENERIC(SyncCompositorHostMsg_ReturnFrame, | |
| 52 ReceiveFrame(message)) | |
| 53 IPC_MESSAGE_UNHANDLED(handled = false) | |
| 54 IPC_END_MESSAGE_MAP() | |
| 55 return handled; | |
| 56 } | |
| 57 | |
| 58 bool SynchronousCompositorObserver::ReceiveFrame(const IPC::Message& message) { | |
| 59 SyncCompositorHostMsg_ReturnFrame::Param param; | |
| 60 if (!SyncCompositorHostMsg_ReturnFrame::Read(&message, ¶m)) | |
| 61 return false; | |
| 62 | |
| 63 int routing_id = message.routing_id(); | |
| 64 scoped_refptr<SynchronousCompositor::FrameFuture> future; | |
| 65 { | |
| 66 base::AutoLock lock(future_map_lock_); | |
| 67 auto itr = future_map_.find(routing_id); | |
| 68 if (itr == future_map_.end()) { | |
| 69 bad_message::ReceivedBadMessage(render_process_host_, | |
| 70 bad_message::SCO_INVALID_ARGUMENT); | |
| 71 return true; | |
| 72 } | |
| 73 future = std::move(itr->second); | |
| 74 DCHECK(future); | |
| 75 future_map_.erase(itr); | |
| 76 } | |
| 77 | |
| 78 auto frame_ptr = base::MakeUnique<SynchronousCompositor::Frame>(); | |
| 79 frame_ptr->compositor_frame_sink_id = std::get<0>(param); | |
| 80 cc::CompositorFrame& compositor_frame = std::get<1>(param); | |
| 81 if (compositor_frame.delegated_frame_data) { | |
| 82 frame_ptr->frame.reset(new cc::CompositorFrame); | |
| 83 *frame_ptr->frame = std::move(compositor_frame); | |
| 84 } | |
| 85 future->setFrame(std::move(frame_ptr)); | |
| 86 // TODO(boliu): Post metadata back to UI thread. | |
| 87 return true; | |
| 88 } | |
| 89 | |
| 90 void SynchronousCompositorObserver::SetFrameFuture( | |
| 91 int routing_id, | |
| 92 scoped_refptr<SynchronousCompositor::FrameFuture> frame_future) { | |
| 93 // TODO(boliu): Need a sequenced id, to queue previous frames. | |
| 94 DCHECK(frame_future); | |
| 95 base::AutoLock lock(future_map_lock_); | |
| 96 future_map_[routing_id] = std::move(frame_future); | |
| 97 } | |
| 98 | |
| 99 void SynchronousCompositorObserver::OnCompositingDidCommit() { | |
| 100 NOTREACHED(); | |
| 101 } | |
| 102 | |
| 103 void SynchronousCompositorObserver::OnRootWindowVisibilityChanged( | |
| 104 bool visible) { | |
| 105 NOTREACHED(); | |
| 106 } | |
| 107 | |
| 108 void SynchronousCompositorObserver::OnAttachCompositor() { | |
| 109 NOTREACHED(); | |
| 110 } | |
| 111 | |
| 112 void SynchronousCompositorObserver::OnDetachCompositor() { | |
| 113 NOTREACHED(); | |
| 114 } | |
| 115 | |
| 116 void SynchronousCompositorObserver::OnVSync(base::TimeTicks frame_time, | |
| 117 base::TimeDelta vsync_period) { | |
| 118 // This is called after DidSendBeginFrame for SynchronousCompositorHosts | |
| 119 // belonging to this WindowAndroid, since this is added as an Observer after | |
| 120 // the observer iteration has started. | |
| 121 DCHECK(window_android_in_vsync_); | |
| 122 window_android_in_vsync_->RemoveObserver(this); | |
| 123 window_android_in_vsync_ = nullptr; | |
| 124 | |
| 125 std::vector<int> routing_ids; | |
| 126 routing_ids.reserve(compositor_host_pending_renderer_state_.size()); | |
| 127 for (const auto host : compositor_host_pending_renderer_state_) | |
| 128 routing_ids.push_back(host->routing_id()); | |
| 129 | |
| 130 std::vector<SyncCompositorCommonRendererParams> params; | |
| 131 params.reserve(compositor_host_pending_renderer_state_.size()); | |
| 132 | |
| 133 if (!render_process_host_->Send( | |
| 134 new SyncCompositorMsg_SynchronizeRendererState(routing_ids, | |
| 135 ¶ms))) { | |
| 136 return; | |
| 137 } | |
| 138 | |
| 139 if (compositor_host_pending_renderer_state_.size() != params.size()) { | |
| 140 bad_message::ReceivedBadMessage(render_process_host_, | |
| 141 bad_message::SCO_INVALID_ARGUMENT); | |
| 142 return; | |
| 143 } | |
| 144 | |
| 145 for (size_t i = 0; i < compositor_host_pending_renderer_state_.size(); ++i) { | |
| 146 compositor_host_pending_renderer_state_[i]->ProcessCommonParams(params[i]); | |
| 147 } | |
| 148 compositor_host_pending_renderer_state_.clear(); | |
| 149 } | |
| 150 | |
| 151 void SynchronousCompositorObserver::OnActivityStopped() { | |
| 152 NOTREACHED(); | |
| 153 } | |
| 154 | |
| 155 void SynchronousCompositorObserver::OnActivityStarted() { | |
| 156 NOTREACHED(); | |
| 157 } | |
| 158 | |
| 159 } // namespace content | |
| OLD | NEW |