OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/in_process_command_buffer.h" | 5 #include "gpu/ipc/in_process_command_buffer.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <queue> | 10 #include <queue> |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 } | 177 } |
178 return program_cache_.get(); | 178 return program_cache_.get(); |
179 } | 179 } |
180 | 180 |
181 InProcessCommandBuffer::InProcessCommandBuffer( | 181 InProcessCommandBuffer::InProcessCommandBuffer( |
182 const scoped_refptr<Service>& service) | 182 const scoped_refptr<Service>& service) |
183 : command_buffer_id_(CommandBufferId::FromUnsafeValue( | 183 : command_buffer_id_(CommandBufferId::FromUnsafeValue( |
184 g_next_command_buffer_id.GetNext() + 1)), | 184 g_next_command_buffer_id.GetNext() + 1)), |
185 delayed_work_pending_(false), | 185 delayed_work_pending_(false), |
186 image_factory_(nullptr), | 186 image_factory_(nullptr), |
| 187 latency_info_(base::MakeUnique<std::vector<ui::LatencyInfo>>()), |
187 gpu_control_client_(nullptr), | 188 gpu_control_client_(nullptr), |
188 #if DCHECK_IS_ON() | 189 #if DCHECK_IS_ON() |
189 context_lost_(false), | 190 context_lost_(false), |
190 #endif | 191 #endif |
191 last_put_offset_(-1), | 192 last_put_offset_(-1), |
192 gpu_memory_buffer_manager_(nullptr), | 193 gpu_memory_buffer_manager_(nullptr), |
193 next_fence_sync_release_(1), | 194 next_fence_sync_release_(1), |
194 flushed_fence_sync_release_(0), | 195 flushed_fence_sync_release_(0), |
195 flush_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC, | 196 flush_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
196 base::WaitableEvent::InitialState::NOT_SIGNALED), | 197 base::WaitableEvent::InitialState::NOT_SIGNALED), |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 void InProcessCommandBuffer::ProcessTasksOnGpuThread() { | 525 void InProcessCommandBuffer::ProcessTasksOnGpuThread() { |
525 while (executor_->scheduled()) { | 526 while (executor_->scheduled()) { |
526 base::AutoLock lock(task_queue_lock_); | 527 base::AutoLock lock(task_queue_lock_); |
527 if (task_queue_.empty()) | 528 if (task_queue_.empty()) |
528 break; | 529 break; |
529 GpuTask* task = task_queue_.front().get(); | 530 GpuTask* task = task_queue_.front().get(); |
530 sync_point_order_data_->BeginProcessingOrderNumber(task->order_number); | 531 sync_point_order_data_->BeginProcessingOrderNumber(task->order_number); |
531 task->callback.Run(); | 532 task->callback.Run(); |
532 if (!executor_->scheduled() && !service_->BlockThreadOnWaitSyncToken()) { | 533 if (!executor_->scheduled() && !service_->BlockThreadOnWaitSyncToken()) { |
533 sync_point_order_data_->PauseProcessingOrderNumber(task->order_number); | 534 sync_point_order_data_->PauseProcessingOrderNumber(task->order_number); |
| 535 // Don't pop the task if it was preempted - it may have been preempted, so |
| 536 // we need to execute it again later. |
534 return; | 537 return; |
535 } | 538 } |
536 sync_point_order_data_->FinishProcessingOrderNumber(task->order_number); | 539 sync_point_order_data_->FinishProcessingOrderNumber(task->order_number); |
537 task_queue_.pop(); | 540 task_queue_.pop(); |
538 } | 541 } |
539 } | 542 } |
540 | 543 |
541 CommandBuffer::State InProcessCommandBuffer::GetLastState() { | 544 CommandBuffer::State InProcessCommandBuffer::GetLastState() { |
542 CheckSequencedThread(); | 545 CheckSequencedThread(); |
543 base::AutoLock lock(last_state_lock_); | 546 base::AutoLock lock(last_state_lock_); |
544 return last_state_; | 547 return last_state_; |
545 } | 548 } |
546 | 549 |
547 void InProcessCommandBuffer::UpdateLastStateOnGpuThread() { | 550 void InProcessCommandBuffer::UpdateLastStateOnGpuThread() { |
548 CheckSequencedThread(); | 551 CheckSequencedThread(); |
549 command_buffer_lock_.AssertAcquired(); | 552 command_buffer_lock_.AssertAcquired(); |
550 base::AutoLock lock(last_state_lock_); | 553 base::AutoLock lock(last_state_lock_); |
551 State state = command_buffer_->GetLastState(); | 554 State state = command_buffer_->GetLastState(); |
552 if (state.generation - last_state_.generation < 0x80000000U) | 555 if (state.generation - last_state_.generation < 0x80000000U) |
553 last_state_ = state; | 556 last_state_ = state; |
554 } | 557 } |
555 | 558 |
556 void InProcessCommandBuffer::FlushOnGpuThread(int32_t put_offset) { | 559 void InProcessCommandBuffer::FlushOnGpuThread( |
| 560 int32_t put_offset, |
| 561 std::vector<ui::LatencyInfo>* latency_info) { |
557 CheckSequencedThread(); | 562 CheckSequencedThread(); |
558 ScopedEvent handle_flush(&flush_event_); | 563 ScopedEvent handle_flush(&flush_event_); |
559 base::AutoLock lock(command_buffer_lock_); | 564 base::AutoLock lock(command_buffer_lock_); |
560 | 565 |
| 566 // Need to run the latency callback before Flush(). |
| 567 if (ui::LatencyInfo::Verify(*latency_info, |
| 568 "InProcessCommandBuffer::FlushOnGpuThread") && |
| 569 !latency_info_callback_.is_null()) { |
| 570 if (!latency_info->empty()) { |
| 571 latency_info_callback_.Run(*latency_info); |
| 572 // FlushOnGpuThread task might be preempted and re-executed (see |
| 573 // ProcessTasksOnGpuThread), so clear the |latency_info| to prevent |
| 574 // executing |latency_info_callback_| multiple times with the same data. |
| 575 latency_info->clear(); |
| 576 } |
| 577 } |
| 578 |
561 command_buffer_->Flush(put_offset); | 579 command_buffer_->Flush(put_offset); |
562 // Update state before signaling the flush event. | 580 // Update state before signaling the flush event. |
563 UpdateLastStateOnGpuThread(); | 581 UpdateLastStateOnGpuThread(); |
564 | 582 |
565 // If we've processed all pending commands but still have pending queries, | 583 // If we've processed all pending commands but still have pending queries, |
566 // pump idle work until the query is passed. | 584 // pump idle work until the query is passed. |
567 if (put_offset == command_buffer_->GetLastState().get_offset && | 585 if (put_offset == command_buffer_->GetLastState().get_offset && |
568 (executor_->HasMoreIdleWork() || executor_->HasPendingQueries())) { | 586 (executor_->HasMoreIdleWork() || executor_->HasPendingQueries())) { |
569 ScheduleDelayedWorkOnGpuThread(); | 587 ScheduleDelayedWorkOnGpuThread(); |
570 } | 588 } |
(...skipping 25 matching lines...) Expand all Loading... |
596 void InProcessCommandBuffer::Flush(int32_t put_offset) { | 614 void InProcessCommandBuffer::Flush(int32_t put_offset) { |
597 CheckSequencedThread(); | 615 CheckSequencedThread(); |
598 if (GetLastState().error != gpu::error::kNoError) | 616 if (GetLastState().error != gpu::error::kNoError) |
599 return; | 617 return; |
600 | 618 |
601 if (last_put_offset_ == put_offset) | 619 if (last_put_offset_ == put_offset) |
602 return; | 620 return; |
603 | 621 |
604 last_put_offset_ = put_offset; | 622 last_put_offset_ = put_offset; |
605 base::Closure task = base::Bind(&InProcessCommandBuffer::FlushOnGpuThread, | 623 base::Closure task = base::Bind(&InProcessCommandBuffer::FlushOnGpuThread, |
606 gpu_thread_weak_ptr_, put_offset); | 624 gpu_thread_weak_ptr_, put_offset, |
| 625 base::Owned(latency_info_.release())); |
| 626 latency_info_.reset(new std::vector<ui::LatencyInfo>); |
607 QueueTask(false, task); | 627 QueueTask(false, task); |
608 | 628 |
609 flushed_fence_sync_release_ = next_fence_sync_release_ - 1; | 629 flushed_fence_sync_release_ = next_fence_sync_release_ - 1; |
610 } | 630 } |
611 | 631 |
612 void InProcessCommandBuffer::OrderingBarrier(int32_t put_offset) { | 632 void InProcessCommandBuffer::OrderingBarrier(int32_t put_offset) { |
613 Flush(put_offset); | 633 Flush(put_offset); |
614 } | 634 } |
615 | 635 |
616 CommandBuffer::State InProcessCommandBuffer::WaitForTokenInRange(int32_t start, | 636 CommandBuffer::State InProcessCommandBuffer::WaitForTokenInRange(int32_t start, |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
984 base::Unretained(this), sync_token, WrapCallback(callback))); | 1004 base::Unretained(this), sync_token, WrapCallback(callback))); |
985 } | 1005 } |
986 | 1006 |
987 void InProcessCommandBuffer::WaitSyncTokenHint(const SyncToken& sync_token) {} | 1007 void InProcessCommandBuffer::WaitSyncTokenHint(const SyncToken& sync_token) {} |
988 | 1008 |
989 bool InProcessCommandBuffer::CanWaitUnverifiedSyncToken( | 1009 bool InProcessCommandBuffer::CanWaitUnverifiedSyncToken( |
990 const SyncToken& sync_token) { | 1010 const SyncToken& sync_token) { |
991 return sync_token.namespace_id() == GetNamespaceID(); | 1011 return sync_token.namespace_id() == GetNamespaceID(); |
992 } | 1012 } |
993 | 1013 |
| 1014 void InProcessCommandBuffer::AddLatencyInfo( |
| 1015 const std::vector<ui::LatencyInfo>& latency_info) { |
| 1016 latency_info_->insert(latency_info_->end(), latency_info.begin(), |
| 1017 latency_info.end()); |
| 1018 } |
| 1019 |
994 #if defined(OS_WIN) | 1020 #if defined(OS_WIN) |
995 void InProcessCommandBuffer::DidCreateAcceleratedSurfaceChildWindow( | 1021 void InProcessCommandBuffer::DidCreateAcceleratedSurfaceChildWindow( |
996 SurfaceHandle parent_window, | 1022 SurfaceHandle parent_window, |
997 SurfaceHandle child_window) { | 1023 SurfaceHandle child_window) { |
998 ::SetParent(child_window, parent_window); | 1024 ::SetParent(child_window, parent_window); |
999 } | 1025 } |
1000 #endif | 1026 #endif |
1001 | 1027 |
1002 void InProcessCommandBuffer::DidSwapBuffersComplete( | 1028 void InProcessCommandBuffer::DidSwapBuffersComplete( |
1003 SwapBuffersCompleteParams params) { | 1029 SwapBuffersCompleteParams params) { |
1004 if (!origin_task_runner_) { | 1030 if (!origin_task_runner_) { |
1005 DidSwapBuffersCompleteOnOriginThread(std::move(params)); | 1031 DidSwapBuffersCompleteOnOriginThread(std::move(params)); |
1006 return; | 1032 return; |
1007 } | 1033 } |
1008 origin_task_runner_->PostTask( | 1034 origin_task_runner_->PostTask( |
1009 FROM_HERE, | 1035 FROM_HERE, |
1010 base::Bind(&InProcessCommandBuffer::DidSwapBuffersCompleteOnOriginThread, | 1036 base::Bind(&InProcessCommandBuffer::DidSwapBuffersCompleteOnOriginThread, |
1011 client_thread_weak_ptr_, base::Passed(¶ms))); | 1037 client_thread_weak_ptr_, base::Passed(¶ms))); |
1012 } | 1038 } |
1013 | 1039 |
1014 const gles2::FeatureInfo* InProcessCommandBuffer::GetFeatureInfo() const { | 1040 const gles2::FeatureInfo* InProcessCommandBuffer::GetFeatureInfo() const { |
1015 return context_group_->feature_info(); | 1041 return context_group_->feature_info(); |
1016 } | 1042 } |
1017 | 1043 |
1018 void InProcessCommandBuffer::SetLatencyInfoCallback( | 1044 void InProcessCommandBuffer::SetLatencyInfoCallback( |
1019 const LatencyInfoCallback& callback) { | 1045 const LatencyInfoCallback& callback) { |
1020 // TODO(fsamuel): Implement this. | 1046 latency_info_callback_ = callback; |
1021 } | 1047 } |
1022 | 1048 |
1023 void InProcessCommandBuffer::UpdateVSyncParameters(base::TimeTicks timebase, | 1049 void InProcessCommandBuffer::UpdateVSyncParameters(base::TimeTicks timebase, |
1024 base::TimeDelta interval) { | 1050 base::TimeDelta interval) { |
1025 if (!origin_task_runner_) { | 1051 if (!origin_task_runner_) { |
1026 UpdateVSyncParametersOnOriginThread(timebase, interval); | 1052 UpdateVSyncParametersOnOriginThread(timebase, interval); |
1027 return; | 1053 return; |
1028 } | 1054 } |
1029 origin_task_runner_->PostTask( | 1055 origin_task_runner_->PostTask( |
1030 FROM_HERE, | 1056 FROM_HERE, |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1124 return wrapped_callback; | 1150 return wrapped_callback; |
1125 } | 1151 } |
1126 | 1152 |
1127 InProcessCommandBuffer::GpuTask::GpuTask(const base::Closure& callback, | 1153 InProcessCommandBuffer::GpuTask::GpuTask(const base::Closure& callback, |
1128 uint32_t order_number) | 1154 uint32_t order_number) |
1129 : callback(callback), order_number(order_number) {} | 1155 : callback(callback), order_number(order_number) {} |
1130 | 1156 |
1131 InProcessCommandBuffer::GpuTask::~GpuTask() {} | 1157 InProcessCommandBuffer::GpuTask::~GpuTask() {} |
1132 | 1158 |
1133 } // namespace gpu | 1159 } // namespace gpu |
OLD | NEW |