Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(823)

Unified Diff: content/common/gpu/gpu_channel.cc

Issue 8198017: Allow FlushSyncs to short circuit (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/common/gpu/gpu_channel.h ('k') | content/common/gpu/gpu_command_buffer_stub.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/common/gpu/gpu_channel.cc
diff --git a/content/common/gpu/gpu_channel.cc b/content/common/gpu/gpu_channel.cc
index 89f775dc29c875ad6374272158257f3644ae6501..75aaec7f0a8411b0d60dad8068e02b92eb83383f 100644
--- a/content/common/gpu/gpu_channel.cc
+++ b/content/common/gpu/gpu_channel.cc
@@ -36,6 +36,7 @@ GpuChannel::GpuChannel(GpuChannelManager* gpu_channel_manager,
share_group_(new gfx::GLShareGroup),
watchdog_(watchdog),
software_(software),
+ handle_messages_scheduled_(false),
task_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
DCHECK(gpu_channel_manager);
DCHECK(renderer_id);
@@ -76,42 +77,16 @@ bool GpuChannel::OnMessageReceived(const IPC::Message& message) {
message.type() != GpuChannelMsg_Echo::ID)
return OnControlMessageReceived(message);
- // If the channel is unscheduled, defer sync and async messages until it is
- // rescheduled. Also, even if the channel is scheduled, do not allow newly
- // received messages to be handled before previously received deferred ones;
- // append them to the deferred queue as well.
- if (!IsScheduled() || !deferred_messages_.empty()) {
- deferred_messages_.push(new IPC::Message(message));
- return true;
+ if (message.type() == GpuCommandBufferMsg_GetStateFast::ID) {
+ // Move GetStateFast commands to the head of the queue, so the renderer
+ // doesn't have to wait any longer than necessary.
+ deferred_messages_.push_front(new IPC::Message(message));
+ } else {
+ deferred_messages_.push_back(new IPC::Message(message));
}
- // Handle deferred control messages.
- if (message.routing_id() == MSG_ROUTING_CONTROL)
- return OnControlMessageReceived(message);
-
- if (!router_.RouteMessage(message)) {
- // Respond to sync messages even if router failed to route.
- if (message.is_sync()) {
- IPC::Message* reply = IPC::SyncMessage::GenerateReply(&message);
- reply->set_reply_error();
- Send(reply);
- }
- return false;
- }
-
- // If the channel becomes unscheduled as a result of handling the message,
- // synthesize an IPC message to flush the command buffer that became
- // unscheduled.
- for (StubMap::Iterator<GpuCommandBufferStub> it(&stubs_);
- !it.IsAtEnd();
- it.Advance()) {
- GpuCommandBufferStub* stub = it.GetCurrentValue();
- if (!stub->IsScheduled()) {
- DCHECK(deferred_messages_.empty());
- deferred_messages_.push(new GpuCommandBufferMsg_Rescheduled(
- stub->route_id()));
- }
- }
+ if (IsScheduled())
+ OnScheduled();
return true;
}
@@ -154,6 +129,8 @@ bool GpuChannel::IsScheduled() {
}
void GpuChannel::OnScheduled() {
+ if (handle_messages_scheduled_)
+ return;
// Post a task to handle any deferred messages. The deferred message queue is
// not emptied here, which ensures that OnMessageReceived will continue to
// defer newly received messages until the ones in the queue have all been
@@ -162,7 +139,8 @@ void GpuChannel::OnScheduled() {
MessageLoop::current()->PostTask(
FROM_HERE,
task_factory_.NewRunnableMethod(
- &GpuChannel::HandleDeferredMessages));
+ &GpuChannel::HandleMessage));
+ handle_messages_scheduled_ = true;
}
void GpuChannel::LoseAllContexts() {
@@ -256,18 +234,42 @@ bool GpuChannel::OnControlMessageReceived(const IPC::Message& msg) {
return handled;
}
-void GpuChannel::HandleDeferredMessages() {
- // Empty the deferred queue so OnMessageRecieved does not defer on that
- // account and to prevent an infinite loop if the scheduler is unscheduled
- // as a result of handling already deferred messages.
- std::queue<IPC::Message*> deferred_messages_copy;
- std::swap(deferred_messages_copy, deferred_messages_);
+void GpuChannel::HandleMessage() {
+ handle_messages_scheduled_ = false;
+ if (!IsScheduled())
+ return;
- while (!deferred_messages_copy.empty()) {
- scoped_ptr<IPC::Message> message(deferred_messages_copy.front());
- deferred_messages_copy.pop();
+ if (!deferred_messages_.empty()) {
+ scoped_ptr<IPC::Message> message(deferred_messages_.front());
+ deferred_messages_.pop_front();
+ // Handle deferred control messages.
+ if (message->routing_id() == MSG_ROUTING_CONTROL)
+ OnControlMessageReceived(*message);
+ else if (!router_.RouteMessage(*message)) {
+ // Respond to sync messages even if router failed to route.
+ if (message->is_sync()) {
+ IPC::Message* reply = IPC::SyncMessage::GenerateReply(&*message);
+ reply->set_reply_error();
+ Send(reply);
+ }
+ } else {
+ // If the channel becomes unscheduled as a result of handling the message,
+ // synthesize an IPC message to flush the command buffer that became
+ // unscheduled.
+ for (StubMap::Iterator<GpuCommandBufferStub> it(&stubs_);
+ !it.IsAtEnd();
+ it.Advance()) {
+ GpuCommandBufferStub* stub = it.GetCurrentValue();
+ if (!stub->IsScheduled()) {
+ deferred_messages_.push_front(new GpuCommandBufferMsg_Rescheduled(
+ stub->route_id()));
+ }
+ }
+ }
+ }
- OnMessageReceived(*message);
+ if (IsScheduled() && !deferred_messages_.empty()) {
+ OnScheduled();
}
}
« no previous file with comments | « content/common/gpu/gpu_channel.h ('k') | content/common/gpu/gpu_command_buffer_stub.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698