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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 #if defined(OS_WIN) 5 #if defined(OS_WIN)
6 #include <windows.h> 6 #include <windows.h>
7 #endif 7 #endif
8 8
9 #include "content/common/gpu/gpu_channel.h" 9 #include "content/common/gpu/gpu_channel.h"
10 10
(...skipping 18 matching lines...) Expand all
29 GpuWatchdog* watchdog, 29 GpuWatchdog* watchdog,
30 int renderer_id, 30 int renderer_id,
31 bool software) 31 bool software)
32 : gpu_channel_manager_(gpu_channel_manager), 32 : gpu_channel_manager_(gpu_channel_manager),
33 renderer_id_(renderer_id), 33 renderer_id_(renderer_id),
34 renderer_process_(base::kNullProcessHandle), 34 renderer_process_(base::kNullProcessHandle),
35 renderer_pid_(base::kNullProcessId), 35 renderer_pid_(base::kNullProcessId),
36 share_group_(new gfx::GLShareGroup), 36 share_group_(new gfx::GLShareGroup),
37 watchdog_(watchdog), 37 watchdog_(watchdog),
38 software_(software), 38 software_(software),
39 handle_messages_scheduled_(false),
39 task_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { 40 task_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
40 DCHECK(gpu_channel_manager); 41 DCHECK(gpu_channel_manager);
41 DCHECK(renderer_id); 42 DCHECK(renderer_id);
42 const CommandLine* command_line = CommandLine::ForCurrentProcess(); 43 const CommandLine* command_line = CommandLine::ForCurrentProcess();
43 log_messages_ = command_line->HasSwitch(switches::kLogPluginMessages); 44 log_messages_ = command_line->HasSwitch(switches::kLogPluginMessages);
44 disallowed_features_.multisampling = 45 disallowed_features_.multisampling =
45 command_line->HasSwitch(switches::kDisableGLMultisampling); 46 command_line->HasSwitch(switches::kDisableGLMultisampling);
46 disallowed_features_.driver_bug_workarounds = 47 disallowed_features_.driver_bug_workarounds =
47 command_line->HasSwitch(switches::kDisableGpuDriverBugWorkarounds); 48 command_line->HasSwitch(switches::kDisableGpuDriverBugWorkarounds);
48 } 49 }
(...skipping 20 matching lines...) Expand all
69 << " with type " << message.type(); 70 << " with type " << message.type();
70 } 71 }
71 72
72 // Control messages are not deferred and can be handled out of order with 73 // Control messages are not deferred and can be handled out of order with
73 // respect to routed ones. Except for Echo, which must be deferred in order 74 // respect to routed ones. Except for Echo, which must be deferred in order
74 // to respect the asynchronous Mac SwapBuffers. 75 // to respect the asynchronous Mac SwapBuffers.
75 if (message.routing_id() == MSG_ROUTING_CONTROL && 76 if (message.routing_id() == MSG_ROUTING_CONTROL &&
76 message.type() != GpuChannelMsg_Echo::ID) 77 message.type() != GpuChannelMsg_Echo::ID)
77 return OnControlMessageReceived(message); 78 return OnControlMessageReceived(message);
78 79
79 // If the channel is unscheduled, defer sync and async messages until it is 80 if (message.type() == GpuCommandBufferMsg_GetStateFast::ID) {
80 // rescheduled. Also, even if the channel is scheduled, do not allow newly 81 // Move GetStateFast commands to the head of the queue, so the renderer
81 // received messages to be handled before previously received deferred ones; 82 // doesn't have to wait any longer than necessary.
82 // append them to the deferred queue as well. 83 deferred_messages_.push_front(new IPC::Message(message));
83 if (!IsScheduled() || !deferred_messages_.empty()) { 84 } else {
84 deferred_messages_.push(new IPC::Message(message)); 85 deferred_messages_.push_back(new IPC::Message(message));
85 return true;
86 } 86 }
87 87
88 // Handle deferred control messages. 88 if (IsScheduled())
89 if (message.routing_id() == MSG_ROUTING_CONTROL) 89 OnScheduled();
90 return OnControlMessageReceived(message);
91
92 if (!router_.RouteMessage(message)) {
93 // Respond to sync messages even if router failed to route.
94 if (message.is_sync()) {
95 IPC::Message* reply = IPC::SyncMessage::GenerateReply(&message);
96 reply->set_reply_error();
97 Send(reply);
98 }
99 return false;
100 }
101
102 // If the channel becomes unscheduled as a result of handling the message,
103 // synthesize an IPC message to flush the command buffer that became
104 // unscheduled.
105 for (StubMap::Iterator<GpuCommandBufferStub> it(&stubs_);
106 !it.IsAtEnd();
107 it.Advance()) {
108 GpuCommandBufferStub* stub = it.GetCurrentValue();
109 if (!stub->IsScheduled()) {
110 DCHECK(deferred_messages_.empty());
111 deferred_messages_.push(new GpuCommandBufferMsg_Rescheduled(
112 stub->route_id()));
113 }
114 }
115 90
116 return true; 91 return true;
117 } 92 }
118 93
119 void GpuChannel::OnChannelError() { 94 void GpuChannel::OnChannelError() {
120 gpu_channel_manager_->RemoveChannel(renderer_id_); 95 gpu_channel_manager_->RemoveChannel(renderer_id_);
121 } 96 }
122 97
123 void GpuChannel::OnChannelConnected(int32 peer_pid) { 98 void GpuChannel::OnChannelConnected(int32 peer_pid) {
124 renderer_pid_ = peer_pid; 99 renderer_pid_ = peer_pid;
(...skipping 22 matching lines...) Expand all
147 it.Advance()) { 122 it.Advance()) {
148 GpuCommandBufferStub* stub = it.GetCurrentValue(); 123 GpuCommandBufferStub* stub = it.GetCurrentValue();
149 if (!stub->IsScheduled()) 124 if (!stub->IsScheduled())
150 return false; 125 return false;
151 } 126 }
152 127
153 return true; 128 return true;
154 } 129 }
155 130
156 void GpuChannel::OnScheduled() { 131 void GpuChannel::OnScheduled() {
132 if (handle_messages_scheduled_)
133 return;
157 // Post a task to handle any deferred messages. The deferred message queue is 134 // Post a task to handle any deferred messages. The deferred message queue is
158 // not emptied here, which ensures that OnMessageReceived will continue to 135 // not emptied here, which ensures that OnMessageReceived will continue to
159 // defer newly received messages until the ones in the queue have all been 136 // defer newly received messages until the ones in the queue have all been
160 // handled by HandleDeferredMessages. HandleDeferredMessages is invoked as a 137 // handled by HandleDeferredMessages. HandleDeferredMessages is invoked as a
161 // task to prevent reentrancy. 138 // task to prevent reentrancy.
162 MessageLoop::current()->PostTask( 139 MessageLoop::current()->PostTask(
163 FROM_HERE, 140 FROM_HERE,
164 task_factory_.NewRunnableMethod( 141 task_factory_.NewRunnableMethod(
165 &GpuChannel::HandleDeferredMessages)); 142 &GpuChannel::HandleMessage));
143 handle_messages_scheduled_ = true;
166 } 144 }
167 145
168 void GpuChannel::LoseAllContexts() { 146 void GpuChannel::LoseAllContexts() {
169 gpu_channel_manager_->LoseAllContexts(); 147 gpu_channel_manager_->LoseAllContexts();
170 } 148 }
171 149
172 void GpuChannel::DestroySoon() { 150 void GpuChannel::DestroySoon() {
173 MessageLoop::current()->PostTask( 151 MessageLoop::current()->PostTask(
174 FROM_HERE, NewRunnableMethod(this, 152 FROM_HERE, NewRunnableMethod(this,
175 &GpuChannel::OnDestroy)); 153 &GpuChannel::OnDestroy));
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 OnDestroyCommandBuffer) 227 OnDestroyCommandBuffer)
250 IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateTransportTexture, 228 IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateTransportTexture,
251 OnCreateTransportTexture) 229 OnCreateTransportTexture)
252 IPC_MESSAGE_HANDLER(GpuChannelMsg_Echo, OnEcho); 230 IPC_MESSAGE_HANDLER(GpuChannelMsg_Echo, OnEcho);
253 IPC_MESSAGE_UNHANDLED(handled = false) 231 IPC_MESSAGE_UNHANDLED(handled = false)
254 IPC_END_MESSAGE_MAP() 232 IPC_END_MESSAGE_MAP()
255 DCHECK(handled) << msg.type(); 233 DCHECK(handled) << msg.type();
256 return handled; 234 return handled;
257 } 235 }
258 236
259 void GpuChannel::HandleDeferredMessages() { 237 void GpuChannel::HandleMessage() {
260 // Empty the deferred queue so OnMessageRecieved does not defer on that 238 handle_messages_scheduled_ = false;
261 // account and to prevent an infinite loop if the scheduler is unscheduled 239 if (!IsScheduled())
262 // as a result of handling already deferred messages. 240 return;
263 std::queue<IPC::Message*> deferred_messages_copy;
264 std::swap(deferred_messages_copy, deferred_messages_);
265 241
266 while (!deferred_messages_copy.empty()) { 242 if (!deferred_messages_.empty()) {
267 scoped_ptr<IPC::Message> message(deferred_messages_copy.front()); 243 scoped_ptr<IPC::Message> message(deferred_messages_.front());
268 deferred_messages_copy.pop(); 244 deferred_messages_.pop_front();
245 // Handle deferred control messages.
246 if (message->routing_id() == MSG_ROUTING_CONTROL)
247 OnControlMessageReceived(*message);
248 else if (!router_.RouteMessage(*message)) {
249 // Respond to sync messages even if router failed to route.
250 if (message->is_sync()) {
251 IPC::Message* reply = IPC::SyncMessage::GenerateReply(&*message);
252 reply->set_reply_error();
253 Send(reply);
254 }
255 } else {
256 // If the channel becomes unscheduled as a result of handling the message,
257 // synthesize an IPC message to flush the command buffer that became
258 // unscheduled.
259 for (StubMap::Iterator<GpuCommandBufferStub> it(&stubs_);
260 !it.IsAtEnd();
261 it.Advance()) {
262 GpuCommandBufferStub* stub = it.GetCurrentValue();
263 if (!stub->IsScheduled()) {
264 deferred_messages_.push_front(new GpuCommandBufferMsg_Rescheduled(
265 stub->route_id()));
266 }
267 }
268 }
269 }
269 270
270 OnMessageReceived(*message); 271 if (IsScheduled() && !deferred_messages_.empty()) {
272 OnScheduled();
271 } 273 }
272 } 274 }
273 275
274 int GpuChannel::GenerateRouteID() { 276 int GpuChannel::GenerateRouteID() {
275 static int last_id = 0; 277 static int last_id = 0;
276 return ++last_id; 278 return ++last_id;
277 } 279 }
278 280
279 void GpuChannel::AddRoute(int32 route_id, IPC::Channel::Listener* listener) { 281 void GpuChannel::AddRoute(int32 route_id, IPC::Channel::Listener* listener) {
280 router_.AddRoute(route_id, listener); 282 router_.AddRoute(route_id, listener);
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 399
398 #if defined(OS_POSIX) 400 #if defined(OS_POSIX)
399 int GpuChannel::TakeRendererFileDescriptor() { 401 int GpuChannel::TakeRendererFileDescriptor() {
400 if (!channel_.get()) { 402 if (!channel_.get()) {
401 NOTREACHED(); 403 NOTREACHED();
402 return -1; 404 return -1;
403 } 405 }
404 return channel_->TakeClientFileDescriptor(); 406 return channel_->TakeClientFileDescriptor();
405 } 407 }
406 #endif // defined(OS_POSIX) 408 #endif // defined(OS_POSIX)
OLDNEW
« 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