| 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/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
| 9 #include "base/hash.h" | 9 #include "base/hash.h" |
| 10 #include "base/json/json_writer.h" | 10 #include "base/json/json_writer.h" |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) { | 215 bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) { |
| 216 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), | 216 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), |
| 217 "GPUTask", | 217 "GPUTask", |
| 218 "data", | 218 "data", |
| 219 DevToolsChannelData::CreateForChannel(channel())); | 219 DevToolsChannelData::CreateForChannel(channel())); |
| 220 // TODO(yurys): remove devtools_gpu_instrumentation call once DevTools | 220 // TODO(yurys): remove devtools_gpu_instrumentation call once DevTools |
| 221 // Timeline migrates to tracing crbug.com/361045. | 221 // Timeline migrates to tracing crbug.com/361045. |
| 222 devtools_gpu_instrumentation::ScopedGpuTask task(channel()); | 222 devtools_gpu_instrumentation::ScopedGpuTask task(channel()); |
| 223 FastSetActiveURL(active_url_, active_url_hash_); | 223 FastSetActiveURL(active_url_, active_url_hash_); |
| 224 | 224 |
| 225 bool have_context = false; | |
| 226 // Ensure the appropriate GL context is current before handling any IPC | 225 // Ensure the appropriate GL context is current before handling any IPC |
| 227 // messages directed at the command buffer. This ensures that the message | 226 // messages directed at the command buffer. This ensures that the message |
| 228 // handler can assume that the context is current (not necessary for | 227 // handler can assume that the context is current (not necessary for |
| 229 // RetireSyncPoint or WaitSyncPoint). | 228 // RetireSyncPoint or WaitSyncPoint). |
| 230 if (decoder_.get() && | 229 if (decoder_.get() && |
| 231 message.type() != GpuCommandBufferMsg_SetGetBuffer::ID && | 230 message.type() != GpuCommandBufferMsg_SetGetBuffer::ID && |
| 232 message.type() != GpuCommandBufferMsg_WaitForTokenInRange::ID && | 231 message.type() != GpuCommandBufferMsg_WaitForTokenInRange::ID && |
| 233 message.type() != GpuCommandBufferMsg_WaitForGetOffsetInRange::ID && | 232 message.type() != GpuCommandBufferMsg_WaitForGetOffsetInRange::ID && |
| 234 message.type() != GpuCommandBufferMsg_RegisterTransferBuffer::ID && | 233 message.type() != GpuCommandBufferMsg_RegisterTransferBuffer::ID && |
| 235 message.type() != GpuCommandBufferMsg_DestroyTransferBuffer::ID && | 234 message.type() != GpuCommandBufferMsg_DestroyTransferBuffer::ID && |
| 236 message.type() != GpuCommandBufferMsg_RetireSyncPoint::ID && | 235 message.type() != GpuCommandBufferMsg_RetireSyncPoint::ID && |
| 237 message.type() != GpuCommandBufferMsg_SignalSyncPoint::ID && | 236 message.type() != GpuCommandBufferMsg_SignalSyncPoint::ID && |
| 237 message.type() != GpuCommandBufferMsg_AsyncFlush::ID && |
| 238 message.type() != | 238 message.type() != |
| 239 GpuCommandBufferMsg_SetClientHasMemoryAllocationChangedCallback::ID) { | 239 GpuCommandBufferMsg_SetClientHasMemoryAllocationChangedCallback::ID) { |
| 240 if (!MakeCurrent()) | 240 if (!MakeCurrent()) |
| 241 return false; | 241 return false; |
| 242 have_context = true; | |
| 243 } | 242 } |
| 244 | 243 |
| 245 // Always use IPC_MESSAGE_HANDLER_DELAY_REPLY for synchronous message handlers | 244 // Always use IPC_MESSAGE_HANDLER_DELAY_REPLY for synchronous message handlers |
| 246 // here. This is so the reply can be delayed if the scheduler is unscheduled. | 245 // here. This is so the reply can be delayed if the scheduler is unscheduled. |
| 247 bool handled = true; | 246 bool handled = true; |
| 248 IPC_BEGIN_MESSAGE_MAP(GpuCommandBufferStub, message) | 247 IPC_BEGIN_MESSAGE_MAP(GpuCommandBufferStub, message) |
| 249 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_Initialize, | 248 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_Initialize, |
| 250 OnInitialize); | 249 OnInitialize); |
| 251 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_SetGetBuffer, | 250 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_SetGetBuffer, |
| 252 OnSetGetBuffer); | 251 OnSetGetBuffer); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 279 OnSetClientHasMemoryAllocationChangedCallback) | 278 OnSetClientHasMemoryAllocationChangedCallback) |
| 280 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateImage, OnCreateImage); | 279 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateImage, OnCreateImage); |
| 281 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyImage, OnDestroyImage); | 280 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyImage, OnDestroyImage); |
| 282 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateStreamTexture, | 281 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateStreamTexture, |
| 283 OnCreateStreamTexture) | 282 OnCreateStreamTexture) |
| 284 IPC_MESSAGE_UNHANDLED(handled = false) | 283 IPC_MESSAGE_UNHANDLED(handled = false) |
| 285 IPC_END_MESSAGE_MAP() | 284 IPC_END_MESSAGE_MAP() |
| 286 | 285 |
| 287 CheckCompleteWaits(); | 286 CheckCompleteWaits(); |
| 288 | 287 |
| 289 if (have_context) { | 288 // Ensure that any delayed work that was created will be handled. |
| 290 // Ensure that any delayed work that was created will be handled. | 289 ScheduleDelayedWork(kHandleMoreWorkPeriodMs); |
| 291 ScheduleDelayedWork(kHandleMoreWorkPeriodMs); | |
| 292 } | |
| 293 | 290 |
| 294 DCHECK(handled); | 291 DCHECK(handled); |
| 295 return handled; | 292 return handled; |
| 296 } | 293 } |
| 297 | 294 |
| 298 bool GpuCommandBufferStub::Send(IPC::Message* message) { | 295 bool GpuCommandBufferStub::Send(IPC::Message* message) { |
| 299 return channel_->Send(message); | 296 return channel_->Send(message); |
| 300 } | 297 } |
| 301 | 298 |
| 302 bool GpuCommandBufferStub::IsScheduled() { | 299 bool GpuCommandBufferStub::IsScheduled() { |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 switches::kEnableGPUServiceLogging)) { | 573 switches::kEnableGPUServiceLogging)) { |
| 577 decoder_->set_log_commands(true); | 574 decoder_->set_log_commands(true); |
| 578 } | 575 } |
| 579 | 576 |
| 580 decoder_->GetLogger()->SetMsgCallback( | 577 decoder_->GetLogger()->SetMsgCallback( |
| 581 base::Bind(&GpuCommandBufferStub::SendConsoleMessage, | 578 base::Bind(&GpuCommandBufferStub::SendConsoleMessage, |
| 582 base::Unretained(this))); | 579 base::Unretained(this))); |
| 583 decoder_->SetShaderCacheCallback( | 580 decoder_->SetShaderCacheCallback( |
| 584 base::Bind(&GpuCommandBufferStub::SendCachedShader, | 581 base::Bind(&GpuCommandBufferStub::SendCachedShader, |
| 585 base::Unretained(this))); | 582 base::Unretained(this))); |
| 586 decoder_->SetWaitSyncPointCallback( | |
| 587 base::Bind(&GpuCommandBufferStub::OnWaitSyncPoint, | |
| 588 base::Unretained(this))); | |
| 589 | 583 |
| 590 command_buffer_->SetPutOffsetChangeCallback( | 584 command_buffer_->SetPutOffsetChangeCallback( |
| 591 base::Bind(&GpuCommandBufferStub::PutChanged, base::Unretained(this))); | 585 base::Bind(&GpuCommandBufferStub::PutChanged, base::Unretained(this))); |
| 592 command_buffer_->SetGetBufferChangeCallback( | 586 command_buffer_->SetGetBufferChangeCallback( |
| 593 base::Bind(&gpu::GpuScheduler::SetGetBuffer, | 587 base::Bind(&gpu::GpuScheduler::SetGetBuffer, |
| 594 base::Unretained(scheduler_.get()))); | 588 base::Unretained(scheduler_.get()))); |
| 595 command_buffer_->SetParseErrorCallback( | 589 command_buffer_->SetParseErrorCallback( |
| 596 base::Bind(&GpuCommandBufferStub::OnParseError, base::Unretained(this))); | 590 base::Bind(&GpuCommandBufferStub::OnParseError, base::Unretained(this))); |
| 597 scheduler_->SetSchedulingChangedCallback( | 591 scheduler_->SetSchedulingChangedCallback( |
| 598 base::Bind(&GpuChannel::StubSchedulingChanged, | 592 base::Bind(&GpuChannel::StubSchedulingChanged, |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 wait_for_get_offset_->reply.get(), state); | 736 wait_for_get_offset_->reply.get(), state); |
| 743 Send(wait_for_get_offset_->reply.release()); | 737 Send(wait_for_get_offset_->reply.release()); |
| 744 wait_for_get_offset_.reset(); | 738 wait_for_get_offset_.reset(); |
| 745 } | 739 } |
| 746 } | 740 } |
| 747 } | 741 } |
| 748 | 742 |
| 749 void GpuCommandBufferStub::OnAsyncFlush( | 743 void GpuCommandBufferStub::OnAsyncFlush( |
| 750 int32 put_offset, | 744 int32 put_offset, |
| 751 uint32 flush_count, | 745 uint32 flush_count, |
| 746 const std::vector<uint32>& sync_points, |
| 752 const std::vector<ui::LatencyInfo>& latency_info) { | 747 const std::vector<ui::LatencyInfo>& latency_info) { |
| 753 TRACE_EVENT1( | 748 TRACE_EVENT1( |
| 754 "gpu", "GpuCommandBufferStub::OnAsyncFlush", "put_offset", put_offset); | 749 "gpu", "GpuCommandBufferStub::OnAsyncFlush", "put_offset", put_offset); |
| 755 | 750 |
| 756 if (ui::LatencyInfo::Verify(latency_info, | 751 if (ui::LatencyInfo::Verify(latency_info, |
| 757 "GpuCommandBufferStub::OnAsyncFlush") && | 752 "GpuCommandBufferStub::OnAsyncFlush") && |
| 758 !latency_info_callback_.is_null()) { | 753 !latency_info_callback_.is_null()) { |
| 759 latency_info_callback_.Run(latency_info); | 754 latency_info_callback_.Run(latency_info); |
| 760 } | 755 } |
| 756 for (uint32 sync_point : sync_points) { |
| 757 WaitSyncPoint(sync_point); |
| 758 } |
| 759 if (scheduler_->IsScheduled()) |
| 760 MakeCurrent(); |
| 761 DCHECK(command_buffer_.get()); | 761 DCHECK(command_buffer_.get()); |
| 762 if (flush_count - last_flush_count_ < 0x8000000U) { | 762 if (flush_count - last_flush_count_ < 0x8000000U) { |
| 763 last_flush_count_ = flush_count; | 763 last_flush_count_ = flush_count; |
| 764 command_buffer_->Flush(put_offset); | 764 command_buffer_->Flush(put_offset, sync_points); |
| 765 } else { | 765 } else { |
| 766 // We received this message out-of-order. This should not happen but is here | 766 // We received this message out-of-order. This should not happen but is here |
| 767 // to catch regressions. Ignore the message. | 767 // to catch regressions. Ignore the message. |
| 768 NOTREACHED() << "Received a Flush message out-of-order"; | 768 NOTREACHED() << "Received a Flush message out-of-order"; |
| 769 } | 769 } |
| 770 | 770 |
| 771 ReportState(); | 771 ReportState(); |
| 772 } | 772 } |
| 773 | 773 |
| 774 void GpuCommandBufferStub::OnRescheduled() { | 774 void GpuCommandBufferStub::OnRescheduled() { |
| 775 gpu::CommandBuffer::State pre_state = command_buffer_->GetLastState(); | 775 gpu::CommandBuffer::State pre_state = command_buffer_->GetLastState(); |
| 776 command_buffer_->Flush(command_buffer_->GetPutOffset()); | 776 command_buffer_->Flush(command_buffer_->GetPutOffset(), |
| 777 std::vector<uint32>()); |
| 777 gpu::CommandBuffer::State post_state = command_buffer_->GetLastState(); | 778 gpu::CommandBuffer::State post_state = command_buffer_->GetLastState(); |
| 778 | 779 |
| 779 if (pre_state.get_offset != post_state.get_offset) | 780 if (pre_state.get_offset != post_state.get_offset) |
| 780 ReportState(); | 781 ReportState(); |
| 781 } | 782 } |
| 782 | 783 |
| 783 void GpuCommandBufferStub::OnRegisterTransferBuffer( | 784 void GpuCommandBufferStub::OnRegisterTransferBuffer( |
| 784 int32 id, | 785 int32 id, |
| 785 base::SharedMemoryHandle transfer_buffer, | 786 base::SharedMemoryHandle transfer_buffer, |
| 786 uint32 size) { | 787 uint32 size) { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 861 sync_points_.push_back(sync_point); | 862 sync_points_.push_back(sync_point); |
| 862 } | 863 } |
| 863 | 864 |
| 864 void GpuCommandBufferStub::OnRetireSyncPoint(uint32 sync_point) { | 865 void GpuCommandBufferStub::OnRetireSyncPoint(uint32 sync_point) { |
| 865 DCHECK(!sync_points_.empty() && sync_points_.front() == sync_point); | 866 DCHECK(!sync_points_.empty() && sync_points_.front() == sync_point); |
| 866 sync_points_.pop_front(); | 867 sync_points_.pop_front(); |
| 867 GpuChannelManager* manager = channel_->gpu_channel_manager(); | 868 GpuChannelManager* manager = channel_->gpu_channel_manager(); |
| 868 manager->sync_point_manager()->RetireSyncPoint(sync_point); | 869 manager->sync_point_manager()->RetireSyncPoint(sync_point); |
| 869 } | 870 } |
| 870 | 871 |
| 871 bool GpuCommandBufferStub::OnWaitSyncPoint(uint32 sync_point) { | 872 void GpuCommandBufferStub::WaitSyncPoint(uint32 sync_point) { |
| 872 if (!sync_point) | 873 if (!sync_point) |
| 873 return true; | 874 return; |
| 874 GpuChannelManager* manager = channel_->gpu_channel_manager(); | 875 GpuChannelManager* manager = channel_->gpu_channel_manager(); |
| 875 if (manager->sync_point_manager()->IsSyncPointRetired(sync_point)) | 876 if (manager->sync_point_manager()->IsSyncPointRetired(sync_point)) |
| 876 return true; | 877 return; |
| 877 | 878 |
| 878 if (sync_point_wait_count_ == 0) { | 879 if (sync_point_wait_count_ == 0) { |
| 879 TRACE_EVENT_ASYNC_BEGIN1("gpu", "WaitSyncPoint", this, | 880 TRACE_EVENT_ASYNC_BEGIN1("gpu", "WaitSyncPoint", this, |
| 880 "GpuCommandBufferStub", this); | 881 "GpuCommandBufferStub", this); |
| 881 } | 882 } |
| 882 scheduler_->SetScheduled(false); | 883 scheduler_->SetScheduled(false); |
| 883 ++sync_point_wait_count_; | 884 ++sync_point_wait_count_; |
| 884 manager->sync_point_manager()->AddSyncPointCallback( | 885 manager->sync_point_manager()->AddSyncPointCallback( |
| 885 sync_point, | 886 sync_point, |
| 886 base::Bind(&GpuCommandBufferStub::OnSyncPointRetired, | 887 base::Bind(&GpuCommandBufferStub::OnSyncPointRetired, |
| 887 this->AsWeakPtr())); | 888 this->AsWeakPtr())); |
| 888 return scheduler_->IsScheduled(); | |
| 889 } | 889 } |
| 890 | 890 |
| 891 void GpuCommandBufferStub::OnSyncPointRetired() { | 891 void GpuCommandBufferStub::OnSyncPointRetired() { |
| 892 --sync_point_wait_count_; | 892 --sync_point_wait_count_; |
| 893 if (sync_point_wait_count_ == 0) { | 893 if (sync_point_wait_count_ == 0) { |
| 894 TRACE_EVENT_ASYNC_END1("gpu", "WaitSyncPoint", this, | 894 TRACE_EVENT_ASYNC_END1("gpu", "WaitSyncPoint", this, |
| 895 "GpuCommandBufferStub", this); | 895 "GpuCommandBufferStub", this); |
| 896 } | 896 } |
| 897 scheduler_->SetScheduled(true); | 897 scheduler_->SetScheduled(true); |
| 898 } | 898 } |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1083 uint64 GpuCommandBufferStub::GetMemoryUsage() const { | 1083 uint64 GpuCommandBufferStub::GetMemoryUsage() const { |
| 1084 return GetMemoryManager()->GetClientMemoryUsage(this); | 1084 return GetMemoryManager()->GetClientMemoryUsage(this); |
| 1085 } | 1085 } |
| 1086 | 1086 |
| 1087 void GpuCommandBufferStub::SwapBuffersCompleted( | 1087 void GpuCommandBufferStub::SwapBuffersCompleted( |
| 1088 const std::vector<ui::LatencyInfo>& latency_info) { | 1088 const std::vector<ui::LatencyInfo>& latency_info) { |
| 1089 Send(new GpuCommandBufferMsg_SwapBuffersCompleted(route_id_, latency_info)); | 1089 Send(new GpuCommandBufferMsg_SwapBuffersCompleted(route_id_, latency_info)); |
| 1090 } | 1090 } |
| 1091 | 1091 |
| 1092 } // namespace content | 1092 } // namespace content |
| OLD | NEW |