OLD | NEW |
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 "base/bind.h" | 5 #include "base/bind.h" |
6 #include "base/bind_helpers.h" | 6 #include "base/bind_helpers.h" |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/hash.h" | 8 #include "base/hash.h" |
9 #include "base/json/json_writer.h" | 9 #include "base/json/json_writer.h" |
10 #include "base/memory/shared_memory.h" | 10 #include "base/memory/shared_memory.h" |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 gpu_preference_(gpu_preference), | 192 gpu_preference_(gpu_preference), |
193 use_virtualized_gl_context_(use_virtualized_gl_context), | 193 use_virtualized_gl_context_(use_virtualized_gl_context), |
194 stream_id_(stream_id), | 194 stream_id_(stream_id), |
195 route_id_(route_id), | 195 route_id_(route_id), |
196 surface_id_(surface_id), | 196 surface_id_(surface_id), |
197 software_(software), | 197 software_(software), |
198 last_flush_count_(0), | 198 last_flush_count_(0), |
199 last_memory_allocation_valid_(false), | 199 last_memory_allocation_valid_(false), |
200 watchdog_(watchdog), | 200 watchdog_(watchdog), |
201 sync_point_wait_count_(0), | 201 sync_point_wait_count_(0), |
202 delayed_work_scheduled_(false), | |
203 previous_processed_num_(0), | 202 previous_processed_num_(0), |
204 active_url_(active_url), | 203 active_url_(active_url), |
205 total_gpu_memory_(0) { | 204 total_gpu_memory_(0) { |
206 active_url_hash_ = base::Hash(active_url.possibly_invalid_spec()); | 205 active_url_hash_ = base::Hash(active_url.possibly_invalid_spec()); |
207 FastSetActiveURL(active_url_, active_url_hash_); | 206 FastSetActiveURL(active_url_, active_url_hash_); |
208 | 207 |
209 gpu::gles2::ContextCreationAttribHelper attrib_parser; | 208 gpu::gles2::ContextCreationAttribHelper attrib_parser; |
210 attrib_parser.Parse(requested_attribs_); | 209 attrib_parser.Parse(requested_attribs_); |
211 | 210 |
212 if (share_group) { | 211 if (share_group) { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 OnSetClientHasMemoryAllocationChangedCallback) | 305 OnSetClientHasMemoryAllocationChangedCallback) |
307 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateImage, OnCreateImage); | 306 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateImage, OnCreateImage); |
308 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyImage, OnDestroyImage); | 307 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyImage, OnDestroyImage); |
309 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateStreamTexture, | 308 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateStreamTexture, |
310 OnCreateStreamTexture) | 309 OnCreateStreamTexture) |
311 IPC_MESSAGE_UNHANDLED(handled = false) | 310 IPC_MESSAGE_UNHANDLED(handled = false) |
312 IPC_END_MESSAGE_MAP() | 311 IPC_END_MESSAGE_MAP() |
313 | 312 |
314 CheckCompleteWaits(); | 313 CheckCompleteWaits(); |
315 | 314 |
| 315 // Ensure that any delayed work that was created will be handled. |
316 if (have_context) { | 316 if (have_context) { |
317 // Ensure that any delayed work that was created will be handled. | 317 if (scheduler_) |
318 ScheduleDelayedWork(kHandleMoreWorkPeriodMs); | 318 scheduler_->ProcessPendingQueries(); |
| 319 ScheduleDelayedWork( |
| 320 base::TimeDelta::FromMilliseconds(kHandleMoreWorkPeriodMs)); |
319 } | 321 } |
320 | 322 |
321 DCHECK(handled); | 323 DCHECK(handled); |
322 return handled; | 324 return handled; |
323 } | 325 } |
324 | 326 |
325 bool GpuCommandBufferStub::Send(IPC::Message* message) { | 327 bool GpuCommandBufferStub::Send(IPC::Message* message) { |
326 return channel_->Send(message); | 328 return channel_->Send(message); |
327 } | 329 } |
328 | 330 |
329 bool GpuCommandBufferStub::IsScheduled() { | 331 bool GpuCommandBufferStub::IsScheduled() { |
330 return (!scheduler_.get() || scheduler_->IsScheduled()); | 332 return (!scheduler_.get() || scheduler_->IsScheduled()); |
331 } | 333 } |
332 | 334 |
333 bool GpuCommandBufferStub::HasMoreWork() { | 335 void GpuCommandBufferStub::PollWork() { |
334 return scheduler_.get() && scheduler_->HasMoreWork(); | 336 // Post another delayed task if we have not yet reached the time at which |
| 337 // we should process delayed work. |
| 338 base::TimeTicks current_time = base::TimeTicks::Now(); |
| 339 DCHECK(!process_delayed_work_time_.is_null()); |
| 340 if (process_delayed_work_time_ > current_time) { |
| 341 task_runner_->PostDelayedTask( |
| 342 FROM_HERE, base::Bind(&GpuCommandBufferStub::PollWork, AsWeakPtr()), |
| 343 process_delayed_work_time_ - current_time); |
| 344 return; |
| 345 } |
| 346 process_delayed_work_time_ = base::TimeTicks(); |
| 347 |
| 348 PerformWork(); |
335 } | 349 } |
336 | 350 |
337 void GpuCommandBufferStub::PollWork() { | 351 void GpuCommandBufferStub::PerformWork() { |
338 TRACE_EVENT0("gpu", "GpuCommandBufferStub::PollWork"); | 352 TRACE_EVENT0("gpu", "GpuCommandBufferStub::PerformWork"); |
339 delayed_work_scheduled_ = false; | 353 |
340 FastSetActiveURL(active_url_, active_url_hash_); | 354 FastSetActiveURL(active_url_, active_url_hash_); |
341 if (decoder_.get() && !MakeCurrent()) | 355 if (decoder_.get() && !MakeCurrent()) |
342 return; | 356 return; |
343 | 357 |
344 if (scheduler_) { | 358 if (scheduler_) { |
345 const uint32_t current_unprocessed_num = | 359 const uint32_t current_unprocessed_num = |
346 channel()->gpu_channel_manager()->UnprocessedOrderNumber(); | 360 channel()->gpu_channel_manager()->UnprocessedOrderNumber(); |
347 // We're idle when no messages were processed or scheduled. | 361 // We're idle when no messages were processed or scheduled. |
348 bool is_idle = (previous_processed_num_ == current_unprocessed_num); | 362 bool is_idle = (previous_processed_num_ == current_unprocessed_num); |
349 if (!is_idle && !last_idle_time_.is_null()) { | 363 if (!is_idle && !last_idle_time_.is_null()) { |
350 base::TimeDelta time_since_idle = | 364 base::TimeDelta time_since_idle = |
351 base::TimeTicks::Now() - last_idle_time_; | 365 base::TimeTicks::Now() - last_idle_time_; |
352 base::TimeDelta max_time_since_idle = | 366 base::TimeDelta max_time_since_idle = |
353 base::TimeDelta::FromMilliseconds(kMaxTimeSinceIdleMs); | 367 base::TimeDelta::FromMilliseconds(kMaxTimeSinceIdleMs); |
354 | 368 |
355 // Force idle when it's been too long since last time we were idle. | 369 // Force idle when it's been too long since last time we were idle. |
356 if (time_since_idle > max_time_since_idle) | 370 if (time_since_idle > max_time_since_idle) |
357 is_idle = true; | 371 is_idle = true; |
358 } | 372 } |
359 | 373 |
360 if (is_idle) { | 374 if (is_idle) { |
361 last_idle_time_ = base::TimeTicks::Now(); | 375 last_idle_time_ = base::TimeTicks::Now(); |
362 scheduler_->PerformIdleWork(); | 376 scheduler_->PerformIdleWork(); |
363 } | 377 } |
| 378 |
| 379 scheduler_->ProcessPendingQueries(); |
364 } | 380 } |
365 ScheduleDelayedWork(kHandleMoreWorkPeriodBusyMs); | 381 |
| 382 ScheduleDelayedWork( |
| 383 base::TimeDelta::FromMilliseconds(kHandleMoreWorkPeriodBusyMs)); |
366 } | 384 } |
367 | 385 |
368 bool GpuCommandBufferStub::HasUnprocessedCommands() { | 386 bool GpuCommandBufferStub::HasUnprocessedCommands() { |
369 if (command_buffer_) { | 387 if (command_buffer_) { |
370 gpu::CommandBuffer::State state = command_buffer_->GetLastState(); | 388 gpu::CommandBuffer::State state = command_buffer_->GetLastState(); |
371 return command_buffer_->GetPutOffset() != state.get_offset && | 389 return command_buffer_->GetPutOffset() != state.get_offset && |
372 !gpu::error::IsError(state.error); | 390 !gpu::error::IsError(state.error); |
373 } | 391 } |
374 return false; | 392 return false; |
375 } | 393 } |
376 | 394 |
377 void GpuCommandBufferStub::ScheduleDelayedWork(int64 delay) { | 395 void GpuCommandBufferStub::ScheduleDelayedWork(base::TimeDelta delay) { |
378 if (!HasMoreWork()) { | 396 bool has_more_work = scheduler_.get() && (scheduler_->HasPendingQueries() || |
| 397 scheduler_->HasMoreIdleWork()); |
| 398 if (!has_more_work) { |
379 last_idle_time_ = base::TimeTicks(); | 399 last_idle_time_ = base::TimeTicks(); |
380 return; | 400 return; |
381 } | 401 } |
382 | 402 |
383 if (delayed_work_scheduled_) | 403 base::TimeTicks current_time = base::TimeTicks::Now(); |
| 404 // |process_delayed_work_time_| is set if processing of delayed work is |
| 405 // already scheduled. Just update the time if already scheduled. |
| 406 if (!process_delayed_work_time_.is_null()) { |
| 407 process_delayed_work_time_ = current_time + delay; |
384 return; | 408 return; |
385 delayed_work_scheduled_ = true; | 409 } |
386 | 410 |
387 // Idle when no messages are processed between now and when | 411 // Idle when no messages are processed between now and when |
388 // PollWork is called. | 412 // PollWork is called. |
389 previous_processed_num_ = | 413 previous_processed_num_ = |
390 channel()->gpu_channel_manager()->ProcessedOrderNumber(); | 414 channel()->gpu_channel_manager()->ProcessedOrderNumber(); |
391 if (last_idle_time_.is_null()) | 415 if (last_idle_time_.is_null()) |
392 last_idle_time_ = base::TimeTicks::Now(); | 416 last_idle_time_ = current_time; |
393 | 417 |
394 // IsScheduled() returns true after passing all unschedule fences | 418 // IsScheduled() returns true after passing all unschedule fences |
395 // and this is when we can start performing idle work. Idle work | 419 // and this is when we can start performing idle work. Idle work |
396 // is done synchronously so we can set delay to 0 and instead poll | 420 // is done synchronously so we can set delay to 0 and instead poll |
397 // for more work at the rate idle work is performed. This also ensures | 421 // for more work at the rate idle work is performed. This also ensures |
398 // that idle work is done as efficiently as possible without any | 422 // that idle work is done as efficiently as possible without any |
399 // unnecessary delays. | 423 // unnecessary delays. |
400 if (scheduler_.get() && | 424 if (scheduler_.get() && |
401 scheduler_->IsScheduled() && | 425 scheduler_->IsScheduled() && |
402 scheduler_->HasMoreIdleWork()) { | 426 scheduler_->HasMoreIdleWork()) { |
403 delay = 0; | 427 delay = base::TimeDelta(); |
404 } | 428 } |
405 | 429 |
| 430 process_delayed_work_time_ = current_time + delay; |
406 task_runner_->PostDelayedTask( | 431 task_runner_->PostDelayedTask( |
407 FROM_HERE, base::Bind(&GpuCommandBufferStub::PollWork, AsWeakPtr()), | 432 FROM_HERE, base::Bind(&GpuCommandBufferStub::PollWork, AsWeakPtr()), |
408 base::TimeDelta::FromMilliseconds(delay)); | 433 delay); |
409 } | 434 } |
410 | 435 |
411 bool GpuCommandBufferStub::MakeCurrent() { | 436 bool GpuCommandBufferStub::MakeCurrent() { |
412 if (decoder_->MakeCurrent()) | 437 if (decoder_->MakeCurrent()) |
413 return true; | 438 return true; |
414 DLOG(ERROR) << "Context lost because MakeCurrent failed."; | 439 DLOG(ERROR) << "Context lost because MakeCurrent failed."; |
415 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason()); | 440 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason()); |
416 command_buffer_->SetParseError(gpu::error::kLostContext); | 441 command_buffer_->SetParseError(gpu::error::kLostContext); |
417 CheckContextLost(); | 442 CheckContextLost(); |
418 return false; | 443 return false; |
(...skipping 759 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1178 result)); | 1203 result)); |
1179 } | 1204 } |
1180 | 1205 |
1181 void GpuCommandBufferStub::SendUpdateVSyncParameters(base::TimeTicks timebase, | 1206 void GpuCommandBufferStub::SendUpdateVSyncParameters(base::TimeTicks timebase, |
1182 base::TimeDelta interval) { | 1207 base::TimeDelta interval) { |
1183 Send(new GpuCommandBufferMsg_UpdateVSyncParameters(route_id_, timebase, | 1208 Send(new GpuCommandBufferMsg_UpdateVSyncParameters(route_id_, timebase, |
1184 interval)); | 1209 interval)); |
1185 } | 1210 } |
1186 | 1211 |
1187 } // namespace content | 1212 } // namespace content |
OLD | NEW |