| 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 "content/common/gpu/gpu_channel.h" | 5 #include "content/common/gpu/gpu_channel.h" |
| 6 | 6 |
| 7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
| 8 #include <windows.h> | 8 #include <windows.h> |
| 9 #endif | 9 #endif |
| 10 | 10 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 // Once we trigger a preemption, the maximum duration that we will wait | 63 // Once we trigger a preemption, the maximum duration that we will wait |
| 64 // before clearing the preemption. | 64 // before clearing the preemption. |
| 65 const int64 kMaxPreemptTimeMs = kVsyncIntervalMs; | 65 const int64 kMaxPreemptTimeMs = kVsyncIntervalMs; |
| 66 | 66 |
| 67 // Stop the preemption once the time for the longest pending IPC drops | 67 // Stop the preemption once the time for the longest pending IPC drops |
| 68 // below this threshold. | 68 // below this threshold. |
| 69 const int64 kStopPreemptThresholdMs = kVsyncIntervalMs; | 69 const int64 kStopPreemptThresholdMs = kVsyncIntervalMs; |
| 70 | 70 |
| 71 } // anonymous namespace | 71 } // anonymous namespace |
| 72 | 72 |
| 73 // Begin order numbers at 1 so 0 can mean no orders. | |
| 74 uint32_t GpuChannelMessageQueue::global_order_counter_ = 1; | |
| 75 | |
| 76 scoped_refptr<GpuChannelMessageQueue> GpuChannelMessageQueue::Create( | 73 scoped_refptr<GpuChannelMessageQueue> GpuChannelMessageQueue::Create( |
| 77 const base::WeakPtr<GpuChannel>& gpu_channel, | 74 const base::WeakPtr<GpuChannel>& gpu_channel, |
| 78 base::SingleThreadTaskRunner* task_runner) { | 75 base::SingleThreadTaskRunner* task_runner) { |
| 79 return new GpuChannelMessageQueue(gpu_channel, task_runner); | 76 return new GpuChannelMessageQueue(gpu_channel, task_runner); |
| 80 } | 77 } |
| 81 | 78 |
| 79 scoped_refptr<gpu::SyncPointClientState> |
| 80 GpuChannelMessageQueue::GetSyncPointClientState() { |
| 81 return sync_point_client_state_; |
| 82 } |
| 83 |
| 82 GpuChannelMessageQueue::GpuChannelMessageQueue( | 84 GpuChannelMessageQueue::GpuChannelMessageQueue( |
| 83 const base::WeakPtr<GpuChannel>& gpu_channel, | 85 const base::WeakPtr<GpuChannel>& gpu_channel, |
| 84 base::SingleThreadTaskRunner* task_runner) | 86 base::SingleThreadTaskRunner* task_runner) |
| 85 : enabled_(true), | 87 : enabled_(true), |
| 86 unprocessed_order_num_(0), | 88 sync_point_client_state_(gpu::SyncPointClientState::Create()), |
| 87 processed_order_num_(0), | |
| 88 gpu_channel_(gpu_channel), | 89 gpu_channel_(gpu_channel), |
| 89 task_runner_(task_runner) {} | 90 task_runner_(task_runner) {} |
| 90 | 91 |
| 91 GpuChannelMessageQueue::~GpuChannelMessageQueue() { | 92 GpuChannelMessageQueue::~GpuChannelMessageQueue() { |
| 92 DCHECK(channel_messages_.empty()); | 93 DCHECK(channel_messages_.empty()); |
| 93 } | 94 } |
| 94 | 95 |
| 95 uint32_t GpuChannelMessageQueue::GetUnprocessedOrderNum() const { | 96 uint32_t GpuChannelMessageQueue::GetUnprocessedOrderNum() const { |
| 96 base::AutoLock auto_lock(channel_messages_lock_); | 97 return sync_point_client_state_->unprocessed_order_num(); |
| 97 return unprocessed_order_num_; | |
| 98 } | 98 } |
| 99 | 99 |
| 100 void GpuChannelMessageQueue::PushBackMessage(const IPC::Message& message) { | 100 uint32_t GpuChannelMessageQueue::GetProcessedOrderNum() const { |
| 101 return sync_point_client_state_->processed_order_num(); |
| 102 } |
| 103 |
| 104 void GpuChannelMessageQueue::PushBackMessage( |
| 105 gpu::SyncPointManager* sync_point_manager, const IPC::Message& message) { |
| 101 base::AutoLock auto_lock(channel_messages_lock_); | 106 base::AutoLock auto_lock(channel_messages_lock_); |
| 102 if (enabled_) | 107 if (enabled_) { |
| 103 PushMessageHelper(make_scoped_ptr(new GpuChannelMessage(message))); | 108 PushMessageHelper(sync_point_manager, |
| 109 make_scoped_ptr(new GpuChannelMessage(message))); |
| 110 } |
| 104 } | 111 } |
| 105 | 112 |
| 106 bool GpuChannelMessageQueue::GenerateSyncPointMessage( | 113 bool GpuChannelMessageQueue::GenerateSyncPointMessage( |
| 107 gpu::SyncPointManager* sync_point_manager, | 114 gpu::SyncPointManager* sync_point_manager, |
| 108 const IPC::Message& message, | 115 const IPC::Message& message, |
| 109 bool retire_sync_point, | 116 bool retire_sync_point, |
| 110 uint32_t* sync_point) { | 117 uint32_t* sync_point) { |
| 111 DCHECK_EQ((uint32_t)GpuCommandBufferMsg_InsertSyncPoint::ID, message.type()); | 118 DCHECK_EQ((uint32_t)GpuCommandBufferMsg_InsertSyncPoint::ID, message.type()); |
| 112 DCHECK(sync_point); | 119 DCHECK(sync_point); |
| 113 base::AutoLock auto_lock(channel_messages_lock_); | 120 base::AutoLock auto_lock(channel_messages_lock_); |
| 114 if (enabled_) { | 121 if (enabled_) { |
| 115 *sync_point = sync_point_manager->GenerateSyncPoint(); | 122 *sync_point = sync_point_manager->GenerateSyncPoint(); |
| 116 | 123 |
| 117 scoped_ptr<GpuChannelMessage> msg(new GpuChannelMessage(message)); | 124 scoped_ptr<GpuChannelMessage> msg(new GpuChannelMessage(message)); |
| 118 msg->retire_sync_point = retire_sync_point; | 125 msg->retire_sync_point = retire_sync_point; |
| 119 msg->sync_point = *sync_point; | 126 msg->sync_point = *sync_point; |
| 120 | 127 |
| 121 PushMessageHelper(msg.Pass()); | 128 PushMessageHelper(sync_point_manager, msg.Pass()); |
| 122 return true; | 129 return true; |
| 123 } | 130 } |
| 124 return false; | 131 return false; |
| 125 } | 132 } |
| 126 | 133 |
| 127 bool GpuChannelMessageQueue::HasQueuedMessages() const { | 134 bool GpuChannelMessageQueue::HasQueuedMessages() const { |
| 128 base::AutoLock auto_lock(channel_messages_lock_); | 135 base::AutoLock auto_lock(channel_messages_lock_); |
| 129 return !channel_messages_.empty(); | 136 return !channel_messages_.empty(); |
| 130 } | 137 } |
| 131 | 138 |
| 132 base::TimeTicks GpuChannelMessageQueue::GetNextMessageTimeTick() const { | 139 base::TimeTicks GpuChannelMessageQueue::GetNextMessageTimeTick() const { |
| 133 base::AutoLock auto_lock(channel_messages_lock_); | 140 base::AutoLock auto_lock(channel_messages_lock_); |
| 134 if (!channel_messages_.empty()) | 141 if (!channel_messages_.empty()) |
| 135 return channel_messages_.front()->time_received; | 142 return channel_messages_.front()->time_received; |
| 136 return base::TimeTicks(); | 143 return base::TimeTicks(); |
| 137 } | 144 } |
| 138 | 145 |
| 139 GpuChannelMessage* GpuChannelMessageQueue::GetNextMessage() const { | 146 GpuChannelMessage* GpuChannelMessageQueue::GetNextMessage() const { |
| 140 base::AutoLock auto_lock(channel_messages_lock_); | 147 base::AutoLock auto_lock(channel_messages_lock_); |
| 141 if (!channel_messages_.empty()) { | 148 if (!channel_messages_.empty()) { |
| 142 DCHECK_GT(channel_messages_.front()->order_number, processed_order_num_); | 149 DCHECK_GT(channel_messages_.front()->order_number, |
| 143 DCHECK_LE(channel_messages_.front()->order_number, unprocessed_order_num_); | 150 sync_point_client_state_->processed_order_num()); |
| 151 DCHECK_LE(channel_messages_.front()->order_number, |
| 152 sync_point_client_state_->unprocessed_order_num()); |
| 153 |
| 144 return channel_messages_.front(); | 154 return channel_messages_.front(); |
| 145 } | 155 } |
| 146 return nullptr; | 156 return nullptr; |
| 147 } | 157 } |
| 148 | 158 |
| 159 void GpuChannelMessageQueue::BeginMessageProcessing( |
| 160 const GpuChannelMessage* msg) { |
| 161 sync_point_client_state_->BeginProcessingOrderNumber(msg->order_number); |
| 162 } |
| 163 |
| 149 bool GpuChannelMessageQueue::MessageProcessed() { | 164 bool GpuChannelMessageQueue::MessageProcessed() { |
| 150 base::AutoLock auto_lock(channel_messages_lock_); | 165 base::AutoLock auto_lock(channel_messages_lock_); |
| 151 DCHECK(!channel_messages_.empty()); | 166 DCHECK(!channel_messages_.empty()); |
| 152 scoped_ptr<GpuChannelMessage> msg(channel_messages_.front()); | 167 scoped_ptr<GpuChannelMessage> msg(channel_messages_.front()); |
| 153 channel_messages_.pop_front(); | 168 channel_messages_.pop_front(); |
| 154 processed_order_num_ = msg->order_number; | 169 sync_point_client_state_->FinishProcessingOrderNumber(msg->order_number); |
| 155 return !channel_messages_.empty(); | 170 return !channel_messages_.empty(); |
| 156 } | 171 } |
| 157 | 172 |
| 158 void GpuChannelMessageQueue::DeleteAndDisableMessages( | 173 void GpuChannelMessageQueue::DeleteAndDisableMessages( |
| 159 GpuChannelManager* gpu_channel_manager) { | 174 GpuChannelManager* gpu_channel_manager) { |
| 160 { | 175 { |
| 161 base::AutoLock auto_lock(channel_messages_lock_); | 176 base::AutoLock auto_lock(channel_messages_lock_); |
| 162 DCHECK(enabled_); | 177 DCHECK(enabled_); |
| 163 enabled_ = false; | 178 enabled_ = false; |
| 164 } | 179 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 179 } | 194 } |
| 180 } | 195 } |
| 181 } | 196 } |
| 182 | 197 |
| 183 void GpuChannelMessageQueue::ScheduleHandleMessage() { | 198 void GpuChannelMessageQueue::ScheduleHandleMessage() { |
| 184 task_runner_->PostTask(FROM_HERE, | 199 task_runner_->PostTask(FROM_HERE, |
| 185 base::Bind(&GpuChannel::HandleMessage, gpu_channel_)); | 200 base::Bind(&GpuChannel::HandleMessage, gpu_channel_)); |
| 186 } | 201 } |
| 187 | 202 |
| 188 void GpuChannelMessageQueue::PushMessageHelper( | 203 void GpuChannelMessageQueue::PushMessageHelper( |
| 204 gpu::SyncPointManager* sync_point_manager, |
| 189 scoped_ptr<GpuChannelMessage> msg) { | 205 scoped_ptr<GpuChannelMessage> msg) { |
| 190 channel_messages_lock_.AssertAcquired(); | 206 channel_messages_lock_.AssertAcquired(); |
| 191 DCHECK(enabled_); | 207 DCHECK(enabled_); |
| 192 | 208 |
| 193 msg->order_number = global_order_counter_++; | 209 msg->order_number = |
| 210 sync_point_client_state_->GenerateUnprocessedOrderNumber( |
| 211 sync_point_manager); |
| 194 msg->time_received = base::TimeTicks::Now(); | 212 msg->time_received = base::TimeTicks::Now(); |
| 195 | 213 |
| 196 unprocessed_order_num_ = msg->order_number; | |
| 197 | |
| 198 bool had_messages = !channel_messages_.empty(); | 214 bool had_messages = !channel_messages_.empty(); |
| 199 channel_messages_.push_back(msg.release()); | 215 channel_messages_.push_back(msg.release()); |
| 200 if (!had_messages) | 216 if (!had_messages) |
| 201 ScheduleHandleMessage(); | 217 ScheduleHandleMessage(); |
| 202 } | 218 } |
| 203 | 219 |
| 204 GpuChannelMessageFilter::GpuChannelMessageFilter( | 220 GpuChannelMessageFilter::GpuChannelMessageFilter( |
| 205 const base::WeakPtr<GpuChannel>& gpu_channel, | 221 const base::WeakPtr<GpuChannel>& gpu_channel, |
| 206 GpuChannelMessageQueue* message_queue, | 222 GpuChannelMessageQueue* message_queue, |
| 207 gpu::SyncPointManager* sync_point_manager, | 223 gpu::SyncPointManager* sync_point_manager, |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 } | 348 } |
| 333 | 349 |
| 334 // Forward all other messages to the GPU Channel. | 350 // Forward all other messages to the GPU Channel. |
| 335 if (!handled) { | 351 if (!handled) { |
| 336 if (message.type() == GpuCommandBufferMsg_WaitForTokenInRange::ID || | 352 if (message.type() == GpuCommandBufferMsg_WaitForTokenInRange::ID || |
| 337 message.type() == GpuCommandBufferMsg_WaitForGetOffsetInRange::ID) { | 353 message.type() == GpuCommandBufferMsg_WaitForGetOffsetInRange::ID) { |
| 338 task_runner_->PostTask(FROM_HERE, | 354 task_runner_->PostTask(FROM_HERE, |
| 339 base::Bind(&GpuChannel::HandleOutOfOrderMessage, | 355 base::Bind(&GpuChannel::HandleOutOfOrderMessage, |
| 340 gpu_channel_, message)); | 356 gpu_channel_, message)); |
| 341 } else { | 357 } else { |
| 342 message_queue_->PushBackMessage(message); | 358 message_queue_->PushBackMessage(sync_point_manager_, message); |
| 343 } | 359 } |
| 344 handled = true; | 360 handled = true; |
| 345 } | 361 } |
| 346 | 362 |
| 347 UpdatePreemptionState(); | 363 UpdatePreemptionState(); |
| 348 return handled; | 364 return handled; |
| 349 } | 365 } |
| 350 | 366 |
| 351 void GpuChannelMessageFilter::OnMessageProcessed() { | 367 void GpuChannelMessageFilter::OnMessageProcessed() { |
| 352 UpdatePreemptionState(); | 368 UpdatePreemptionState(); |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 604 channel_->AddFilter(filter_.get()); | 620 channel_->AddFilter(filter_.get()); |
| 605 | 621 |
| 606 return channel_handle; | 622 return channel_handle; |
| 607 } | 623 } |
| 608 | 624 |
| 609 base::ProcessId GpuChannel::GetClientPID() const { | 625 base::ProcessId GpuChannel::GetClientPID() const { |
| 610 return channel_->GetPeerPID(); | 626 return channel_->GetPeerPID(); |
| 611 } | 627 } |
| 612 | 628 |
| 613 uint32_t GpuChannel::GetProcessedOrderNum() const { | 629 uint32_t GpuChannel::GetProcessedOrderNum() const { |
| 614 return message_queue_->processed_order_num(); | 630 return message_queue_->GetProcessedOrderNum(); |
| 615 } | 631 } |
| 616 | 632 |
| 617 uint32_t GpuChannel::GetUnprocessedOrderNum() const { | 633 uint32_t GpuChannel::GetUnprocessedOrderNum() const { |
| 618 return message_queue_->GetUnprocessedOrderNum(); | 634 return message_queue_->GetUnprocessedOrderNum(); |
| 619 } | 635 } |
| 620 | 636 |
| 621 bool GpuChannel::OnMessageReceived(const IPC::Message& message) { | 637 bool GpuChannel::OnMessageReceived(const IPC::Message& message) { |
| 622 // All messages should be pushed to channel_messages_ and handled separately. | 638 // All messages should be pushed to channel_messages_ and handled separately. |
| 623 NOTREACHED(); | 639 NOTREACHED(); |
| 624 return false; | 640 return false; |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 799 IPC_MESSAGE_HANDLER(GpuChannelMsg_DestroyCommandBuffer, | 815 IPC_MESSAGE_HANDLER(GpuChannelMsg_DestroyCommandBuffer, |
| 800 OnDestroyCommandBuffer) | 816 OnDestroyCommandBuffer) |
| 801 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuMsg_CreateJpegDecoder, | 817 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuMsg_CreateJpegDecoder, |
| 802 OnCreateJpegDecoder) | 818 OnCreateJpegDecoder) |
| 803 IPC_MESSAGE_UNHANDLED(handled = false) | 819 IPC_MESSAGE_UNHANDLED(handled = false) |
| 804 IPC_END_MESSAGE_MAP() | 820 IPC_END_MESSAGE_MAP() |
| 805 DCHECK(handled) << msg.type(); | 821 DCHECK(handled) << msg.type(); |
| 806 return handled; | 822 return handled; |
| 807 } | 823 } |
| 808 | 824 |
| 825 scoped_refptr<gpu::SyncPointClientState> GpuChannel::GetSyncPointClientState() { |
| 826 return message_queue_->GetSyncPointClientState(); |
| 827 } |
| 828 |
| 809 void GpuChannel::HandleMessage() { | 829 void GpuChannel::HandleMessage() { |
| 810 // If we have been preempted by another channel, just post a task to wake up. | 830 // If we have been preempted by another channel, just post a task to wake up. |
| 811 if (preempted_flag_ && preempted_flag_->IsSet()) { | 831 if (preempted_flag_ && preempted_flag_->IsSet()) { |
| 812 ScheduleHandleMessage(); | 832 ScheduleHandleMessage(); |
| 813 return; | 833 return; |
| 814 } | 834 } |
| 815 | 835 |
| 816 GpuChannelMessage* m = message_queue_->GetNextMessage(); | 836 GpuChannelMessage* m = message_queue_->GetNextMessage(); |
| 817 | 837 |
| 818 // TODO(sunnyps): This could be a DCHECK maybe? | 838 // TODO(sunnyps): This could be a DCHECK maybe? |
| 819 if (!m) | 839 if (!m) |
| 820 return; | 840 return; |
| 821 | 841 |
| 822 current_order_num_ = m->order_number; | |
| 823 const IPC::Message& message = m->message; | 842 const IPC::Message& message = m->message; |
| 843 message_queue_->BeginMessageProcessing(m); |
| 824 int32_t routing_id = message.routing_id(); | 844 int32_t routing_id = message.routing_id(); |
| 825 GpuCommandBufferStub* stub = stubs_.get(routing_id); | 845 GpuCommandBufferStub* stub = stubs_.get(routing_id); |
| 826 | 846 |
| 827 DCHECK(!stub || stub->IsScheduled()); | 847 DCHECK(!stub || stub->IsScheduled()); |
| 828 | 848 |
| 829 DVLOG(1) << "received message @" << &message << " on channel @" << this | 849 DVLOG(1) << "received message @" << &message << " on channel @" << this |
| 830 << " with type " << message.type(); | 850 << " with type " << message.type(); |
| 831 | 851 |
| 832 bool handled = false; | 852 bool handled = false; |
| 833 | 853 |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1062 } | 1082 } |
| 1063 } | 1083 } |
| 1064 } | 1084 } |
| 1065 | 1085 |
| 1066 void GpuChannel::HandleUpdateValueState( | 1086 void GpuChannel::HandleUpdateValueState( |
| 1067 unsigned int target, const gpu::ValueState& state) { | 1087 unsigned int target, const gpu::ValueState& state) { |
| 1068 pending_valuebuffer_state_->UpdateState(target, state); | 1088 pending_valuebuffer_state_->UpdateState(target, state); |
| 1069 } | 1089 } |
| 1070 | 1090 |
| 1071 } // namespace content | 1091 } // namespace content |
| OLD | NEW |