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

Side by Side Diff: gpu/ipc/service/gpu_channel.cc

Issue 2440093003: WIP GPU scheduler + delayed activation / tile draw
Patch Set: SignalSyncToken -> IsFenceSyncReleased Created 4 years 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
« no previous file with comments | « gpu/ipc/service/gpu_channel.h ('k') | gpu/ipc/service/gpu_channel_manager.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "gpu/ipc/service/gpu_channel.h" 5 #include "gpu/ipc/service/gpu_channel.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #if defined(OS_WIN) 9 #if defined(OS_WIN)
10 #include <windows.h> 10 #include <windows.h>
(...skipping 21 matching lines...) Expand all
32 #include "build/build_config.h" 32 #include "build/build_config.h"
33 #include "gpu/command_buffer/common/mailbox.h" 33 #include "gpu/command_buffer/common/mailbox.h"
34 #include "gpu/command_buffer/service/command_executor.h" 34 #include "gpu/command_buffer/service/command_executor.h"
35 #include "gpu/command_buffer/service/image_factory.h" 35 #include "gpu/command_buffer/service/image_factory.h"
36 #include "gpu/command_buffer/service/mailbox_manager.h" 36 #include "gpu/command_buffer/service/mailbox_manager.h"
37 #include "gpu/command_buffer/service/sync_point_manager.h" 37 #include "gpu/command_buffer/service/sync_point_manager.h"
38 #include "gpu/ipc/common/gpu_messages.h" 38 #include "gpu/ipc/common/gpu_messages.h"
39 #include "gpu/ipc/service/gpu_channel_manager.h" 39 #include "gpu/ipc/service/gpu_channel_manager.h"
40 #include "gpu/ipc/service/gpu_channel_manager_delegate.h" 40 #include "gpu/ipc/service/gpu_channel_manager_delegate.h"
41 #include "gpu/ipc/service/gpu_memory_buffer_factory.h" 41 #include "gpu/ipc/service/gpu_memory_buffer_factory.h"
42 #include "gpu/ipc/service/gpu_scheduler.h"
42 #include "ipc/ipc_channel.h" 43 #include "ipc/ipc_channel.h"
43 #include "ipc/message_filter.h" 44 #include "ipc/message_filter.h"
44 #include "ui/gl/gl_context.h" 45 #include "ui/gl/gl_context.h"
45 #include "ui/gl/gl_image_shared_memory.h" 46 #include "ui/gl/gl_image_shared_memory.h"
46 #include "ui/gl/gl_surface.h" 47 #include "ui/gl/gl_surface.h"
47 48
48 namespace gpu { 49 namespace gpu {
49 namespace { 50 namespace {
50 51
51 // Number of milliseconds between successive vsync. Many GL commands block 52 // Number of milliseconds between successive vsync. Many GL commands block
(...skipping 12 matching lines...) Expand all
64 // Stop the preemption once the time for the longest pending IPC drops 65 // Stop the preemption once the time for the longest pending IPC drops
65 // below this threshold. 66 // below this threshold.
66 const int64_t kStopPreemptThresholdMs = kVsyncIntervalMs; 67 const int64_t kStopPreemptThresholdMs = kVsyncIntervalMs;
67 68
68 } // anonymous namespace 69 } // anonymous namespace
69 70
70 scoped_refptr<GpuChannelMessageQueue> GpuChannelMessageQueue::Create( 71 scoped_refptr<GpuChannelMessageQueue> GpuChannelMessageQueue::Create(
71 int32_t stream_id, 72 int32_t stream_id,
72 GpuStreamPriority stream_priority, 73 GpuStreamPriority stream_priority,
73 GpuChannel* channel, 74 GpuChannel* channel,
74 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, 75 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
75 const scoped_refptr<PreemptionFlag>& preempting_flag, 76 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
76 const scoped_refptr<PreemptionFlag>& preempted_flag, 77 GpuScheduler* scheduler,
78 scoped_refptr<PreemptionFlag> preempting_flag,
79 scoped_refptr<PreemptionFlag> preemption_flag,
77 SyncPointManager* sync_point_manager) { 80 SyncPointManager* sync_point_manager) {
78 return new GpuChannelMessageQueue(stream_id, stream_priority, channel, 81 return new GpuChannelMessageQueue(
79 io_task_runner, preempting_flag, 82 stream_id, stream_priority, channel, std::move(main_task_runner),
80 preempted_flag, sync_point_manager); 83 std::move(io_task_runner), scheduler, std::move(preempting_flag),
84 std::move(preemption_flag), sync_point_manager);
81 } 85 }
82 86
83 scoped_refptr<SyncPointOrderData> 87 scoped_refptr<SyncPointOrderData>
84 GpuChannelMessageQueue::GetSyncPointOrderData() { 88 GpuChannelMessageQueue::GetSyncPointOrderData() {
85 return sync_point_order_data_; 89 return sync_point_order_data_;
86 } 90 }
87 91
88 GpuChannelMessageQueue::GpuChannelMessageQueue( 92 GpuChannelMessageQueue::GpuChannelMessageQueue(
89 int32_t stream_id, 93 int32_t stream_id,
90 GpuStreamPriority stream_priority, 94 GpuStreamPriority stream_priority,
91 GpuChannel* channel, 95 GpuChannel* channel,
92 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, 96 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
93 const scoped_refptr<PreemptionFlag>& preempting_flag, 97 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
94 const scoped_refptr<PreemptionFlag>& preempted_flag, 98 GpuScheduler* scheduler,
99 scoped_refptr<PreemptionFlag> preempting_flag,
100 scoped_refptr<PreemptionFlag> preemption_flag,
95 SyncPointManager* sync_point_manager) 101 SyncPointManager* sync_point_manager)
96 : stream_id_(stream_id), 102 : stream_id_(stream_id),
97 stream_priority_(stream_priority), 103 priority_(stream_priority),
98 enabled_(true), 104 num_routes_(0u),
99 scheduled_(true), 105 scheduled_(true),
100 channel_(channel), 106 channel_(channel),
101 preemption_state_(IDLE), 107 preemption_state_(IDLE),
102 max_preemption_time_( 108 max_preemption_time_(
103 base::TimeDelta::FromMilliseconds(kMaxPreemptTimeMs)), 109 base::TimeDelta::FromMilliseconds(kMaxPreemptTimeMs)),
104 timer_(new base::OneShotTimer), 110 timer_(new base::OneShotTimer),
105 sync_point_order_data_(SyncPointOrderData::Create()), 111 sync_point_order_data_(SyncPointOrderData::Create()),
106 io_task_runner_(io_task_runner), 112 main_task_runner_(std::move(main_task_runner)),
107 preempting_flag_(preempting_flag), 113 io_task_runner_(std::move(io_task_runner)),
108 preempted_flag_(preempted_flag), 114 scheduler_(scheduler),
115 preempting_flag_(std::move(preempting_flag)),
116 preemption_flag_(std::move(preemption_flag)),
109 sync_point_manager_(sync_point_manager) { 117 sync_point_manager_(sync_point_manager) {
110 timer_->SetTaskRunner(io_task_runner); 118 timer_->SetTaskRunner(io_task_runner);
111 io_thread_checker_.DetachFromThread(); 119 io_thread_checker_.DetachFromThread();
120 if (scheduler_)
121 scheduler_->AddStream(this, stream_priority);
112 } 122 }
113 123
114 GpuChannelMessageQueue::~GpuChannelMessageQueue() { 124 GpuChannelMessageQueue::~GpuChannelMessageQueue() {
115 DCHECK(!enabled_);
116 DCHECK(channel_messages_.empty()); 125 DCHECK(channel_messages_.empty());
117 } 126 }
118 127
119 void GpuChannelMessageQueue::Disable() { 128 void GpuChannelMessageQueue::Destroy() {
120 { 129 // We guarantee that the queues will no longer be modified when |Destroy| is
121 base::AutoLock auto_lock(channel_lock_); 130 // called therefore it is now safe to modify the queue without the lock.
122 DCHECK(enabled_);
123 enabled_ = false;
124 }
125
126 // We guarantee that the queues will no longer be modified after enabled_
127 // is set to false, it is now safe to modify the queue without the lock.
128 // All public facing modifying functions check enabled_ while all
129 // private modifying functions DCHECK(enabled_) to enforce this.
130 while (!channel_messages_.empty()) { 131 while (!channel_messages_.empty()) {
131 const IPC::Message& msg = channel_messages_.front()->message; 132 const IPC::Message& msg = channel_messages_.front()->message;
132 if (msg.is_sync()) { 133 if (msg.is_sync()) {
133 IPC::Message* reply = IPC::SyncMessage::GenerateReply(&msg); 134 IPC::Message* reply = IPC::SyncMessage::GenerateReply(&msg);
134 reply->set_reply_error(); 135 reply->set_reply_error();
135 channel_->Send(reply); 136 channel_->Send(reply);
136 } 137 }
137 channel_messages_.pop_front(); 138 channel_messages_.pop_front();
138 } 139 }
139 140
140 sync_point_order_data_->Destroy(); 141 sync_point_order_data_->Destroy();
141 sync_point_order_data_ = nullptr; 142 sync_point_order_data_ = nullptr;
142 143
144 if (scheduler_)
145 scheduler_->RemoveStream(this);
146
147 channel_ = nullptr;
148
143 io_task_runner_->PostTask( 149 io_task_runner_->PostTask(
144 FROM_HERE, base::Bind(&GpuChannelMessageQueue::DisableIO, this)); 150 FROM_HERE, base::Bind(&GpuChannelMessageQueue::DestroyIO, this));
145 } 151 }
146 152
147 void GpuChannelMessageQueue::DisableIO() { 153 void GpuChannelMessageQueue::DestroyIO() {
148 DCHECK(io_thread_checker_.CalledOnValidThread()); 154 DCHECK(io_thread_checker_.CalledOnValidThread());
149 timer_ = nullptr; 155 timer_ = nullptr;
150 } 156 }
151 157
158 void GpuChannelMessageQueue::OnRouteAdded() {
159 num_routes_++;
160 }
161
162 void GpuChannelMessageQueue::OnRouteRemoved() {
163 num_routes_--;
164 }
165
166 size_t GpuChannelMessageQueue::NumRoutes() const {
167 return num_routes_;
168 }
169
170 void GpuChannelMessageQueue::Run() {
171 DCHECK(scheduler_);
172 while (!scheduler_->ShouldYield() && HasMessages() && IsScheduled())
173 channel_->HandleMessageOnStream(this);
174 }
175
152 bool GpuChannelMessageQueue::IsScheduled() const { 176 bool GpuChannelMessageQueue::IsScheduled() const {
153 base::AutoLock lock(channel_lock_); 177 base::AutoLock lock(channel_lock_);
154 return scheduled_; 178 return scheduled_;
155 } 179 }
156 180
157 void GpuChannelMessageQueue::OnRescheduled(bool scheduled) { 181 void GpuChannelMessageQueue::Schedule() {
158 base::AutoLock lock(channel_lock_); 182 base::AutoLock lock(channel_lock_);
159 DCHECK(enabled_); 183 if (scheduled_)
160 if (scheduled_ == scheduled)
161 return; 184 return;
162 scheduled_ = scheduled; 185 scheduled_ = true;
163 if (scheduled) 186 if (scheduler_) {
164 channel_->PostHandleMessage(this); 187 scheduler_->ScheduleStream(this);
165 if (preempting_flag_) { 188 } else {
166 io_task_runner_->PostTask( 189 if (!channel_messages_.empty())
167 FROM_HERE, 190 channel_->PostHandleMessageOnStream(this);
168 base::Bind(&GpuChannelMessageQueue::UpdatePreemptionState, this)); 191 if (preempting_flag_)
192 PostUpdatePreemptionState();
169 } 193 }
170 } 194 }
171 195
196 void GpuChannelMessageQueue::Deschedule() {
197 base::AutoLock lock(channel_lock_);
198 if (!scheduled_)
199 return;
200 scheduled_ = false;
201 if (scheduler_) {
202 scheduler_->DescheduleStream(this);
203 } else if (preempting_flag_) {
204 PostUpdatePreemptionState();
205 }
206 }
207
172 uint32_t GpuChannelMessageQueue::GetUnprocessedOrderNum() const { 208 uint32_t GpuChannelMessageQueue::GetUnprocessedOrderNum() const {
173 return sync_point_order_data_->unprocessed_order_num(); 209 return sync_point_order_data_->unprocessed_order_num();
174 } 210 }
175 211
176 uint32_t GpuChannelMessageQueue::GetProcessedOrderNum() const { 212 uint32_t GpuChannelMessageQueue::GetProcessedOrderNum() const {
177 return sync_point_order_data_->processed_order_num(); 213 return sync_point_order_data_->processed_order_num();
178 } 214 }
179 215
180 bool GpuChannelMessageQueue::PushBackMessage(const IPC::Message& message) { 216 bool GpuChannelMessageQueue::HasMessages() const {
181 base::AutoLock auto_lock(channel_lock_); 217 base::AutoLock auto_lock(channel_lock_);
182 if (enabled_) { 218 return !channel_messages_.empty();
183 if (message.type() == GpuCommandBufferMsg_WaitForTokenInRange::ID || 219 }
184 message.type() == GpuCommandBufferMsg_WaitForGetOffsetInRange::ID) {
185 channel_->PostHandleOutOfOrderMessage(message);
186 return true;
187 }
188 220
189 uint32_t order_num = sync_point_order_data_->GenerateUnprocessedOrderNumber( 221 void GpuChannelMessageQueue::PushBackMessage(const IPC::Message& message) {
190 sync_point_manager_); 222 base::AutoLock auto_lock(channel_lock_);
191 std::unique_ptr<GpuChannelMessage> msg( 223 DCHECK(channel_);
192 new GpuChannelMessage(message, order_num, base::TimeTicks::Now()));
193 224
194 if (channel_messages_.empty()) { 225 uint32_t order_num = sync_point_order_data_->GenerateUnprocessedOrderNumber(
195 DCHECK(scheduled_); 226 sync_point_manager_);
196 channel_->PostHandleMessage(this); 227 std::unique_ptr<GpuChannelMessage> msg(
197 } 228 new GpuChannelMessage(message, order_num, base::TimeTicks::Now()));
229 channel_messages_.push_back(std::move(msg));
198 230
199 channel_messages_.push_back(std::move(msg)); 231 bool start_running = channel_messages_.size() == 1 && scheduled_;
200 232
233 if (scheduler_) {
234 if (start_running)
235 scheduler_->ScheduleStream(this);
236 } else {
237 if (start_running)
238 channel_->PostHandleMessageOnStream(this);
201 if (preempting_flag_) 239 if (preempting_flag_)
202 UpdatePreemptionStateHelper(); 240 UpdatePreemptionStateHelper();
203
204 return true;
205 } 241 }
206 return false;
207 } 242 }
208 243
209 const GpuChannelMessage* GpuChannelMessageQueue::BeginMessageProcessing() { 244 const GpuChannelMessage* GpuChannelMessageQueue::BeginMessageProcessing() {
210 base::AutoLock auto_lock(channel_lock_); 245 base::AutoLock auto_lock(channel_lock_);
211 DCHECK(enabled_); 246 if (channel_messages_.empty())
212 // If we have been preempted by another channel, just post a task to wake up. 247 return nullptr;
213 if (preempted_flag_ && preempted_flag_->IsSet()) { 248 if (preemption_flag_ && preemption_flag_->IsSet()) {
214 channel_->PostHandleMessage(this); 249 channel_->PostHandleMessageOnStream(this);
215 return nullptr; 250 return nullptr;
216 } 251 }
217 if (channel_messages_.empty())
218 return nullptr;
219 sync_point_order_data_->BeginProcessingOrderNumber( 252 sync_point_order_data_->BeginProcessingOrderNumber(
220 channel_messages_.front()->order_number); 253 channel_messages_.front()->order_number);
221 return channel_messages_.front().get(); 254 return channel_messages_.front().get();
222 } 255 }
223 256
224 void GpuChannelMessageQueue::PauseMessageProcessing() { 257 void GpuChannelMessageQueue::PauseMessageProcessing() {
225 base::AutoLock auto_lock(channel_lock_); 258 base::AutoLock auto_lock(channel_lock_);
226 DCHECK(!channel_messages_.empty()); 259 DCHECK(!channel_messages_.empty());
227 260
228 // If we have been preempted by another channel, just post a task to wake up.
229 if (scheduled_)
230 channel_->PostHandleMessage(this);
231
232 sync_point_order_data_->PauseProcessingOrderNumber( 261 sync_point_order_data_->PauseProcessingOrderNumber(
233 channel_messages_.front()->order_number); 262 channel_messages_.front()->order_number);
263
264 if (!scheduler_) {
265 if (scheduled_)
266 channel_->PostHandleMessageOnStream(this);
267 if (preempting_flag_)
268 PostUpdatePreemptionState();
269 }
234 } 270 }
235 271
236 void GpuChannelMessageQueue::FinishMessageProcessing() { 272 void GpuChannelMessageQueue::FinishMessageProcessing() {
237 base::AutoLock auto_lock(channel_lock_); 273 base::AutoLock auto_lock(channel_lock_);
238 DCHECK(!channel_messages_.empty()); 274 DCHECK(!channel_messages_.empty());
239 DCHECK(scheduled_); 275 DCHECK(scheduled_);
240 276
241 sync_point_order_data_->FinishProcessingOrderNumber( 277 sync_point_order_data_->FinishProcessingOrderNumber(
242 channel_messages_.front()->order_number); 278 channel_messages_.front()->order_number);
243 channel_messages_.pop_front(); 279 channel_messages_.pop_front();
244 280
245 if (!channel_messages_.empty()) 281 if (scheduler_) {
246 channel_->PostHandleMessage(this); 282 if (channel_messages_.empty())
247 283 scheduler_->DescheduleStream(this);
248 if (preempting_flag_) { 284 } else {
249 io_task_runner_->PostTask( 285 if (!channel_messages_.empty())
250 FROM_HERE, 286 channel_->PostHandleMessageOnStream(this);
251 base::Bind(&GpuChannelMessageQueue::UpdatePreemptionState, this)); 287 if (preempting_flag_)
288 PostUpdatePreemptionState();
252 } 289 }
253 } 290 }
254 291
292 void GpuChannelMessageQueue::PostUpdatePreemptionState() {
293 DCHECK(preempting_flag_);
294 DCHECK(!scheduler_);
295 io_task_runner_->PostTask(
296 FROM_HERE,
297 base::Bind(&GpuChannelMessageQueue::UpdatePreemptionState, this));
298 }
299
255 void GpuChannelMessageQueue::UpdatePreemptionState() { 300 void GpuChannelMessageQueue::UpdatePreemptionState() {
256 DCHECK(io_thread_checker_.CalledOnValidThread());
257 DCHECK(preempting_flag_);
258 base::AutoLock lock(channel_lock_); 301 base::AutoLock lock(channel_lock_);
259 UpdatePreemptionStateHelper(); 302 UpdatePreemptionStateHelper();
260 } 303 }
261 304
262 void GpuChannelMessageQueue::UpdatePreemptionStateHelper() { 305 void GpuChannelMessageQueue::UpdatePreemptionStateHelper() {
263 DCHECK(io_thread_checker_.CalledOnValidThread()); 306 DCHECK(io_thread_checker_.CalledOnValidThread());
307 channel_lock_.AssertAcquired();
264 DCHECK(preempting_flag_); 308 DCHECK(preempting_flag_);
265 channel_lock_.AssertAcquired();
266 switch (preemption_state_) { 309 switch (preemption_state_) {
267 case IDLE: 310 case IDLE:
268 UpdateStateIdle(); 311 UpdateStateIdle();
269 break; 312 break;
270 case WAITING: 313 case WAITING:
271 UpdateStateWaiting(); 314 UpdateStateWaiting();
272 break; 315 break;
273 case CHECKING: 316 case CHECKING:
274 UpdateStateChecking(); 317 UpdateStateChecking();
275 break; 318 break;
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 DCHECK(preempting_flag_); 479 DCHECK(preempting_flag_);
437 channel_lock_.AssertAcquired(); 480 channel_lock_.AssertAcquired();
438 DCHECK(preemption_state_ == CHECKING || preemption_state_ == PREEMPTING); 481 DCHECK(preemption_state_ == CHECKING || preemption_state_ == PREEMPTING);
439 DCHECK(!scheduled_); 482 DCHECK(!scheduled_);
440 483
441 preemption_state_ = WOULD_PREEMPT_DESCHEDULED; 484 preemption_state_ = WOULD_PREEMPT_DESCHEDULED;
442 preempting_flag_->Reset(); 485 preempting_flag_->Reset();
443 TRACE_COUNTER_ID1("gpu", "GpuChannel::Preempting", this, 0); 486 TRACE_COUNTER_ID1("gpu", "GpuChannel::Preempting", this, 0);
444 } 487 }
445 488
446 GpuChannelMessageFilter::GpuChannelMessageFilter() 489 GpuChannelMessageFilter::GpuChannelMessageFilter(GpuChannel* gpu_channel)
447 : channel_(nullptr), peer_pid_(base::kNullProcessId) {} 490 : gpu_channel_(gpu_channel) {}
448 491
449 GpuChannelMessageFilter::~GpuChannelMessageFilter() {} 492 GpuChannelMessageFilter::~GpuChannelMessageFilter() {}
450 493
494 scoped_refptr<GpuChannelMessageFilter> GpuChannelMessageFilter::Create(
495 GpuChannel* gpu_channel) {
496 return make_scoped_refptr(new GpuChannelMessageFilter(gpu_channel));
497 }
498
499 void GpuChannelMessageFilter::Disable() {
500 base::AutoLock lock(lock_);
501 enabled_ = false;
502 }
503
451 void GpuChannelMessageFilter::OnFilterAdded(IPC::Channel* channel) { 504 void GpuChannelMessageFilter::OnFilterAdded(IPC::Channel* channel) {
452 DCHECK(!channel_); 505 DCHECK(!channel_);
453 channel_ = channel; 506 channel_ = channel;
454 for (scoped_refptr<IPC::MessageFilter>& filter : channel_filters_) { 507 for (scoped_refptr<IPC::MessageFilter>& filter : channel_filters_) {
455 filter->OnFilterAdded(channel_); 508 filter->OnFilterAdded(channel_);
456 } 509 }
457 } 510 }
458 511
459 void GpuChannelMessageFilter::OnFilterRemoved() { 512 void GpuChannelMessageFilter::OnFilterRemoved() {
460 for (scoped_refptr<IPC::MessageFilter>& filter : channel_filters_) { 513 for (scoped_refptr<IPC::MessageFilter>& filter : channel_filters_) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 } 547 }
495 548
496 void GpuChannelMessageFilter::RemoveChannelFilter( 549 void GpuChannelMessageFilter::RemoveChannelFilter(
497 scoped_refptr<IPC::MessageFilter> filter) { 550 scoped_refptr<IPC::MessageFilter> filter) {
498 if (channel_) 551 if (channel_)
499 filter->OnFilterRemoved(); 552 filter->OnFilterRemoved();
500 channel_filters_.erase( 553 channel_filters_.erase(
501 std::find(channel_filters_.begin(), channel_filters_.end(), filter)); 554 std::find(channel_filters_.begin(), channel_filters_.end(), filter));
502 } 555 }
503 556
504 // This gets called from the main thread and assumes that all messages which
505 // lead to creation of a new route are synchronous messages.
506 // TODO(sunnyps): Create routes (and streams) on the IO thread so that we can
507 // make the CreateCommandBuffer/VideoDecoder/VideoEncoder messages asynchronous.
508 void GpuChannelMessageFilter::AddRoute( 557 void GpuChannelMessageFilter::AddRoute(
509 int32_t route_id, 558 int32_t route_id,
510 const scoped_refptr<GpuChannelMessageQueue>& queue) { 559 scoped_refptr<GpuChannelMessageQueue> stream) {
511 base::AutoLock lock(routes_lock_); 560 base::AutoLock lock(lock_);
512 routes_.insert(std::make_pair(route_id, queue)); 561 routes_.insert(std::make_pair(route_id, stream));
513 } 562 }
514 563
515 void GpuChannelMessageFilter::RemoveRoute(int32_t route_id) { 564 scoped_refptr<GpuChannelMessageQueue> GpuChannelMessageFilter::RemoveRoute(
516 base::AutoLock lock(routes_lock_); 565 int32_t route_id) {
517 routes_.erase(route_id); 566 base::AutoLock lock(lock_);
567 auto it = routes_.find(route_id);
568 if (it != routes_.end()) {
569 scoped_refptr<GpuChannelMessageQueue> stream(it->second);
570 routes_.erase(it);
571 return stream;
572 }
573 return nullptr;
518 } 574 }
519 575
520 bool GpuChannelMessageFilter::OnMessageReceived(const IPC::Message& message) { 576 bool GpuChannelMessageFilter::OnMessageReceived(const IPC::Message& message) {
577 base::AutoLock lock(lock_);
521 DCHECK(channel_); 578 DCHECK(channel_);
522 579
580 if (!enabled_)
581 return MessageErrorHandler(message, "Channel destroyed");
582
523 if (message.should_unblock() || message.is_reply()) 583 if (message.should_unblock() || message.is_reply())
524 return MessageErrorHandler(message, "Unexpected message type"); 584 return MessageErrorHandler(message, "Unexpected message type");
525 585
526 if (message.type() == GpuChannelMsg_Nop::ID) { 586 if (message.type() == GpuChannelMsg_Nop::ID) {
527 IPC::Message* reply = IPC::SyncMessage::GenerateReply(&message); 587 IPC::Message* reply = IPC::SyncMessage::GenerateReply(&message);
528 Send(reply); 588 Send(reply);
529 return true; 589 return true;
530 } 590 }
531 591
532 for (scoped_refptr<IPC::MessageFilter>& filter : channel_filters_) { 592 for (scoped_refptr<IPC::MessageFilter>& filter : channel_filters_) {
533 if (filter->OnMessageReceived(message)) 593 if (filter->OnMessageReceived(message))
534 return true; 594 return true;
535 } 595 }
536 596
537 scoped_refptr<GpuChannelMessageQueue> message_queue = 597 if (message.routing_id() == MSG_ROUTING_CONTROL ||
538 LookupStreamByRoute(message.routing_id()); 598 message.type() == GpuCommandBufferMsg_WaitForTokenInRange::ID ||
599 message.type() == GpuCommandBufferMsg_WaitForGetOffsetInRange::ID) {
600 gpu_channel_->PostHandleOutOfOrderMessage(message);
601 return true;
602 }
539 603
540 if (!message_queue) 604 scoped_refptr<GpuChannelMessageQueue> stream =
541 return MessageErrorHandler(message, "Could not find message queue"); 605 LookupRoute(message.routing_id());
606 if (!stream)
607 return MessageErrorHandler(message, "Could not find route");
542 608
543 if (!message_queue->PushBackMessage(message)) 609 stream->PushBackMessage(message);
544 return MessageErrorHandler(message, "Channel destroyed");
545
546 return true; 610 return true;
547 } 611 }
548 612
549 bool GpuChannelMessageFilter::Send(IPC::Message* message) { 613 bool GpuChannelMessageFilter::Send(IPC::Message* message) {
550 return channel_->Send(message); 614 return channel_->Send(message);
551 } 615 }
552 616
553 scoped_refptr<GpuChannelMessageQueue> 617 scoped_refptr<GpuChannelMessageQueue> GpuChannelMessageFilter::LookupRoute(
554 GpuChannelMessageFilter::LookupStreamByRoute(int32_t route_id) { 618 int32_t route_id) {
555 base::AutoLock lock(routes_lock_); 619 scoped_refptr<GpuChannelMessageQueue> stream;
556 auto it = routes_.find(route_id); 620 auto it = routes_.find(route_id);
557 if (it != routes_.end()) 621 if (it != routes_.end())
558 return it->second; 622 stream = it->second;
559 return nullptr; 623 return stream;
560 } 624 }
561 625
562 bool GpuChannelMessageFilter::MessageErrorHandler(const IPC::Message& message, 626 bool GpuChannelMessageFilter::MessageErrorHandler(const IPC::Message& message,
563 const char* error_msg) { 627 const char* error_msg) {
564 DLOG(ERROR) << error_msg; 628 DLOG(ERROR) << error_msg;
565 if (message.is_sync()) { 629 if (message.is_sync()) {
566 IPC::Message* reply = IPC::SyncMessage::GenerateReply(&message); 630 IPC::Message* reply = IPC::SyncMessage::GenerateReply(&message);
567 reply->set_reply_error(); 631 reply->set_reply_error();
568 Send(reply); 632 Send(reply);
569 } 633 }
570 return true; 634 return true;
571 } 635 }
572 636
573 GpuChannel::GpuChannel(GpuChannelManager* gpu_channel_manager, 637 GpuChannel::GpuChannel(
574 SyncPointManager* sync_point_manager, 638 GpuChannelManager* gpu_channel_manager,
575 GpuWatchdogThread* watchdog, 639 SyncPointManager* sync_point_manager,
576 gl::GLShareGroup* share_group, 640 GpuWatchdogThread* watchdog,
577 gles2::MailboxManager* mailbox, 641 GpuScheduler* scheduler,
578 PreemptionFlag* preempting_flag, 642 scoped_refptr<gl::GLShareGroup> share_group,
579 PreemptionFlag* preempted_flag, 643 scoped_refptr<gles2::MailboxManager> mailbox_manager,
580 base::SingleThreadTaskRunner* task_runner, 644 scoped_refptr<PreemptionFlag> preempting_flag,
581 base::SingleThreadTaskRunner* io_task_runner, 645 scoped_refptr<PreemptionFlag> preemption_flag,
582 int32_t client_id, 646 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
583 uint64_t client_tracing_id, 647 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
584 bool allow_view_command_buffers, 648 int32_t client_id,
585 bool allow_real_time_streams) 649 uint64_t client_tracing_id,
650 bool allow_view_command_buffers,
651 bool allow_real_time_streams)
586 : gpu_channel_manager_(gpu_channel_manager), 652 : gpu_channel_manager_(gpu_channel_manager),
587 sync_point_manager_(sync_point_manager), 653 sync_point_manager_(sync_point_manager),
654 scheduler_(scheduler),
588 unhandled_message_listener_(nullptr), 655 unhandled_message_listener_(nullptr),
589 preempting_flag_(preempting_flag), 656 preempting_flag_(std::move(preempting_flag)),
590 preempted_flag_(preempted_flag), 657 preemption_flag_(std::move(preemption_flag)),
591 client_id_(client_id), 658 client_id_(client_id),
592 client_tracing_id_(client_tracing_id), 659 client_tracing_id_(client_tracing_id),
593 task_runner_(task_runner), 660 task_runner_(std::move(task_runner)),
594 io_task_runner_(io_task_runner), 661 io_task_runner_(std::move(io_task_runner)),
595 share_group_(share_group), 662 share_group_(std::move(share_group)),
596 mailbox_manager_(mailbox), 663 mailbox_manager_(std::move(mailbox_manager)),
597 watchdog_(watchdog), 664 watchdog_(watchdog),
598 allow_view_command_buffers_(allow_view_command_buffers), 665 allow_view_command_buffers_(allow_view_command_buffers),
599 allow_real_time_streams_(allow_real_time_streams), 666 allow_real_time_streams_(allow_real_time_streams) {
600 weak_factory_(this) {
601 DCHECK(gpu_channel_manager); 667 DCHECK(gpu_channel_manager);
602 DCHECK(client_id); 668 DCHECK(client_id);
603 669 filter_ = GpuChannelMessageFilter::Create(this);
604 filter_ = new GpuChannelMessageFilter();
605
606 scoped_refptr<GpuChannelMessageQueue> control_queue =
607 CreateStream(GPU_STREAM_DEFAULT, GpuStreamPriority::HIGH);
608 AddRouteToStream(MSG_ROUTING_CONTROL, GPU_STREAM_DEFAULT);
609 } 670 }
610 671
611 GpuChannel::~GpuChannel() { 672 GpuChannel::~GpuChannel() {
612 // Clear stubs first because of dependencies. 673 // Clear stubs first because of dependencies.
613 stubs_.clear(); 674 stubs_.clear();
614 675
676 filter_->Disable();
677
615 for (auto& kv : streams_) 678 for (auto& kv : streams_)
616 kv.second->Disable(); 679 kv.second->Destroy();
617 680
618 if (preempting_flag_.get()) 681 if (preempting_flag_)
619 preempting_flag_->Reset(); 682 preempting_flag_->Reset();
620 } 683 }
621 684
622 IPC::ChannelHandle GpuChannel::Init(base::WaitableEvent* shutdown_event) { 685 IPC::ChannelHandle GpuChannel::Init(base::WaitableEvent* shutdown_event) {
623 DCHECK(shutdown_event); 686 DCHECK(shutdown_event);
624 DCHECK(!channel_); 687 DCHECK(!channel_);
625 688
626 mojo::MessagePipe pipe; 689 mojo::MessagePipe pipe;
627 channel_ = IPC::SyncChannel::Create(pipe.handle0.release(), 690 channel_ = IPC::SyncChannel::Create(pipe.handle0.release(),
628 IPC::Channel::MODE_SERVER, this, 691 IPC::Channel::MODE_SERVER, this,
629 io_task_runner_, false, shutdown_event); 692 io_task_runner_, false, shutdown_event);
630 693
631 channel_->AddFilter(filter_.get()); 694 channel_->AddFilter(filter_.get());
632 695
633 return pipe.handle1.release(); 696 return pipe.handle1.release();
634 } 697 }
635 698
636 void GpuChannel::SetUnhandledMessageListener(IPC::Listener* listener) { 699 void GpuChannel::SetUnhandledMessageListener(IPC::Listener* listener) {
637 unhandled_message_listener_ = listener; 700 unhandled_message_listener_ = listener;
638 } 701 }
639 702
640 base::WeakPtr<GpuChannel> GpuChannel::AsWeakPtr() {
641 return weak_factory_.GetWeakPtr();
642 }
643
644 base::ProcessId GpuChannel::GetClientPID() const { 703 base::ProcessId GpuChannel::GetClientPID() const {
645 DCHECK_NE(peer_pid_, base::kNullProcessId); 704 DCHECK_NE(peer_pid_, base::kNullProcessId);
646 return peer_pid_; 705 return peer_pid_;
647 } 706 }
648 707
708 base::Callback<bool(void)> GpuChannel::GetPreemptionCallback() const {
709 if (scheduler_) {
710 return base::Bind(&GpuScheduler::ShouldYield, base::Unretained(scheduler_));
711 } else if (preemption_flag_) {
712 return base::Bind(&PreemptionFlag::IsSet,
713 base::RetainedRef(preemption_flag_));
714 }
715 return base::Callback<bool(void)>();
716 }
717
649 uint32_t GpuChannel::GetProcessedOrderNum() const { 718 uint32_t GpuChannel::GetProcessedOrderNum() const {
650 uint32_t processed_order_num = 0; 719 uint32_t processed_order_num = 0;
651 for (auto& kv : streams_) { 720 for (auto& kv : streams_) {
652 processed_order_num = 721 processed_order_num =
653 std::max(processed_order_num, kv.second->GetProcessedOrderNum()); 722 std::max(processed_order_num, kv.second->GetProcessedOrderNum());
654 } 723 }
655 return processed_order_num; 724 return processed_order_num;
656 } 725 }
657 726
658 uint32_t GpuChannel::GetUnprocessedOrderNum() const { 727 uint32_t GpuChannel::GetUnprocessedOrderNum() const {
659 uint32_t unprocessed_order_num = 0; 728 uint32_t unprocessed_order_num = 0;
660 for (auto& kv : streams_) { 729 for (auto& kv : streams_) {
661 unprocessed_order_num = 730 unprocessed_order_num =
662 std::max(unprocessed_order_num, kv.second->GetUnprocessedOrderNum()); 731 std::max(unprocessed_order_num, kv.second->GetUnprocessedOrderNum());
663 } 732 }
664 return unprocessed_order_num; 733 return unprocessed_order_num;
665 } 734 }
666 735
667 bool GpuChannel::OnMessageReceived(const IPC::Message& msg) { 736 bool GpuChannel::OnMessageReceived(const IPC::Message& msg) {
668 // All messages should be pushed to channel_messages_ and handled separately. 737 // All messages should be pushed to channel_messages_ and handled
738 // separately.
669 NOTREACHED(); 739 NOTREACHED();
670 return false; 740 return false;
671 } 741 }
672 742
673 void GpuChannel::OnChannelConnected(int32_t peer_pid) { 743 void GpuChannel::OnChannelConnected(int32_t peer_pid) {
674 peer_pid_ = peer_pid; 744 peer_pid_ = peer_pid;
675 } 745 }
676 746
677 void GpuChannel::OnChannelError() { 747 void GpuChannel::OnChannelError() {
678 gpu_channel_manager_->RemoveChannel(client_id_); 748 gpu_channel_manager_->RemoveChannel(client_id_);
679 } 749 }
680 750
681 bool GpuChannel::Send(IPC::Message* message) { 751 bool GpuChannel::Send(IPC::Message* message) {
682 // The GPU process must never send a synchronous IPC message to the renderer 752 // The GPU process must never send a synchronous IPC message to the renderer
683 // process. This could result in deadlock. 753 // process. This could result in deadlock.
684 DCHECK(!message->is_sync()); 754 DCHECK(!message->is_sync());
685 755
686 DVLOG(1) << "sending message @" << message << " on channel @" << this 756 DVLOG(1) << "sending message @" << message << " on channel @" << this
687 << " with type " << message->type(); 757 << " with type " << message->type();
688 758
689 if (!channel_) { 759 if (!channel_) {
690 delete message; 760 delete message;
691 return false; 761 return false;
692 } 762 }
693 763
694 return channel_->Send(message); 764 return channel_->Send(message);
695 } 765 }
696 766
697 void GpuChannel::OnStreamRescheduled(int32_t stream_id, bool scheduled) { 767 void GpuChannel::ScheduleCommandBuffer(GpuCommandBufferStub* stub) {
698 scoped_refptr<GpuChannelMessageQueue> queue = LookupStream(stream_id); 768 scoped_refptr<GpuChannelMessageQueue> stream =
699 DCHECK(queue); 769 LookupStream(stub->stream_id());
700 queue->OnRescheduled(scheduled); 770 DCHECK(stream);
771 stream->Schedule();
772 }
773
774 void GpuChannel::DescheduleCommandBuffer(GpuCommandBufferStub* stub) {
775 scoped_refptr<GpuChannelMessageQueue> stream =
776 LookupStream(stub->stream_id());
777 DCHECK(stream);
778 stream->Deschedule();
779 }
780
781 scoped_refptr<GpuChannelMessageQueue> GpuChannel::LookupStreamByCommandBufferId(
782 CommandBufferId command_buffer_id) {
783 int32_t channel_id = GpuCommandBufferStub::GetChannelID(command_buffer_id);
784 GpuChannel* channel = gpu_channel_manager_->LookupChannel(channel_id);
785
786 int32_t route_id = GpuCommandBufferStub::GetRouteID(command_buffer_id);
787 GpuCommandBufferStub* stub = channel->LookupCommandBuffer(route_id);
788
789 return channel->LookupStream(stub->stream_id());
701 } 790 }
702 791
703 GpuCommandBufferStub* GpuChannel::LookupCommandBuffer(int32_t route_id) { 792 GpuCommandBufferStub* GpuChannel::LookupCommandBuffer(int32_t route_id) {
704 return stubs_.get(route_id); 793 auto it = stubs_.find(route_id);
794 if (it != stubs_.end())
795 return it->second.get();
796 return nullptr;
705 } 797 }
706 798
707 void GpuChannel::LoseAllContexts() { 799 void GpuChannel::LoseAllContexts() {
708 gpu_channel_manager_->LoseAllContexts(); 800 gpu_channel_manager_->LoseAllContexts();
709 } 801 }
710 802
711 void GpuChannel::MarkAllContextsLost() { 803 void GpuChannel::MarkAllContextsLost() {
712 for (auto& kv : stubs_) 804 for (auto& kv : stubs_)
713 kv.second->MarkContextLost(); 805 kv.second->MarkContextLost();
714 } 806 }
715 807
716 bool GpuChannel::AddRoute(int32_t route_id, 808 bool GpuChannel::AddRoute(int32_t route_id,
717 int32_t stream_id, 809 int32_t stream_id,
718 IPC::Listener* listener) { 810 IPC::Listener* listener) {
719 if (router_.AddRoute(route_id, listener)) { 811 if (router_.AddRoute(route_id, listener)) {
720 AddRouteToStream(route_id, stream_id); 812 scoped_refptr<GpuChannelMessageQueue> stream = LookupStream(stream_id);
813 filter_->AddRoute(route_id, stream);
814 stream->OnRouteAdded();
721 return true; 815 return true;
722 } 816 }
723 return false; 817 return false;
724 } 818 }
725 819
726 void GpuChannel::RemoveRoute(int32_t route_id) { 820 void GpuChannel::RemoveRoute(int32_t route_id) {
727 router_.RemoveRoute(route_id); 821 router_.RemoveRoute(route_id);
728 RemoveRouteFromStream(route_id); 822 scoped_refptr<GpuChannelMessageQueue> stream = filter_->RemoveRoute(route_id);
823 stream->OnRouteRemoved();
824 if (stream->NumRoutes() == 0) {
825 stream->Destroy();
826 streams_.erase(stream->stream_id());
827 }
729 } 828 }
730 829
731 bool GpuChannel::OnControlMessageReceived(const IPC::Message& msg) { 830 bool GpuChannel::OnControlMessageReceived(const IPC::Message& msg) {
732 bool handled = true; 831 bool handled = true;
733 IPC_BEGIN_MESSAGE_MAP(GpuChannel, msg) 832 IPC_BEGIN_MESSAGE_MAP(GpuChannel, msg)
734 IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateCommandBuffer, 833 IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateCommandBuffer,
735 OnCreateCommandBuffer) 834 OnCreateCommandBuffer)
736 IPC_MESSAGE_HANDLER(GpuChannelMsg_DestroyCommandBuffer, 835 IPC_MESSAGE_HANDLER(GpuChannelMsg_DestroyCommandBuffer,
737 OnDestroyCommandBuffer) 836 OnDestroyCommandBuffer)
738 IPC_MESSAGE_HANDLER(GpuChannelMsg_GetDriverBugWorkArounds, 837 IPC_MESSAGE_HANDLER(GpuChannelMsg_GetDriverBugWorkArounds,
739 OnGetDriverBugWorkArounds) 838 OnGetDriverBugWorkArounds)
740 IPC_MESSAGE_UNHANDLED(handled = false) 839 IPC_MESSAGE_UNHANDLED(handled = false)
741 IPC_END_MESSAGE_MAP() 840 IPC_END_MESSAGE_MAP()
742 return handled; 841 return handled;
743 } 842 }
744 843
745 scoped_refptr<SyncPointOrderData> GpuChannel::GetSyncPointOrderData( 844 scoped_refptr<SyncPointOrderData> GpuChannel::GetSyncPointOrderData(
746 int32_t stream_id) { 845 int32_t stream_id) {
747 auto it = streams_.find(stream_id); 846 auto it = streams_.find(stream_id);
748 DCHECK(it != streams_.end()); 847 DCHECK(it != streams_.end());
749 DCHECK(it->second); 848 DCHECK(it->second);
750 return it->second->GetSyncPointOrderData(); 849 return it->second->GetSyncPointOrderData();
751 } 850 }
752 851
753 void GpuChannel::PostHandleMessage( 852 void GpuChannel::PostHandleMessageOnStream(
754 const scoped_refptr<GpuChannelMessageQueue>& queue) { 853 scoped_refptr<GpuChannelMessageQueue> stream) {
755 task_runner_->PostTask(FROM_HERE, 854 task_runner_->PostTask(
756 base::Bind(&GpuChannel::HandleMessage, 855 FROM_HERE,
757 weak_factory_.GetWeakPtr(), queue)); 856 base::Bind(&GpuChannel::HandleMessageOnStream, AsWeakPtr(), stream));
758 } 857 }
759 858
760 void GpuChannel::PostHandleOutOfOrderMessage(const IPC::Message& msg) { 859 void GpuChannel::HandleMessageOnStream(
761 task_runner_->PostTask(FROM_HERE, 860 scoped_refptr<GpuChannelMessageQueue> stream) {
762 base::Bind(&GpuChannel::HandleOutOfOrderMessage, 861 const GpuChannelMessage* msg_wrapper = stream->BeginMessageProcessing();
763 weak_factory_.GetWeakPtr(), msg)); 862 if (!msg_wrapper)
764 }
765
766 void GpuChannel::HandleMessage(
767 const scoped_refptr<GpuChannelMessageQueue>& message_queue) {
768 const GpuChannelMessage* channel_msg =
769 message_queue->BeginMessageProcessing();
770 if (!channel_msg)
771 return; 863 return;
772 864
773 const IPC::Message& msg = channel_msg->message; 865 const IPC::Message& msg = msg_wrapper->message;
774 int32_t routing_id = msg.routing_id(); 866 GpuCommandBufferStub* stub = LookupCommandBuffer(msg.routing_id());
775 GpuCommandBufferStub* stub = stubs_.get(routing_id);
776
777 DCHECK(!stub || stub->IsScheduled()); 867 DCHECK(!stub || stub->IsScheduled());
778
779 DVLOG(1) << "received message @" << &msg << " on channel @" << this 868 DVLOG(1) << "received message @" << &msg << " on channel @" << this
780 << " with type " << msg.type(); 869 << " with type " << msg.type();
781 870
782 HandleMessageHelper(msg); 871 HandleMessageHelper(msg);
783 872
784 // If we get descheduled or yield while processing a message. 873 // If we get descheduled or preempted while processing a message.
785 if ((stub && stub->HasUnprocessedCommands()) || 874 if ((stub && stub->HasUnprocessedCommands()) || !stream->IsScheduled()) {
786 !message_queue->IsScheduled()) {
787 DCHECK((uint32_t)GpuCommandBufferMsg_AsyncFlush::ID == msg.type() || 875 DCHECK((uint32_t)GpuCommandBufferMsg_AsyncFlush::ID == msg.type() ||
788 (uint32_t)GpuCommandBufferMsg_WaitSyncToken::ID == msg.type()); 876 (uint32_t)GpuCommandBufferMsg_WaitSyncToken::ID == msg.type());
789 message_queue->PauseMessageProcessing(); 877 stream->PauseMessageProcessing();
790 } else { 878 } else {
791 message_queue->FinishMessageProcessing(); 879 stream->FinishMessageProcessing();
792 } 880 }
793 } 881 }
794 882
883 void GpuChannel::PostHandleOutOfOrderMessage(const IPC::Message& msg) {
884 task_runner_->PostTask(
885 FROM_HERE,
886 base::Bind(&GpuChannel::HandleOutOfOrderMessage, AsWeakPtr(), msg));
887 }
888
889 void GpuChannel::HandleOutOfOrderMessage(const IPC::Message& msg) {
890 HandleMessageHelper(msg);
891 }
892
795 void GpuChannel::HandleMessageHelper(const IPC::Message& msg) { 893 void GpuChannel::HandleMessageHelper(const IPC::Message& msg) {
796 int32_t routing_id = msg.routing_id(); 894 int32_t routing_id = msg.routing_id();
797
798 bool handled = false; 895 bool handled = false;
799 if (routing_id == MSG_ROUTING_CONTROL) { 896 if (routing_id == MSG_ROUTING_CONTROL) {
800 handled = OnControlMessageReceived(msg); 897 handled = OnControlMessageReceived(msg);
801 } else { 898 } else {
802 handled = router_.RouteMessage(msg); 899 handled = router_.RouteMessage(msg);
803 } 900 }
804 901
805 if (!handled && unhandled_message_listener_) 902 if (!handled && unhandled_message_listener_)
806 handled = unhandled_message_listener_->OnMessageReceived(msg); 903 handled = unhandled_message_listener_->OnMessageReceived(msg);
807 904
808 // Respond to sync messages even if router failed to route. 905 // Respond to sync messages even if router failed to route.
809 if (!handled && msg.is_sync()) { 906 if (!handled && msg.is_sync()) {
810 IPC::Message* reply = IPC::SyncMessage::GenerateReply(&msg); 907 IPC::Message* reply = IPC::SyncMessage::GenerateReply(&msg);
811 reply->set_reply_error(); 908 reply->set_reply_error();
812 Send(reply); 909 Send(reply);
813 } 910 }
814 } 911 }
815 912
816 void GpuChannel::HandleOutOfOrderMessage(const IPC::Message& msg) {
817 HandleMessageHelper(msg);
818 }
819
820 void GpuChannel::HandleMessageForTesting(const IPC::Message& msg) {
821 HandleMessageHelper(msg);
822 }
823
824 scoped_refptr<GpuChannelMessageQueue> GpuChannel::CreateStream( 913 scoped_refptr<GpuChannelMessageQueue> GpuChannel::CreateStream(
825 int32_t stream_id, 914 int32_t stream_id,
826 GpuStreamPriority stream_priority) { 915 GpuStreamPriority stream_priority) {
827 DCHECK(streams_.find(stream_id) == streams_.end()); 916 return GpuChannelMessageQueue::Create(
828 scoped_refptr<GpuChannelMessageQueue> queue = GpuChannelMessageQueue::Create( 917 stream_id, stream_priority, this, task_runner_, io_task_runner_,
829 stream_id, stream_priority, this, io_task_runner_, 918 scheduler_, preempting_flag_, preemption_flag_, sync_point_manager_);
830 (stream_id == GPU_STREAM_DEFAULT) ? preempting_flag_ : nullptr,
831 preempted_flag_, sync_point_manager_);
832 streams_.insert(std::make_pair(stream_id, queue));
833 streams_to_num_routes_.insert(std::make_pair(stream_id, 0));
834 return queue;
835 } 919 }
836 920
837 scoped_refptr<GpuChannelMessageQueue> GpuChannel::LookupStream( 921 scoped_refptr<GpuChannelMessageQueue> GpuChannel::LookupStream(
838 int32_t stream_id) { 922 int32_t stream_id) {
839 auto stream_it = streams_.find(stream_id); 923 auto it = streams_.find(stream_id);
840 if (stream_it != streams_.end()) 924 if (it != streams_.end())
841 return stream_it->second; 925 return it->second;
842 return nullptr; 926 return nullptr;
843 } 927 }
844 928
845 void GpuChannel::DestroyStreamIfNecessary(
846 const scoped_refptr<GpuChannelMessageQueue>& queue) {
847 int32_t stream_id = queue->stream_id();
848 if (streams_to_num_routes_[stream_id] == 0) {
849 queue->Disable();
850 streams_to_num_routes_.erase(stream_id);
851 streams_.erase(stream_id);
852 }
853 }
854
855 void GpuChannel::AddRouteToStream(int32_t route_id, int32_t stream_id) {
856 DCHECK(streams_.find(stream_id) != streams_.end());
857 DCHECK(routes_to_streams_.find(route_id) == routes_to_streams_.end());
858 streams_to_num_routes_[stream_id]++;
859 routes_to_streams_.insert(std::make_pair(route_id, stream_id));
860 filter_->AddRoute(route_id, streams_[stream_id]);
861 }
862
863 void GpuChannel::RemoveRouteFromStream(int32_t route_id) {
864 DCHECK(routes_to_streams_.find(route_id) != routes_to_streams_.end());
865 int32_t stream_id = routes_to_streams_[route_id];
866 DCHECK(streams_.find(stream_id) != streams_.end());
867 routes_to_streams_.erase(route_id);
868 streams_to_num_routes_[stream_id]--;
869 filter_->RemoveRoute(route_id);
870 DestroyStreamIfNecessary(streams_[stream_id]);
871 }
872
873 #if defined(OS_ANDROID) 929 #if defined(OS_ANDROID)
874 const GpuCommandBufferStub* GpuChannel::GetOneStub() const { 930 const GpuCommandBufferStub* GpuChannel::GetOneStub() const {
875 for (const auto& kv : stubs_) { 931 for (const auto& kv : stubs_) {
876 const GpuCommandBufferStub* stub = kv.second; 932 const GpuCommandBufferStub* stub = kv.second.get();
877 if (stub->decoder() && !stub->decoder()->WasContextLost()) 933 if (stub->decoder() && !stub->decoder()->WasContextLost())
878 return stub; 934 return stub;
879 } 935 }
880 return nullptr; 936 return nullptr;
881 } 937 }
882 #endif 938 #endif
883 939
884 void GpuChannel::OnCreateCommandBuffer( 940 void GpuChannel::OnCreateCommandBuffer(
885 const GPUCreateCommandBufferConfig& init_params, 941 const GPUCreateCommandBufferConfig& init_params,
886 int32_t route_id, 942 int32_t route_id,
887 base::SharedMemoryHandle shared_state_handle, 943 base::SharedMemoryHandle shared_state_handle,
888 bool* result, 944 bool* result,
889 gpu::Capabilities* capabilities) { 945 gpu::Capabilities* capabilities) {
890 TRACE_EVENT2("gpu", "GpuChannel::OnCreateCommandBuffer", "route_id", route_id, 946 TRACE_EVENT2("gpu", "GpuChannel::OnCreateCommandBuffer", "route_id", route_id,
891 "offscreen", (init_params.surface_handle == kNullSurfaceHandle)); 947 "offscreen", (init_params.surface_handle == kNullSurfaceHandle));
892 std::unique_ptr<base::SharedMemory> shared_state_shm( 948 std::unique_ptr<base::SharedMemory> shared_state_shm(
893 new base::SharedMemory(shared_state_handle, false)); 949 new base::SharedMemory(shared_state_handle, false));
894 std::unique_ptr<GpuCommandBufferStub> stub = 950 GpuCommandBufferStub* stub =
895 CreateCommandBuffer(init_params, route_id, std::move(shared_state_shm)); 951 CreateCommandBuffer(init_params, route_id, std::move(shared_state_shm));
896 if (stub) { 952 if (stub) {
897 *result = true; 953 *result = true;
898 *capabilities = stub->decoder()->GetCapabilities(); 954 *capabilities = stub->decoder()->GetCapabilities();
899 stubs_.set(route_id, std::move(stub));
900 } else { 955 } else {
901 *result = false; 956 *result = false;
902 *capabilities = gpu::Capabilities(); 957 *capabilities = gpu::Capabilities();
903 } 958 }
904 } 959 }
905 960
906 std::unique_ptr<GpuCommandBufferStub> GpuChannel::CreateCommandBuffer( 961 GpuCommandBufferStub* GpuChannel::CreateCommandBuffer(
907 const GPUCreateCommandBufferConfig& init_params, 962 const GPUCreateCommandBufferConfig& init_params,
908 int32_t route_id, 963 int32_t route_id,
909 std::unique_ptr<base::SharedMemory> shared_state_shm) { 964 std::unique_ptr<base::SharedMemory> shared_state_shm) {
910 if (init_params.surface_handle != kNullSurfaceHandle && 965 if (init_params.surface_handle != kNullSurfaceHandle &&
911 !allow_view_command_buffers_) { 966 !allow_view_command_buffers_) {
912 DLOG(ERROR) << "GpuChannel::CreateCommandBuffer(): attempt to create a " 967 DLOG(ERROR) << "GpuChannel::CreateCommandBuffer(): attempt to create a "
913 "view context on a non-priviledged channel"; 968 "view context on a non-priviledged channel";
914 return nullptr; 969 return nullptr;
915 } 970 }
916 971
917 int32_t share_group_id = init_params.share_group_id; 972 int32_t share_group_id = init_params.share_group_id;
918 GpuCommandBufferStub* share_group = stubs_.get(share_group_id); 973 GpuCommandBufferStub* share_group = LookupCommandBuffer(share_group_id);
919 974
920 if (!share_group && share_group_id != MSG_ROUTING_NONE) { 975 if (!share_group && share_group_id != MSG_ROUTING_NONE) {
921 DLOG(ERROR) 976 DLOG(ERROR) << "GpuChannel::CreateCommandBuffer(): invalid share group id";
922 << "GpuChannel::CreateCommandBuffer(): invalid share group id";
923 return nullptr; 977 return nullptr;
924 } 978 }
925 979
926 int32_t stream_id = init_params.stream_id; 980 int32_t stream_id = init_params.stream_id;
927 if (share_group && stream_id != share_group->stream_id()) { 981 if (share_group && stream_id != share_group->stream_id()) {
928 DLOG(ERROR) << "GpuChannel::CreateCommandBuffer(): stream id does not " 982 DLOG(ERROR) << "GpuChannel::CreateCommandBuffer(): stream id does not "
929 "match share group stream id"; 983 "match share group stream id";
930 return nullptr; 984 return nullptr;
931 } 985 }
932 986
(...skipping 12 matching lines...) Expand all
945 "not initialized"; 999 "not initialized";
946 return nullptr; 1000 return nullptr;
947 } 1001 }
948 1002
949 if (share_group && share_group->decoder()->WasContextLost()) { 1003 if (share_group && share_group->decoder()->WasContextLost()) {
950 DLOG(ERROR) << "GpuChannel::CreateCommandBuffer(): shared context was " 1004 DLOG(ERROR) << "GpuChannel::CreateCommandBuffer(): shared context was "
951 "already lost"; 1005 "already lost";
952 return nullptr; 1006 return nullptr;
953 } 1007 }
954 1008
955 scoped_refptr<GpuChannelMessageQueue> queue = LookupStream(stream_id); 1009 scoped_refptr<GpuChannelMessageQueue> stream = LookupStream(stream_id);
956 if (!queue) 1010 if (!stream) {
957 queue = CreateStream(stream_id, stream_priority); 1011 stream = CreateStream(stream_id, stream_priority);
1012 streams_.insert(std::make_pair(stream_id, stream));
1013 }
958 1014
959 std::unique_ptr<GpuCommandBufferStub> stub(GpuCommandBufferStub::Create( 1015 std::unique_ptr<GpuCommandBufferStub> stub(GpuCommandBufferStub::Create(
960 this, share_group, init_params, route_id, std::move(shared_state_shm))); 1016 this, share_group, init_params, route_id, std::move(shared_state_shm)));
961 1017
962 if (!stub) { 1018 if (!router_.AddRoute(route_id, stub.get())) {
963 DestroyStreamIfNecessary(queue); 1019 DLOG(ERROR) << "GpuChannel::CreateCommandBuffer(): failed to add route";
1020 if (stream->NumRoutes() == 0) {
1021 stream->Destroy();
1022 streams_.erase(stream_id);
1023 }
964 return nullptr; 1024 return nullptr;
965 } 1025 }
966 1026
967 if (!AddRoute(route_id, stream_id, stub.get())) { 1027 filter_->AddRoute(route_id, stream);
968 DestroyStreamIfNecessary(queue); 1028 stream->OnRouteAdded();
969 DLOG(ERROR) << "GpuChannel::CreateCommandBuffer(): failed to add route";
970 return nullptr;
971 }
972 1029
973 return stub; 1030 GpuCommandBufferStub* ret_stub = stub.get();
1031 stubs_.insert(std::make_pair(route_id, std::move(stub)));
1032
1033 return ret_stub;
974 } 1034 }
975 1035
976 void GpuChannel::OnDestroyCommandBuffer(int32_t route_id) { 1036 void GpuChannel::OnDestroyCommandBuffer(int32_t route_id) {
977 TRACE_EVENT1("gpu", "GpuChannel::OnDestroyCommandBuffer", 1037 TRACE_EVENT1("gpu", "GpuChannel::OnDestroyCommandBuffer", "route_id",
978 "route_id", route_id); 1038 route_id);
979 1039 auto it = stubs_.find(route_id);
980 std::unique_ptr<GpuCommandBufferStub> stub = stubs_.take_and_erase(route_id); 1040 if (it != stubs_.end()) {
981 // In case the renderer is currently blocked waiting for a sync reply from the 1041 std::unique_ptr<GpuCommandBufferStub> stub(std::move(it->second));
982 // stub, we need to make sure to reschedule the correct stream here. 1042 stubs_.erase(it);
983 if (stub && !stub->IsScheduled()) { 1043 // In case the renderer is currently blocked waiting for a sync reply from
984 // This stub won't get a chance to reschedule the stream so do that now. 1044 // the stub, we need to make sure to reschedule the correct stream here.
985 OnStreamRescheduled(stub->stream_id(), true); 1045 ScheduleCommandBuffer(stub.get());
986 } 1046 }
987
988 RemoveRoute(route_id); 1047 RemoveRoute(route_id);
989 } 1048 }
990 1049
991 void GpuChannel::OnGetDriverBugWorkArounds( 1050 void GpuChannel::OnGetDriverBugWorkArounds(
992 std::vector<std::string>* gpu_driver_bug_workarounds) { 1051 std::vector<std::string>* gpu_driver_bug_workarounds) {
993 gpu_driver_bug_workarounds->clear(); 1052 gpu_driver_bug_workarounds->clear();
994 #define GPU_OP(type, name) \ 1053 #define GPU_OP(type, name) \
995 if (gpu_channel_manager_->gpu_driver_bug_workarounds().name) \ 1054 if (gpu_channel_manager_->gpu_driver_bug_workarounds().name) \
996 gpu_driver_bug_workarounds->push_back(#name); 1055 gpu_driver_bug_workarounds->push_back(#name);
997 GPU_DRIVER_BUG_WORKAROUNDS(GPU_OP) 1056 GPU_DRIVER_BUG_WORKAROUNDS(GPU_OP)
998 #undef GPU_OP 1057 #undef GPU_OP
999 } 1058 }
1000 1059
1001 void GpuChannel::CacheShader(const std::string& key, 1060 void GpuChannel::CacheShader(const std::string& key,
1002 const std::string& shader) { 1061 const std::string& shader) {
1003 gpu_channel_manager_->delegate()->StoreShaderToDisk(client_id_, key, shader); 1062 gpu_channel_manager_->delegate()->StoreShaderToDisk(client_id_, key, shader);
1004 } 1063 }
1005 1064
1006 void GpuChannel::AddFilter(IPC::MessageFilter* filter) { 1065 void GpuChannel::AddFilter(IPC::MessageFilter* filter) {
1007 io_task_runner_->PostTask( 1066 io_task_runner_->PostTask(
1008 FROM_HERE, base::Bind(&GpuChannelMessageFilter::AddChannelFilter, 1067 FROM_HERE,
1009 filter_, make_scoped_refptr(filter))); 1068 base::Bind(&GpuChannelMessageFilter::AddChannelFilter,
1069 base::RetainedRef(filter_), make_scoped_refptr(filter)));
1010 } 1070 }
1011 1071
1012 void GpuChannel::RemoveFilter(IPC::MessageFilter* filter) { 1072 void GpuChannel::RemoveFilter(IPC::MessageFilter* filter) {
1013 io_task_runner_->PostTask( 1073 io_task_runner_->PostTask(
1014 FROM_HERE, base::Bind(&GpuChannelMessageFilter::RemoveChannelFilter, 1074 FROM_HERE,
1015 filter_, make_scoped_refptr(filter))); 1075 base::Bind(&GpuChannelMessageFilter::RemoveChannelFilter,
1076 base::RetainedRef(filter_), make_scoped_refptr(filter)));
1016 } 1077 }
1017 1078
1018 uint64_t GpuChannel::GetMemoryUsage() { 1079 uint64_t GpuChannel::GetMemoryUsage() {
1019 // Collect the unique memory trackers in use by the |stubs_|. 1080 // Collect the unique memory trackers in use by the |stubs_|.
1020 std::set<gles2::MemoryTracker*> unique_memory_trackers; 1081 std::set<gles2::MemoryTracker*> unique_memory_trackers;
1021 for (auto& kv : stubs_) 1082 for (auto& kv : stubs_)
1022 unique_memory_trackers.insert(kv.second->GetMemoryTracker()); 1083 unique_memory_trackers.insert(kv.second->GetMemoryTracker());
1023 1084
1024 // Sum the memory usage for all unique memory trackers. 1085 // Sum the memory usage for all unique memory trackers.
1025 uint64_t size = 0; 1086 uint64_t size = 0;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1057 1118
1058 return manager->gpu_memory_buffer_factory() 1119 return manager->gpu_memory_buffer_factory()
1059 ->AsImageFactory() 1120 ->AsImageFactory()
1060 ->CreateImageForGpuMemoryBuffer(handle, size, format, internalformat, 1121 ->CreateImageForGpuMemoryBuffer(handle, size, format, internalformat,
1061 client_id_, surface_handle); 1122 client_id_, surface_handle);
1062 } 1123 }
1063 } 1124 }
1064 } 1125 }
1065 1126
1066 } // namespace gpu 1127 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/ipc/service/gpu_channel.h ('k') | gpu/ipc/service/gpu_channel_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698