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 |