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 #include "base/bind.h" | 5 #include "base/bind.h" |
6 #include "base/bind_helpers.h" | 6 #include "base/bind_helpers.h" |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/hash.h" | 8 #include "base/hash.h" |
9 #include "base/json/json_writer.h" | 9 #include "base/json/json_writer.h" |
10 #include "base/memory/shared_memory.h" | 10 #include "base/memory/shared_memory.h" |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 gpu_preference_(gpu_preference), | 196 gpu_preference_(gpu_preference), |
197 use_virtualized_gl_context_(use_virtualized_gl_context), | 197 use_virtualized_gl_context_(use_virtualized_gl_context), |
198 command_buffer_id_(GetCommandBufferID(channel->client_id(), route_id)), | 198 command_buffer_id_(GetCommandBufferID(channel->client_id(), route_id)), |
199 stream_id_(stream_id), | 199 stream_id_(stream_id), |
200 route_id_(route_id), | 200 route_id_(route_id), |
201 surface_id_(surface_id), | 201 surface_id_(surface_id), |
202 software_(software), | 202 software_(software), |
203 last_flush_count_(0), | 203 last_flush_count_(0), |
204 last_memory_allocation_valid_(false), | 204 last_memory_allocation_valid_(false), |
205 watchdog_(watchdog), | 205 watchdog_(watchdog), |
206 sync_point_wait_count_(0), | 206 waiting_for_sync_point_(false), |
207 previous_processed_num_(0), | 207 previous_processed_num_(0), |
208 active_url_(active_url), | 208 active_url_(active_url), |
209 total_gpu_memory_(0) { | 209 total_gpu_memory_(0) { |
210 active_url_hash_ = base::Hash(active_url.possibly_invalid_spec()); | 210 active_url_hash_ = base::Hash(active_url.possibly_invalid_spec()); |
211 FastSetActiveURL(active_url_, active_url_hash_); | 211 FastSetActiveURL(active_url_, active_url_hash_); |
212 | 212 |
213 gpu::gles2::ContextCreationAttribHelper attrib_parser; | 213 gpu::gles2::ContextCreationAttribHelper attrib_parser; |
214 attrib_parser.Parse(requested_attribs_); | 214 attrib_parser.Parse(requested_attribs_); |
215 | 215 |
216 if (share_group) { | 216 if (share_group) { |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 | 326 |
327 DCHECK(handled); | 327 DCHECK(handled); |
328 return handled; | 328 return handled; |
329 } | 329 } |
330 | 330 |
331 bool GpuCommandBufferStub::Send(IPC::Message* message) { | 331 bool GpuCommandBufferStub::Send(IPC::Message* message) { |
332 return channel_->Send(message); | 332 return channel_->Send(message); |
333 } | 333 } |
334 | 334 |
335 bool GpuCommandBufferStub::IsScheduled() { | 335 bool GpuCommandBufferStub::IsScheduled() { |
336 return (!scheduler_.get() || scheduler_->IsScheduled()); | 336 return (!scheduler_.get() || scheduler_->scheduled()); |
337 } | 337 } |
338 | 338 |
339 void GpuCommandBufferStub::PollWork() { | 339 void GpuCommandBufferStub::PollWork() { |
340 // Post another delayed task if we have not yet reached the time at which | 340 // Post another delayed task if we have not yet reached the time at which |
341 // we should process delayed work. | 341 // we should process delayed work. |
342 base::TimeTicks current_time = base::TimeTicks::Now(); | 342 base::TimeTicks current_time = base::TimeTicks::Now(); |
343 DCHECK(!process_delayed_work_time_.is_null()); | 343 DCHECK(!process_delayed_work_time_.is_null()); |
344 if (process_delayed_work_time_ > current_time) { | 344 if (process_delayed_work_time_ > current_time) { |
345 task_runner_->PostDelayedTask( | 345 task_runner_->PostDelayedTask( |
346 FROM_HERE, base::Bind(&GpuCommandBufferStub::PollWork, AsWeakPtr()), | 346 FROM_HERE, base::Bind(&GpuCommandBufferStub::PollWork, AsWeakPtr()), |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 channel()->gpu_channel_manager()->GetProcessedOrderNum(); | 418 channel()->gpu_channel_manager()->GetProcessedOrderNum(); |
419 if (last_idle_time_.is_null()) | 419 if (last_idle_time_.is_null()) |
420 last_idle_time_ = current_time; | 420 last_idle_time_ = current_time; |
421 | 421 |
422 // IsScheduled() returns true after passing all unschedule fences | 422 // IsScheduled() returns true after passing all unschedule fences |
423 // and this is when we can start performing idle work. Idle work | 423 // and this is when we can start performing idle work. Idle work |
424 // is done synchronously so we can set delay to 0 and instead poll | 424 // is done synchronously so we can set delay to 0 and instead poll |
425 // for more work at the rate idle work is performed. This also ensures | 425 // for more work at the rate idle work is performed. This also ensures |
426 // that idle work is done as efficiently as possible without any | 426 // that idle work is done as efficiently as possible without any |
427 // unnecessary delays. | 427 // unnecessary delays. |
428 if (scheduler_.get() && | 428 if (scheduler_.get() && scheduler_->scheduled() && |
429 scheduler_->IsScheduled() && | |
430 scheduler_->HasMoreIdleWork()) { | 429 scheduler_->HasMoreIdleWork()) { |
431 delay = base::TimeDelta(); | 430 delay = base::TimeDelta(); |
432 } | 431 } |
433 | 432 |
434 process_delayed_work_time_ = current_time + delay; | 433 process_delayed_work_time_ = current_time + delay; |
435 task_runner_->PostDelayedTask( | 434 task_runner_->PostDelayedTask( |
436 FROM_HERE, base::Bind(&GpuCommandBufferStub::PollWork, AsWeakPtr()), | 435 FROM_HERE, base::Bind(&GpuCommandBufferStub::PollWork, AsWeakPtr()), |
437 delay); | 436 delay); |
438 } | 437 } |
439 | 438 |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
643 base::Bind(&GpuCommandBufferStub::OnWaitSyncPoint, | 642 base::Bind(&GpuCommandBufferStub::OnWaitSyncPoint, |
644 base::Unretained(this))); | 643 base::Unretained(this))); |
645 | 644 |
646 command_buffer_->SetPutOffsetChangeCallback( | 645 command_buffer_->SetPutOffsetChangeCallback( |
647 base::Bind(&GpuCommandBufferStub::PutChanged, base::Unretained(this))); | 646 base::Bind(&GpuCommandBufferStub::PutChanged, base::Unretained(this))); |
648 command_buffer_->SetGetBufferChangeCallback( | 647 command_buffer_->SetGetBufferChangeCallback( |
649 base::Bind(&gpu::GpuScheduler::SetGetBuffer, | 648 base::Bind(&gpu::GpuScheduler::SetGetBuffer, |
650 base::Unretained(scheduler_.get()))); | 649 base::Unretained(scheduler_.get()))); |
651 command_buffer_->SetParseErrorCallback( | 650 command_buffer_->SetParseErrorCallback( |
652 base::Bind(&GpuCommandBufferStub::OnParseError, base::Unretained(this))); | 651 base::Bind(&GpuCommandBufferStub::OnParseError, base::Unretained(this))); |
653 scheduler_->SetSchedulingChangedCallback( | 652 scheduler_->SetSchedulingChangedCallback(base::Bind( |
654 base::Bind(&GpuChannel::StubSchedulingChanged, | 653 &GpuCommandBufferStub::OnSchedulingChanged, base::Unretained(this))); |
655 base::Unretained(channel_))); | |
656 | 654 |
657 if (watchdog_) { | 655 if (watchdog_) { |
658 scheduler_->SetCommandProcessedCallback( | 656 scheduler_->SetCommandProcessedCallback( |
659 base::Bind(&GpuCommandBufferStub::OnCommandProcessed, | 657 base::Bind(&GpuCommandBufferStub::OnCommandProcessed, |
660 base::Unretained(this))); | 658 base::Unretained(this))); |
661 } | 659 } |
662 | 660 |
663 const size_t kSharedStateSize = sizeof(gpu::CommandBufferSharedState); | 661 const size_t kSharedStateSize = sizeof(gpu::CommandBufferSharedState); |
664 if (!shared_state_shm->Map(kSharedStateSize)) { | 662 if (!shared_state_shm->Map(kSharedStateSize)) { |
665 DLOG(ERROR) << "Failed to map shared state buffer."; | 663 DLOG(ERROR) << "Failed to map shared state buffer."; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
741 // Tell the browser about this context loss as well, so it can | 739 // Tell the browser about this context loss as well, so it can |
742 // determine whether client APIs like WebGL need to be immediately | 740 // determine whether client APIs like WebGL need to be immediately |
743 // blocked from automatically running. | 741 // blocked from automatically running. |
744 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); | 742 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); |
745 gpu_channel_manager->Send(new GpuHostMsg_DidLoseContext( | 743 gpu_channel_manager->Send(new GpuHostMsg_DidLoseContext( |
746 handle_.is_null(), state.context_lost_reason, active_url_)); | 744 handle_.is_null(), state.context_lost_reason, active_url_)); |
747 | 745 |
748 CheckContextLost(); | 746 CheckContextLost(); |
749 } | 747 } |
750 | 748 |
| 749 void GpuCommandBufferStub::OnSchedulingChanged(bool scheduled) { |
| 750 TRACE_EVENT1("gpu", "GpuCommandBufferStub::OnSchedulingChanged", "scheduled", |
| 751 scheduled); |
| 752 channel_->OnStubSchedulingChanged(this, scheduled); |
| 753 } |
| 754 |
751 void GpuCommandBufferStub::OnWaitForTokenInRange(int32 start, | 755 void GpuCommandBufferStub::OnWaitForTokenInRange(int32 start, |
752 int32 end, | 756 int32 end, |
753 IPC::Message* reply_message) { | 757 IPC::Message* reply_message) { |
754 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnWaitForTokenInRange"); | 758 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnWaitForTokenInRange"); |
755 DCHECK(command_buffer_.get()); | 759 DCHECK(command_buffer_.get()); |
756 CheckContextLost(); | 760 CheckContextLost(); |
757 if (wait_for_token_) | 761 if (wait_for_token_) |
758 LOG(ERROR) << "Got WaitForToken command while currently waiting for token."; | 762 LOG(ERROR) << "Got WaitForToken command while currently waiting for token."; |
759 wait_for_token_ = | 763 wait_for_token_ = |
760 make_scoped_ptr(new WaitForCommandState(start, end, reply_message)); | 764 make_scoped_ptr(new WaitForCommandState(start, end, reply_message)); |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
923 gpu::gles2::MailboxManager* mailbox_manager = | 927 gpu::gles2::MailboxManager* mailbox_manager = |
924 context_group_->mailbox_manager(); | 928 context_group_->mailbox_manager(); |
925 if (mailbox_manager->UsesSync() && MakeCurrent()) | 929 if (mailbox_manager->UsesSync() && MakeCurrent()) |
926 mailbox_manager->PushTextureUpdates(sync_point); | 930 mailbox_manager->PushTextureUpdates(sync_point); |
927 | 931 |
928 GpuChannelManager* manager = channel_->gpu_channel_manager(); | 932 GpuChannelManager* manager = channel_->gpu_channel_manager(); |
929 manager->sync_point_manager()->RetireSyncPoint(sync_point); | 933 manager->sync_point_manager()->RetireSyncPoint(sync_point); |
930 } | 934 } |
931 | 935 |
932 bool GpuCommandBufferStub::OnWaitSyncPoint(uint32 sync_point) { | 936 bool GpuCommandBufferStub::OnWaitSyncPoint(uint32 sync_point) { |
| 937 DCHECK(!waiting_for_sync_point_); |
| 938 DCHECK(scheduler_->scheduled()); |
933 if (!sync_point) | 939 if (!sync_point) |
934 return true; | 940 return true; |
935 GpuChannelManager* manager = channel_->gpu_channel_manager(); | 941 GpuChannelManager* manager = channel_->gpu_channel_manager(); |
936 if (manager->sync_point_manager()->IsSyncPointRetired(sync_point)) { | 942 if (manager->sync_point_manager()->IsSyncPointRetired(sync_point)) { |
937 PullTextureUpdates(sync_point); | 943 PullTextureUpdates(sync_point); |
938 return true; | 944 return true; |
939 } | 945 } |
940 | 946 |
941 if (sync_point_wait_count_ == 0) { | 947 TRACE_EVENT_ASYNC_BEGIN1("gpu", "WaitSyncPoint", this, "GpuCommandBufferStub", |
942 TRACE_EVENT_ASYNC_BEGIN1("gpu", "WaitSyncPoint", this, | 948 this); |
943 "GpuCommandBufferStub", this); | 949 |
944 } | |
945 scheduler_->SetScheduled(false); | 950 scheduler_->SetScheduled(false); |
946 ++sync_point_wait_count_; | 951 waiting_for_sync_point_ = true; |
947 manager->sync_point_manager()->AddSyncPointCallback( | 952 manager->sync_point_manager()->AddSyncPointCallback( |
948 sync_point, | 953 sync_point, |
949 base::Bind(&RunOnThread, task_runner_, | 954 base::Bind(&RunOnThread, task_runner_, |
950 base::Bind(&GpuCommandBufferStub::OnWaitSyncPointCompleted, | 955 base::Bind(&GpuCommandBufferStub::OnWaitSyncPointCompleted, |
951 this->AsWeakPtr(), sync_point))); | 956 this->AsWeakPtr(), sync_point))); |
952 return scheduler_->IsScheduled(); | 957 return !waiting_for_sync_point_; |
953 } | 958 } |
954 | 959 |
955 void GpuCommandBufferStub::OnWaitSyncPointCompleted(uint32 sync_point) { | 960 void GpuCommandBufferStub::OnWaitSyncPointCompleted(uint32 sync_point) { |
| 961 DCHECK(waiting_for_sync_point_); |
| 962 DCHECK(!scheduler_->scheduled()); |
| 963 TRACE_EVENT_ASYNC_END1("gpu", "WaitSyncPoint", this, "GpuCommandBufferStub", |
| 964 this); |
956 PullTextureUpdates(sync_point); | 965 PullTextureUpdates(sync_point); |
957 --sync_point_wait_count_; | 966 waiting_for_sync_point_ = false; |
958 if (sync_point_wait_count_ == 0) { | |
959 TRACE_EVENT_ASYNC_END1("gpu", "WaitSyncPoint", this, | |
960 "GpuCommandBufferStub", this); | |
961 } | |
962 scheduler_->SetScheduled(true); | 967 scheduler_->SetScheduled(true); |
963 } | 968 } |
964 | 969 |
965 void GpuCommandBufferStub::PullTextureUpdates(uint32 sync_point) { | 970 void GpuCommandBufferStub::PullTextureUpdates(uint32 sync_point) { |
966 gpu::gles2::MailboxManager* mailbox_manager = | 971 gpu::gles2::MailboxManager* mailbox_manager = |
967 context_group_->mailbox_manager(); | 972 context_group_->mailbox_manager(); |
968 if (mailbox_manager->UsesSync() && MakeCurrent()) | 973 if (mailbox_manager->UsesSync() && MakeCurrent()) |
969 mailbox_manager->PullTextureUpdates(sync_point); | 974 mailbox_manager->PullTextureUpdates(sync_point); |
970 } | 975 } |
971 | 976 |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1204 result)); | 1209 result)); |
1205 } | 1210 } |
1206 | 1211 |
1207 void GpuCommandBufferStub::SendUpdateVSyncParameters(base::TimeTicks timebase, | 1212 void GpuCommandBufferStub::SendUpdateVSyncParameters(base::TimeTicks timebase, |
1208 base::TimeDelta interval) { | 1213 base::TimeDelta interval) { |
1209 Send(new GpuCommandBufferMsg_UpdateVSyncParameters(route_id_, timebase, | 1214 Send(new GpuCommandBufferMsg_UpdateVSyncParameters(route_id_, timebase, |
1210 interval)); | 1215 interval)); |
1211 } | 1216 } |
1212 | 1217 |
1213 } // namespace content | 1218 } // namespace content |
OLD | NEW |