Chromium Code Reviews| 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 #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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |