Index: content/common/gpu/gpu_channel.cc |
diff --git a/content/common/gpu/gpu_channel.cc b/content/common/gpu/gpu_channel.cc |
index 49d086c26a965392cd863ae0317d90c92ecf71b8..3f7361dc1860ceaf5fe897bf05b093ee20717365 100644 |
--- a/content/common/gpu/gpu_channel.cc |
+++ b/content/common/gpu/gpu_channel.cc |
@@ -68,10 +68,11 @@ const int64 kMaxPreemptTimeMs = kVsyncIntervalMs; |
// below this threshold. |
const int64 kStopPreemptThresholdMs = kVsyncIntervalMs; |
-const uint32_t kOutOfOrderNumber = static_cast<uint32_t>(-1); |
- |
} // anonymous namespace |
+// Begin order numbers at 1 so 0 can mean no orders. |
+uint32_t GpuChannelMessageQueue::global_order_counter_ = 1; |
+ |
scoped_refptr<GpuChannelMessageQueue> GpuChannelMessageQueue::Create( |
const base::WeakPtr<GpuChannel>& gpu_channel, |
base::SingleThreadTaskRunner* task_runner) { |
@@ -89,7 +90,6 @@ GpuChannelMessageQueue::GpuChannelMessageQueue( |
GpuChannelMessageQueue::~GpuChannelMessageQueue() { |
DCHECK(channel_messages_.empty()); |
- DCHECK(out_of_order_messages_.empty()); |
} |
uint32_t GpuChannelMessageQueue::GetUnprocessedOrderNum() const { |
@@ -97,18 +97,14 @@ uint32_t GpuChannelMessageQueue::GetUnprocessedOrderNum() const { |
return unprocessed_order_num_; |
} |
-void GpuChannelMessageQueue::PushBackMessage(uint32_t order_number, |
- const IPC::Message& message) { |
+void GpuChannelMessageQueue::PushBackMessage(const IPC::Message& message) { |
base::AutoLock auto_lock(channel_messages_lock_); |
- if (enabled_) { |
- PushMessageHelper( |
- make_scoped_ptr(new GpuChannelMessage(order_number, message))); |
- } |
+ if (enabled_) |
+ PushMessageHelper(make_scoped_ptr(new GpuChannelMessage(message))); |
} |
bool GpuChannelMessageQueue::GenerateSyncPointMessage( |
gpu::SyncPointManager* sync_point_manager, |
- uint32_t order_number, |
const IPC::Message& message, |
bool retire_sync_point, |
uint32_t* sync_point) { |
@@ -118,8 +114,7 @@ bool GpuChannelMessageQueue::GenerateSyncPointMessage( |
if (enabled_) { |
*sync_point = sync_point_manager->GenerateSyncPoint(); |
- scoped_ptr<GpuChannelMessage> msg( |
- new GpuChannelMessage(order_number, message)); |
+ scoped_ptr<GpuChannelMessage> msg(new GpuChannelMessage(message)); |
msg->retire_sync_point = retire_sync_point; |
msg->sync_point = *sync_point; |
@@ -131,56 +126,33 @@ bool GpuChannelMessageQueue::GenerateSyncPointMessage( |
bool GpuChannelMessageQueue::HasQueuedMessages() const { |
base::AutoLock auto_lock(channel_messages_lock_); |
- return HasQueuedMessagesHelper(); |
+ return !channel_messages_.empty(); |
} |
base::TimeTicks GpuChannelMessageQueue::GetNextMessageTimeTick() const { |
base::AutoLock auto_lock(channel_messages_lock_); |
- |
- base::TimeTicks next_message_tick; |
if (!channel_messages_.empty()) |
- next_message_tick = channel_messages_.front()->time_received; |
- |
- base::TimeTicks next_out_of_order_tick; |
- if (!out_of_order_messages_.empty()) |
- next_out_of_order_tick = out_of_order_messages_.front()->time_received; |
- |
- if (next_message_tick.is_null()) |
- return next_out_of_order_tick; |
- else if (next_out_of_order_tick.is_null()) |
- return next_message_tick; |
- else |
- return std::min(next_message_tick, next_out_of_order_tick); |
+ return channel_messages_.front()->time_received; |
+ return base::TimeTicks(); |
} |
GpuChannelMessage* GpuChannelMessageQueue::GetNextMessage() const { |
base::AutoLock auto_lock(channel_messages_lock_); |
- if (!out_of_order_messages_.empty()) { |
- DCHECK_EQ(out_of_order_messages_.front()->order_number, kOutOfOrderNumber); |
- return out_of_order_messages_.front(); |
- } else if (!channel_messages_.empty()) { |
+ if (!channel_messages_.empty()) { |
DCHECK_GT(channel_messages_.front()->order_number, processed_order_num_); |
DCHECK_LE(channel_messages_.front()->order_number, unprocessed_order_num_); |
return channel_messages_.front(); |
- } else { |
- return nullptr; |
} |
+ return nullptr; |
} |
-bool GpuChannelMessageQueue::MessageProcessed(uint32_t order_number) { |
+bool GpuChannelMessageQueue::MessageProcessed() { |
base::AutoLock auto_lock(channel_messages_lock_); |
- if (order_number != kOutOfOrderNumber) { |
- DCHECK(!channel_messages_.empty()); |
- scoped_ptr<GpuChannelMessage> msg(channel_messages_.front()); |
- channel_messages_.pop_front(); |
- DCHECK_EQ(order_number, msg->order_number); |
- processed_order_num_ = order_number; |
- } else { |
- DCHECK(!out_of_order_messages_.empty()); |
- scoped_ptr<GpuChannelMessage> msg(out_of_order_messages_.front()); |
- out_of_order_messages_.pop_front(); |
- } |
- return HasQueuedMessagesHelper(); |
+ DCHECK(!channel_messages_.empty()); |
+ scoped_ptr<GpuChannelMessage> msg(channel_messages_.front()); |
+ channel_messages_.pop_front(); |
+ processed_order_num_ = msg->order_number; |
+ return !channel_messages_.empty(); |
} |
void GpuChannelMessageQueue::DeleteAndDisableMessages( |
@@ -206,7 +178,6 @@ void GpuChannelMessageQueue::DeleteAndDisableMessages( |
msg->sync_point); |
} |
} |
- STLDeleteElements(&out_of_order_messages_); |
} |
void GpuChannelMessageQueue::ScheduleHandleMessage() { |
@@ -218,31 +189,26 @@ void GpuChannelMessageQueue::PushMessageHelper( |
scoped_ptr<GpuChannelMessage> msg) { |
channel_messages_lock_.AssertAcquired(); |
DCHECK(enabled_); |
- bool had_messages = HasQueuedMessagesHelper(); |
- if (msg->order_number != kOutOfOrderNumber) { |
- unprocessed_order_num_ = msg->order_number; |
- channel_messages_.push_back(msg.release()); |
- } else { |
- out_of_order_messages_.push_back(msg.release()); |
- } |
+ |
+ msg->order_number = global_order_counter_++; |
+ msg->time_received = base::TimeTicks::Now(); |
+ |
+ unprocessed_order_num_ = msg->order_number; |
+ |
+ bool had_messages = !channel_messages_.empty(); |
+ channel_messages_.push_back(msg.release()); |
if (!had_messages) |
ScheduleHandleMessage(); |
} |
-bool GpuChannelMessageQueue::HasQueuedMessagesHelper() const { |
- channel_messages_lock_.AssertAcquired(); |
- return !channel_messages_.empty() || !out_of_order_messages_.empty(); |
-} |
- |
-// Begin order numbers at 1 so 0 can mean no orders. |
-uint32_t GpuChannelMessageFilter::global_order_counter_ = 1; |
- |
GpuChannelMessageFilter::GpuChannelMessageFilter( |
+ const base::WeakPtr<GpuChannel>& gpu_channel, |
GpuChannelMessageQueue* message_queue, |
gpu::SyncPointManager* sync_point_manager, |
base::SingleThreadTaskRunner* task_runner, |
bool future_sync_points) |
: preemption_state_(IDLE), |
+ gpu_channel_(gpu_channel), |
message_queue_(message_queue), |
sender_(nullptr), |
peer_pid_(base::kNullProcessId), |
@@ -311,13 +277,18 @@ void GpuChannelMessageFilter::RemoveChannelFilter( |
bool GpuChannelMessageFilter::OnMessageReceived(const IPC::Message& message) { |
DCHECK(sender_); |
+ |
+ if (message.should_unblock() || message.is_reply()) { |
+ DLOG(ERROR) << "Unexpected message type"; |
+ return true; |
+ } |
+ |
for (scoped_refptr<IPC::MessageFilter>& filter : channel_filters_) { |
if (filter->OnMessageReceived(message)) { |
return true; |
} |
} |
- const uint32_t order_number = global_order_counter_++; |
bool handled = false; |
if ((message.type() == GpuCommandBufferMsg_RetireSyncPoint::ID) && |
!future_sync_points_) { |
@@ -337,7 +308,7 @@ bool GpuChannelMessageFilter::OnMessageReceived(const IPC::Message& message) { |
} |
bool retire_sync_point = base::get<0>(params); |
if (!future_sync_points_ && !retire_sync_point) { |
- LOG(ERROR) << "Untrusted contexts can't create future sync points"; |
+ DLOG(ERROR) << "Untrusted contexts can't create future sync points"; |
reply->set_reply_error(); |
Send(reply); |
return true; |
@@ -347,9 +318,8 @@ bool GpuChannelMessageFilter::OnMessageReceived(const IPC::Message& message) { |
// message queue could be disabled from the main thread during generation. |
uint32_t sync_point = 0u; |
if (!message_queue_->GenerateSyncPointMessage( |
- sync_point_manager_, order_number, message, retire_sync_point, |
- &sync_point)) { |
- LOG(ERROR) << "GpuChannel has been destroyed."; |
+ sync_point_manager_, message, retire_sync_point, &sync_point)) { |
+ DLOG(ERROR) << "GpuChannel has been destroyed."; |
reply->set_reply_error(); |
Send(reply); |
return true; |
@@ -362,14 +332,14 @@ bool GpuChannelMessageFilter::OnMessageReceived(const IPC::Message& message) { |
} |
// Forward all other messages to the GPU Channel. |
- if (!handled && !message.is_reply() && !message.should_unblock()) { |
+ if (!handled) { |
if (message.type() == GpuCommandBufferMsg_WaitForTokenInRange::ID || |
message.type() == GpuCommandBufferMsg_WaitForGetOffsetInRange::ID) { |
- // Move Wait commands to the head of the queue, so the renderer |
- // doesn't have to wait any longer than necessary. |
- message_queue_->PushBackMessage(kOutOfOrderNumber, message); |
+ task_runner_->PostTask(FROM_HERE, |
+ base::Bind(&GpuChannel::HandleOutOfOrderMessage, |
+ gpu_channel_, message)); |
} else { |
- message_queue_->PushBackMessage(order_number, message); |
+ message_queue_->PushBackMessage(message); |
} |
handled = true; |
} |
@@ -595,8 +565,9 @@ GpuChannel::GpuChannel(GpuChannelManager* gpu_channel_manager, |
GpuChannelMessageQueue::Create(weak_factory_.GetWeakPtr(), task_runner); |
filter_ = new GpuChannelMessageFilter( |
- message_queue_.get(), gpu_channel_manager_->sync_point_manager(), |
- task_runner_.get(), allow_future_sync_points_); |
+ weak_factory_.GetWeakPtr(), message_queue_.get(), |
+ gpu_channel_manager_->sync_point_manager(), task_runner_.get(), |
+ allow_future_sync_points_); |
subscription_ref_set_->AddObserver(this); |
} |
@@ -848,7 +819,7 @@ void GpuChannel::HandleMessage() { |
if (!m) |
return; |
- uint32_t order_number = m->order_number; |
+ current_order_num_ = m->order_number; |
const IPC::Message& message = m->message; |
int32_t routing_id = message.routing_id(); |
GpuCommandBufferStub* stub = stubs_.get(routing_id); |
@@ -858,8 +829,6 @@ void GpuChannel::HandleMessage() { |
DVLOG(1) << "received message @" << &message << " on channel @" << this |
<< " with type " << message.type(); |
- current_order_num_ = order_number; |
- |
bool handled = false; |
if (routing_id == MSG_ROUTING_CONTROL) { |
@@ -892,8 +861,7 @@ void GpuChannel::HandleMessage() { |
// A command buffer may be descheduled or preempted but only in the middle of |
// a flush. In this case we should not pop the message from the queue. |
- if (stub && stub->HasUnprocessedCommands() && |
- order_number != kOutOfOrderNumber) { |
+ if (stub && stub->HasUnprocessedCommands()) { |
DCHECK_EQ((uint32_t)GpuCommandBufferMsg_AsyncFlush::ID, message.type()); |
// If the stub is still scheduled then we were preempted and need to |
// schedule a wakeup otherwise some other event will wake us up e.g. sync |
@@ -904,9 +872,8 @@ void GpuChannel::HandleMessage() { |
return; |
} |
- if (message_queue_->MessageProcessed(order_number)) { |
+ if (message_queue_->MessageProcessed()) |
ScheduleHandleMessage(); |
- } |
if (preempting_flag_) { |
io_task_runner_->PostTask( |
@@ -920,6 +887,17 @@ void GpuChannel::ScheduleHandleMessage() { |
weak_factory_.GetWeakPtr())); |
} |
+void GpuChannel::HandleOutOfOrderMessage(const IPC::Message& msg) { |
+ switch (msg.type()) { |
+ case GpuCommandBufferMsg_WaitForGetOffsetInRange::ID: |
+ case GpuCommandBufferMsg_WaitForTokenInRange::ID: |
+ router_.RouteMessage(msg); |
+ break; |
+ default: |
+ NOTREACHED(); |
+ } |
+} |
+ |
void GpuChannel::OnCreateOffscreenCommandBuffer( |
const gfx::Size& size, |
const GPUCreateCommandBufferConfig& init_params, |