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

Side by Side Diff: content/common/gpu/gpu_channel.cc

Issue 12340118: GPU: Only allow the UI channel to preempt if all stubs are scheduled. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 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
OLDNEW
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 #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 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 public: 150 public:
151 // Takes ownership of gpu_channel (see below). 151 // Takes ownership of gpu_channel (see below).
152 SyncPointMessageFilter(base::WeakPtr<GpuChannel>* gpu_channel, 152 SyncPointMessageFilter(base::WeakPtr<GpuChannel>* gpu_channel,
153 scoped_refptr<SyncPointManager> sync_point_manager, 153 scoped_refptr<SyncPointManager> sync_point_manager,
154 scoped_refptr<base::MessageLoopProxy> message_loop) 154 scoped_refptr<base::MessageLoopProxy> message_loop)
155 : preemption_state_(IDLE), 155 : preemption_state_(IDLE),
156 gpu_channel_(gpu_channel), 156 gpu_channel_(gpu_channel),
157 channel_(NULL), 157 channel_(NULL),
158 sync_point_manager_(sync_point_manager), 158 sync_point_manager_(sync_point_manager),
159 message_loop_(message_loop), 159 message_loop_(message_loop),
160 messages_received_(0) { 160 messages_received_(0),
161 a_stub_is_descheduled_(false) {
161 } 162 }
162 163
163 virtual void OnFilterAdded(IPC::Channel* channel) OVERRIDE { 164 virtual void OnFilterAdded(IPC::Channel* channel) OVERRIDE {
164 DCHECK(!channel_); 165 DCHECK(!channel_);
165 channel_ = channel; 166 channel_ = channel;
166 } 167 }
167 168
168 virtual void OnFilterRemoved() OVERRIDE { 169 virtual void OnFilterRemoved() OVERRIDE {
169 DCHECK(channel_); 170 DCHECK(channel_);
170 channel_ = NULL; 171 channel_ = NULL;
(...skipping 29 matching lines...) Expand all
200 } 201 }
201 } 202 }
202 203
203 void MessageProcessed(uint64 messages_processed) { 204 void MessageProcessed(uint64 messages_processed) {
204 while (!pending_messages_.empty() && 205 while (!pending_messages_.empty() &&
205 pending_messages_.front().message_number <= messages_processed) 206 pending_messages_.front().message_number <= messages_processed)
206 pending_messages_.pop(); 207 pending_messages_.pop();
207 UpdatePreemptionState(); 208 UpdatePreemptionState();
208 } 209 }
209 210
210 void SetPreemptingFlag(gpu::PreemptionFlag* preempting_flag) { 211 void SetPreemptingFlagAndSchedulingState(
212 gpu::PreemptionFlag* preempting_flag,
213 bool a_stub_is_descheduled) {
211 preempting_flag_ = preempting_flag; 214 preempting_flag_ = preempting_flag;
215 a_stub_is_descheduled_ = a_stub_is_descheduled;
216 }
217
218 void UpdateStubSchedulingState(bool a_stub_is_descheduled) {
piman 2013/02/27 21:54:43 I'm afraid this will kick preemption more than you
jonathan.backer 2013/02/28 21:43:56 Done.
219 a_stub_is_descheduled_ = a_stub_is_descheduled;
220 if (preemption_state_ == PREEMPTING) {
221 if (a_stub_is_descheduled_)
222 preempting_flag_->Reset();
223 else
224 preempting_flag_->Set();
225 }
212 } 226 }
213 227
214 protected: 228 protected:
215 virtual ~SyncPointMessageFilter() { 229 virtual ~SyncPointMessageFilter() {
216 message_loop_->PostTask(FROM_HERE, base::Bind( 230 message_loop_->PostTask(FROM_HERE, base::Bind(
217 &SyncPointMessageFilter::DeleteWeakPtrOnMainThread, gpu_channel_)); 231 &SyncPointMessageFilter::DeleteWeakPtrOnMainThread, gpu_channel_));
218 } 232 }
219 233
220 private: 234 private:
221 enum PreemptionState { 235 enum PreemptionState {
222 // Either there's no other channel to preempt, there are no messages 236 // Either there's no other channel to preempt, there are no messages
223 // pending processing, or we just finished preempting and have to wait 237 // pending processing, or we just finished preempting and have to wait
224 // before preempting again. 238 // before preempting again.
225 IDLE, 239 IDLE,
226 // We are waiting kPreemptWaitTimeMs before checking if we should preempt. 240 // We are waiting kPreemptWaitTimeMs before checking if we should preempt.
227 WAITING, 241 WAITING,
228 // We can preempt whenever any IPC processing takes more than 242 // We can preempt whenever any IPC processing takes more than
229 // kPreemptWaitTimeMs. 243 // kPreemptWaitTimeMs.
230 CHECKING, 244 CHECKING,
231 // We are currently preempting. 245 // We are currently preempting if and only if all stubs on this channel
246 // are scheduled.
232 PREEMPTING, 247 PREEMPTING,
233 }; 248 };
234 249
235 PreemptionState preemption_state_; 250 PreemptionState preemption_state_;
236 251
237 struct PendingMessage { 252 struct PendingMessage {
238 uint64 message_number; 253 uint64 message_number;
239 base::TimeTicks time_received; 254 base::TimeTicks time_received;
240 255
241 explicit PendingMessage(uint64 message_number) 256 explicit PendingMessage(uint64 message_number)
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 } 332 }
318 333
319 void TransitionToPreempting() { 334 void TransitionToPreempting() {
320 DCHECK_EQ(preemption_state_, CHECKING); 335 DCHECK_EQ(preemption_state_, CHECKING);
321 336
322 // Stop any pending state update checks that we may have queued 337 // Stop any pending state update checks that we may have queued
323 // while CHECKING. 338 // while CHECKING.
324 timer_.Stop(); 339 timer_.Stop();
325 340
326 preemption_state_ = PREEMPTING; 341 preemption_state_ = PREEMPTING;
327 preempting_flag_->Set(); 342 if (!a_stub_is_descheduled_)
343 preempting_flag_->Set();
328 TRACE_COUNTER_ID1("gpu", "GpuChannel::Preempting", this, 1); 344 TRACE_COUNTER_ID1("gpu", "GpuChannel::Preempting", this, 1);
329 345
330 timer_.Start( 346 timer_.Start(
331 FROM_HERE, 347 FROM_HERE,
332 base::TimeDelta::FromMilliseconds(kMaxPreemptTimeMs), 348 base::TimeDelta::FromMilliseconds(kMaxPreemptTimeMs),
333 this, &SyncPointMessageFilter::TransitionToIdle); 349 this, &SyncPointMessageFilter::TransitionToIdle);
334 350
335 UpdatePreemptionState(); 351 UpdatePreemptionState();
336 } 352 }
337 353
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 scoped_refptr<SyncPointManager> sync_point_manager_; 389 scoped_refptr<SyncPointManager> sync_point_manager_;
374 scoped_refptr<base::MessageLoopProxy> message_loop_; 390 scoped_refptr<base::MessageLoopProxy> message_loop_;
375 scoped_refptr<gpu::PreemptionFlag> preempting_flag_; 391 scoped_refptr<gpu::PreemptionFlag> preempting_flag_;
376 392
377 std::queue<PendingMessage> pending_messages_; 393 std::queue<PendingMessage> pending_messages_;
378 394
379 // Count of the number of IPCs received on this GpuChannel. 395 // Count of the number of IPCs received on this GpuChannel.
380 uint64 messages_received_; 396 uint64 messages_received_;
381 397
382 base::OneShotTimer<SyncPointMessageFilter> timer_; 398 base::OneShotTimer<SyncPointMessageFilter> timer_;
399
400 bool a_stub_is_descheduled_;
383 }; 401 };
384 402
385 GpuChannel::GpuChannel(GpuChannelManager* gpu_channel_manager, 403 GpuChannel::GpuChannel(GpuChannelManager* gpu_channel_manager,
386 GpuWatchdog* watchdog, 404 GpuWatchdog* watchdog,
387 gfx::GLShareGroup* share_group, 405 gfx::GLShareGroup* share_group,
388 gpu::gles2::MailboxManager* mailbox, 406 gpu::gles2::MailboxManager* mailbox,
389 int client_id, 407 int client_id,
390 bool software) 408 bool software)
391 : gpu_channel_manager_(gpu_channel_manager), 409 : gpu_channel_manager_(gpu_channel_manager),
392 messages_processed_(0), 410 messages_processed_(0),
393 client_id_(client_id), 411 client_id_(client_id),
394 share_group_(share_group ? share_group : new gfx::GLShareGroup), 412 share_group_(share_group ? share_group : new gfx::GLShareGroup),
395 mailbox_manager_(mailbox ? mailbox : new gpu::gles2::MailboxManager), 413 mailbox_manager_(mailbox ? mailbox : new gpu::gles2::MailboxManager),
396 image_manager_(new gpu::gles2::ImageManager), 414 image_manager_(new gpu::gles2::ImageManager),
397 watchdog_(watchdog), 415 watchdog_(watchdog),
398 software_(software), 416 software_(software),
399 handle_messages_scheduled_(false), 417 handle_messages_scheduled_(false),
400 processed_get_state_fast_(false), 418 processed_get_state_fast_(false),
401 currently_processing_message_(NULL), 419 currently_processing_message_(NULL),
402 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { 420 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
421 a_stub_is_descheduled_(false) {
403 DCHECK(gpu_channel_manager); 422 DCHECK(gpu_channel_manager);
404 DCHECK(client_id); 423 DCHECK(client_id);
405 424
406 channel_id_ = IPC::Channel::GenerateVerifiedChannelID("gpu"); 425 channel_id_ = IPC::Channel::GenerateVerifiedChannelID("gpu");
407 const CommandLine* command_line = CommandLine::ForCurrentProcess(); 426 const CommandLine* command_line = CommandLine::ForCurrentProcess();
408 log_messages_ = command_line->HasSwitch(switches::kLogPluginMessages); 427 log_messages_ = command_line->HasSwitch(switches::kLogPluginMessages);
409 disallowed_features_.multisampling = 428 disallowed_features_.multisampling =
410 command_line->HasSwitch(switches::kDisableGLMultisampling); 429 command_line->HasSwitch(switches::kDisableGLMultisampling);
411 #if defined(OS_ANDROID) 430 #if defined(OS_ANDROID)
412 stream_texture_manager_.reset(new StreamTextureManagerAndroid(this)); 431 stream_texture_manager_.reset(new StreamTextureManagerAndroid(this));
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 // not emptied here, which ensures that OnMessageReceived will continue to 557 // not emptied here, which ensures that OnMessageReceived will continue to
539 // defer newly received messages until the ones in the queue have all been 558 // defer newly received messages until the ones in the queue have all been
540 // handled by HandleMessage. HandleMessage is invoked as a 559 // handled by HandleMessage. HandleMessage is invoked as a
541 // task to prevent reentrancy. 560 // task to prevent reentrancy.
542 MessageLoop::current()->PostTask( 561 MessageLoop::current()->PostTask(
543 FROM_HERE, 562 FROM_HERE,
544 base::Bind(&GpuChannel::HandleMessage, weak_factory_.GetWeakPtr())); 563 base::Bind(&GpuChannel::HandleMessage, weak_factory_.GetWeakPtr()));
545 handle_messages_scheduled_ = true; 564 handle_messages_scheduled_ = true;
546 } 565 }
547 566
567 void GpuChannel::StubSchedulingChanged() {
568 bool a_stub_is_descheduled = false;
569 for (StubMap::Iterator<GpuCommandBufferStub> it(&stubs_);
570 !it.IsAtEnd(); it.Advance()) {
piman 2013/02/27 21:54:43 Could we count scheduled stubs? If we fix the call
jonathan.backer 2013/02/28 21:43:56 Done. I'm concerned about teardown. I think I've h
571 if (!it.GetCurrentValue()->IsScheduled()) {
572 a_stub_is_descheduled = true;
573 break;
574 }
575 }
576 if (a_stub_is_descheduled != a_stub_is_descheduled_) {
577 a_stub_is_descheduled_ = a_stub_is_descheduled;
578 if (preempting_flag_.get()) {
579 io_message_loop_->PostTask(
580 FROM_HERE,
581 base::Bind(&SyncPointMessageFilter::UpdateStubSchedulingState,
582 filter_, a_stub_is_descheduled));
583 }
584 }
585 }
586
548 void GpuChannel::CreateViewCommandBuffer( 587 void GpuChannel::CreateViewCommandBuffer(
549 const gfx::GLSurfaceHandle& window, 588 const gfx::GLSurfaceHandle& window,
550 int32 surface_id, 589 int32 surface_id,
551 const GPUCreateCommandBufferConfig& init_params, 590 const GPUCreateCommandBufferConfig& init_params,
552 int32* route_id) { 591 int32* route_id) {
553 TRACE_EVENT1("gpu", 592 TRACE_EVENT1("gpu",
554 "GpuChannel::CreateViewCommandBuffer", 593 "GpuChannel::CreateViewCommandBuffer",
555 "surface_id", 594 "surface_id",
556 surface_id); 595 surface_id);
557 596
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 681
643 void GpuChannel::RemoveRoute(int32 route_id) { 682 void GpuChannel::RemoveRoute(int32 route_id) {
644 router_.RemoveRoute(route_id); 683 router_.RemoveRoute(route_id);
645 } 684 }
646 685
647 gpu::PreemptionFlag* GpuChannel::GetPreemptionFlag() { 686 gpu::PreemptionFlag* GpuChannel::GetPreemptionFlag() {
648 if (!preempting_flag_.get()) { 687 if (!preempting_flag_.get()) {
649 preempting_flag_ = new gpu::PreemptionFlag; 688 preempting_flag_ = new gpu::PreemptionFlag;
650 io_message_loop_->PostTask( 689 io_message_loop_->PostTask(
651 FROM_HERE, 690 FROM_HERE,
652 base::Bind(&SyncPointMessageFilter::SetPreemptingFlag, 691 base::Bind(&SyncPointMessageFilter::SetPreemptingFlagAndSchedulingState,
653 filter_, preempting_flag_)); 692 filter_, preempting_flag_, a_stub_is_descheduled_));
654 } 693 }
655 return preempting_flag_.get(); 694 return preempting_flag_.get();
656 } 695 }
657 696
658 void GpuChannel::SetPreemptByFlag( 697 void GpuChannel::SetPreemptByFlag(
659 scoped_refptr<gpu::PreemptionFlag> preempted_flag) { 698 scoped_refptr<gpu::PreemptionFlag> preempted_flag) {
660 preempted_flag_ = preempted_flag; 699 preempted_flag_ = preempted_flag;
661 700
662 for (StubMap::Iterator<GpuCommandBufferStub> it(&stubs_); 701 for (StubMap::Iterator<GpuCommandBufferStub> it(&stubs_);
663 !it.IsAtEnd(); it.Advance()) { 702 !it.IsAtEnd(); it.Advance()) {
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
850 messages_processed_++; 889 messages_processed_++;
851 if (preempting_flag_.get()) { 890 if (preempting_flag_.get()) {
852 io_message_loop_->PostTask( 891 io_message_loop_->PostTask(
853 FROM_HERE, 892 FROM_HERE,
854 base::Bind(&SyncPointMessageFilter::MessageProcessed, 893 base::Bind(&SyncPointMessageFilter::MessageProcessed,
855 filter_, messages_processed_)); 894 filter_, messages_processed_));
856 } 895 }
857 } 896 }
858 897
859 } // namespace content 898 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698