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 #include "gpu/ipc/service/gpu_command_buffer_stub.h" | 5 #include "gpu/ipc/service/gpu_command_buffer_stub.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| 11 #include "base/command_line.h" | |
| 11 #include "base/hash.h" | 12 #include "base/hash.h" |
| 12 #include "base/json/json_writer.h" | 13 #include "base/json/json_writer.h" |
| 13 #include "base/macros.h" | 14 #include "base/macros.h" |
| 14 #include "base/memory/memory_pressure_listener.h" | 15 #include "base/memory/memory_pressure_listener.h" |
| 15 #include "base/memory/ptr_util.h" | 16 #include "base/memory/ptr_util.h" |
| 16 #include "base/memory/shared_memory.h" | 17 #include "base/memory/shared_memory.h" |
| 18 #include "base/metrics/field_trial.h" | |
| 17 #include "base/metrics/histogram_macros.h" | 19 #include "base/metrics/histogram_macros.h" |
| 18 #include "base/time/time.h" | 20 #include "base/time/time.h" |
| 19 #include "base/trace_event/trace_event.h" | 21 #include "base/trace_event/trace_event.h" |
| 20 #include "build/build_config.h" | 22 #include "build/build_config.h" |
| 21 #include "gpu/command_buffer/common/constants.h" | 23 #include "gpu/command_buffer/common/constants.h" |
| 22 #include "gpu/command_buffer/common/gpu_memory_buffer_support.h" | 24 #include "gpu/command_buffer/common/gpu_memory_buffer_support.h" |
| 23 #include "gpu/command_buffer/common/mailbox.h" | 25 #include "gpu/command_buffer/common/mailbox.h" |
| 24 #include "gpu/command_buffer/common/sync_token.h" | 26 #include "gpu/command_buffer/common/sync_token.h" |
| 25 #include "gpu/command_buffer/service/gl_context_virtual.h" | 27 #include "gpu/command_buffer/service/gl_context_virtual.h" |
| 26 #include "gpu/command_buffer/service/gl_state_restorer_impl.h" | 28 #include "gpu/command_buffer/service/gl_state_restorer_impl.h" |
| 27 #include "gpu/command_buffer/service/image_manager.h" | 29 #include "gpu/command_buffer/service/image_manager.h" |
| 28 #include "gpu/command_buffer/service/logger.h" | 30 #include "gpu/command_buffer/service/logger.h" |
| 29 #include "gpu/command_buffer/service/mailbox_manager.h" | 31 #include "gpu/command_buffer/service/mailbox_manager.h" |
| 30 #include "gpu/command_buffer/service/memory_tracking.h" | 32 #include "gpu/command_buffer/service/memory_tracking.h" |
| 31 #include "gpu/command_buffer/service/query_manager.h" | 33 #include "gpu/command_buffer/service/query_manager.h" |
| 32 #include "gpu/command_buffer/service/service_utils.h" | 34 #include "gpu/command_buffer/service/service_utils.h" |
| 33 #include "gpu/command_buffer/service/sync_point_manager.h" | 35 #include "gpu/command_buffer/service/sync_point_manager.h" |
| 34 #include "gpu/command_buffer/service/transfer_buffer_manager.h" | 36 #include "gpu/command_buffer/service/transfer_buffer_manager.h" |
| 35 #include "gpu/ipc/common/gpu_messages.h" | 37 #include "gpu/ipc/common/gpu_messages.h" |
| 36 #include "gpu/ipc/service/gpu_channel.h" | 38 #include "gpu/ipc/service/gpu_channel.h" |
| 37 #include "gpu/ipc/service/gpu_channel_manager.h" | 39 #include "gpu/ipc/service/gpu_channel_manager.h" |
| 38 #include "gpu/ipc/service/gpu_channel_manager_delegate.h" | 40 #include "gpu/ipc/service/gpu_channel_manager_delegate.h" |
| 39 #include "gpu/ipc/service/gpu_memory_buffer_factory.h" | 41 #include "gpu/ipc/service/gpu_memory_buffer_factory.h" |
| 40 #include "gpu/ipc/service/gpu_memory_manager.h" | 42 #include "gpu/ipc/service/gpu_memory_manager.h" |
| 41 #include "gpu/ipc/service/gpu_memory_tracking.h" | 43 #include "gpu/ipc/service/gpu_memory_tracking.h" |
| 44 #include "gpu/ipc/service/gpu_vsync_provider.h" | |
| 42 #include "gpu/ipc/service/gpu_watchdog_thread.h" | 45 #include "gpu/ipc/service/gpu_watchdog_thread.h" |
| 43 #include "gpu/ipc/service/image_transport_surface.h" | 46 #include "gpu/ipc/service/image_transport_surface.h" |
| 44 #include "ui/gl/gl_bindings.h" | 47 #include "ui/gl/gl_bindings.h" |
| 45 #include "ui/gl/gl_context.h" | 48 #include "ui/gl/gl_context.h" |
| 46 #include "ui/gl/gl_image.h" | 49 #include "ui/gl/gl_image.h" |
| 47 #include "ui/gl/gl_implementation.h" | 50 #include "ui/gl/gl_implementation.h" |
| 48 #include "ui/gl/gl_switches.h" | 51 #include "ui/gl/gl_switches.h" |
| 49 #include "ui/gl/init/gl_factory.h" | 52 #include "ui/gl/init/gl_factory.h" |
| 50 | 53 |
| 51 #if defined(OS_WIN) | 54 #if defined(OS_WIN) |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 211 res->SetInteger("renderer_pid", channel->GetClientPID()); | 214 res->SetInteger("renderer_pid", channel->GetClientPID()); |
| 212 res->SetDouble("used_bytes", channel->GetMemoryUsage()); | 215 res->SetDouble("used_bytes", channel->GetMemoryUsage()); |
| 213 return base::WrapUnique(new DevToolsChannelData(res.release())); | 216 return base::WrapUnique(new DevToolsChannelData(res.release())); |
| 214 } | 217 } |
| 215 | 218 |
| 216 CommandBufferId GetCommandBufferID(int channel_id, int32_t route_id) { | 219 CommandBufferId GetCommandBufferID(int channel_id, int32_t route_id) { |
| 217 return CommandBufferId::FromUnsafeValue( | 220 return CommandBufferId::FromUnsafeValue( |
| 218 (static_cast<uint64_t>(channel_id) << 32) | route_id); | 221 (static_cast<uint64_t>(channel_id) << 32) | route_id); |
| 219 } | 222 } |
| 220 | 223 |
| 224 bool IsGpuVSyncSignalSupported() { | |
|
sunnyps
2017/01/25 01:36:41
This should be passed from the browser to gpu proc
stanisc
2017/01/26 02:14:13
I think it is doesn't make much sense to over-comp
| |
| 225 #if defined(OS_WIN) | |
| 226 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | |
| 227 if (command_line->HasSwitch(switches::kUseD3DVSync)) | |
| 228 return true; | |
| 229 | |
| 230 const std::string group_name = | |
| 231 base::FieldTrialList::FindFullName("UseD3DVSync"); | |
|
jbauman
2017/01/25 00:00:16
Could you use base::Feature here instead?
stanisc
2017/01/26 02:14:12
Done.
| |
| 232 return group_name == "Enabled"; | |
| 233 #else | |
| 234 return false; | |
| 235 #endif // defined(OS_WIN) | |
| 236 } | |
| 237 | |
| 221 } // namespace | 238 } // namespace |
| 222 | 239 |
| 223 std::unique_ptr<GpuCommandBufferStub> GpuCommandBufferStub::Create( | 240 std::unique_ptr<GpuCommandBufferStub> GpuCommandBufferStub::Create( |
| 224 GpuChannel* channel, | 241 GpuChannel* channel, |
| 225 GpuCommandBufferStub* share_command_buffer_stub, | 242 GpuCommandBufferStub* share_command_buffer_stub, |
| 226 const GPUCreateCommandBufferConfig& init_params, | 243 const GPUCreateCommandBufferConfig& init_params, |
| 227 int32_t route_id, | 244 int32_t route_id, |
| 228 std::unique_ptr<base::SharedMemory> shared_state_shm) { | 245 std::unique_ptr<base::SharedMemory> shared_state_shm) { |
| 229 std::unique_ptr<GpuCommandBufferStub> stub( | 246 std::unique_ptr<GpuCommandBufferStub> stub( |
| 230 new GpuCommandBufferStub(channel, init_params, route_id)); | 247 new GpuCommandBufferStub(channel, init_params, route_id)); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 242 initialized_(false), | 259 initialized_(false), |
| 243 surface_handle_(init_params.surface_handle), | 260 surface_handle_(init_params.surface_handle), |
| 244 use_virtualized_gl_context_(false), | 261 use_virtualized_gl_context_(false), |
| 245 command_buffer_id_(GetCommandBufferID(channel->client_id(), route_id)), | 262 command_buffer_id_(GetCommandBufferID(channel->client_id(), route_id)), |
| 246 stream_id_(init_params.stream_id), | 263 stream_id_(init_params.stream_id), |
| 247 route_id_(route_id), | 264 route_id_(route_id), |
| 248 last_flush_count_(0), | 265 last_flush_count_(0), |
| 249 waiting_for_sync_point_(false), | 266 waiting_for_sync_point_(false), |
| 250 previous_processed_num_(0), | 267 previous_processed_num_(0), |
| 251 active_url_(init_params.active_url), | 268 active_url_(init_params.active_url), |
| 252 active_url_hash_(base::Hash(active_url_.possibly_invalid_spec())) {} | 269 active_url_hash_(base::Hash(active_url_.possibly_invalid_spec())), |
| 270 gpu_vsync_signal_supported_(IsGpuVSyncSignalSupported()) {} | |
| 253 | 271 |
| 254 GpuCommandBufferStub::~GpuCommandBufferStub() { | 272 GpuCommandBufferStub::~GpuCommandBufferStub() { |
| 255 Destroy(); | 273 Destroy(); |
| 256 } | 274 } |
| 257 | 275 |
| 258 GpuMemoryManager* GpuCommandBufferStub::GetMemoryManager() const { | 276 GpuMemoryManager* GpuCommandBufferStub::GetMemoryManager() const { |
| 259 return channel()->gpu_channel_manager()->gpu_memory_manager(); | 277 return channel()->gpu_channel_manager()->gpu_memory_manager(); |
| 260 } | 278 } |
| 261 | 279 |
| 262 bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) { | 280 bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 303 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_WaitSyncToken, | 321 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_WaitSyncToken, |
| 304 OnWaitSyncToken) | 322 OnWaitSyncToken) |
| 305 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalSyncToken, | 323 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalSyncToken, |
| 306 OnSignalSyncToken) | 324 OnSignalSyncToken) |
| 307 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalQuery, | 325 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalQuery, |
| 308 OnSignalQuery) | 326 OnSignalQuery) |
| 309 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateImage, OnCreateImage); | 327 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateImage, OnCreateImage); |
| 310 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyImage, OnDestroyImage); | 328 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyImage, OnDestroyImage); |
| 311 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateStreamTexture, | 329 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateStreamTexture, |
| 312 OnCreateStreamTexture) | 330 OnCreateStreamTexture) |
| 331 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SetNeedsVSync, OnSetNeedsVSync); | |
| 313 IPC_MESSAGE_UNHANDLED(handled = false) | 332 IPC_MESSAGE_UNHANDLED(handled = false) |
| 314 IPC_END_MESSAGE_MAP() | 333 IPC_END_MESSAGE_MAP() |
| 315 | 334 |
| 316 CheckCompleteWaits(); | 335 CheckCompleteWaits(); |
| 317 | 336 |
| 318 // Ensure that any delayed work that was created will be handled. | 337 // Ensure that any delayed work that was created will be handled. |
| 319 if (have_context) { | 338 if (have_context) { |
| 320 if (executor_) | 339 if (executor_) |
| 321 executor_->ProcessPendingQueries(); | 340 executor_->ProcessPendingQueries(); |
| 322 ScheduleDelayedWork( | 341 ScheduleDelayedWork( |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 363 return context_group_->feature_info(); | 382 return context_group_->feature_info(); |
| 364 } | 383 } |
| 365 | 384 |
| 366 void GpuCommandBufferStub::SetLatencyInfoCallback( | 385 void GpuCommandBufferStub::SetLatencyInfoCallback( |
| 367 const LatencyInfoCallback& callback) { | 386 const LatencyInfoCallback& callback) { |
| 368 latency_info_callback_ = callback; | 387 latency_info_callback_ = callback; |
| 369 } | 388 } |
| 370 | 389 |
| 371 void GpuCommandBufferStub::UpdateVSyncParameters(base::TimeTicks timebase, | 390 void GpuCommandBufferStub::UpdateVSyncParameters(base::TimeTicks timebase, |
| 372 base::TimeDelta interval) { | 391 base::TimeDelta interval) { |
| 392 #if defined(OS_WIN) | |
| 393 if (gpu_vsync_signal_supported_) { | |
| 394 base::AutoLock lock(vsync_lock_); | |
| 395 vsync_interval_ = interval; | |
| 396 return; | |
| 397 } | |
| 398 #endif // defined(OS_WIN) | |
| 399 | |
| 400 SendUpdatedVSyncParameters(timebase, interval); | |
| 401 } | |
| 402 | |
| 403 void GpuCommandBufferStub::UpdateGpuVSync(base::TimeTicks timestamp) { | |
| 404 DCHECK(gpu_vsync_signal_supported_); | |
| 405 | |
| 406 #if defined(OS_WIN) | |
| 407 | |
| 408 base::TimeDelta interval; | |
| 409 { | |
| 410 base::AutoLock lock(vsync_lock_); | |
| 411 interval = vsync_interval_; | |
| 412 } | |
| 413 | |
| 414 SendUpdatedVSyncParameters(timestamp, interval); | |
| 415 #endif // defined(OS_WIN) | |
| 416 } | |
| 417 | |
| 418 void GpuCommandBufferStub::SendUpdatedVSyncParameters( | |
|
jbauman
2017/01/25 00:00:16
Technically Send on an IPC::SyncChannel can only b
stanisc
2017/01/26 02:14:13
Done.
| |
| 419 base::TimeTicks timebase, | |
| 420 base::TimeDelta interval) { | |
| 373 Send(new GpuCommandBufferMsg_UpdateVSyncParameters(route_id_, timebase, | 421 Send(new GpuCommandBufferMsg_UpdateVSyncParameters(route_id_, timebase, |
| 374 interval)); | 422 interval)); |
| 375 } | 423 } |
| 376 | 424 |
| 377 bool GpuCommandBufferStub::IsScheduled() { | 425 bool GpuCommandBufferStub::IsScheduled() { |
| 378 return (!executor_.get() || executor_->scheduled()); | 426 return (!executor_.get() || executor_->scheduled()); |
| 379 } | 427 } |
| 380 | 428 |
| 381 void GpuCommandBufferStub::PollWork() { | 429 void GpuCommandBufferStub::PollWork() { |
| 382 // Post another delayed task if we have not yet reached the time at which | 430 // Post another delayed task if we have not yet reached the time at which |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 514 | 562 |
| 515 if (decoder_) | 563 if (decoder_) |
| 516 decoder_->set_engine(NULL); | 564 decoder_->set_engine(NULL); |
| 517 | 565 |
| 518 // The scheduler has raw references to the decoder and the command buffer so | 566 // The scheduler has raw references to the decoder and the command buffer so |
| 519 // destroy it before those. | 567 // destroy it before those. |
| 520 executor_.reset(); | 568 executor_.reset(); |
| 521 | 569 |
| 522 sync_point_client_.reset(); | 570 sync_point_client_.reset(); |
| 523 | 571 |
| 572 vsync_provider_.reset(); | |
| 573 | |
| 524 bool have_context = false; | 574 bool have_context = false; |
| 525 if (decoder_ && decoder_->GetGLContext()) { | 575 if (decoder_ && decoder_->GetGLContext()) { |
| 526 // Try to make the context current regardless of whether it was lost, so we | 576 // Try to make the context current regardless of whether it was lost, so we |
| 527 // don't leak resources. | 577 // don't leak resources. |
| 528 have_context = decoder_->GetGLContext()->MakeCurrent(surface_.get()); | 578 have_context = decoder_->GetGLContext()->MakeCurrent(surface_.get()); |
| 529 } | 579 } |
| 530 for (auto& observer : destruction_observers_) | 580 for (auto& observer : destruction_observers_) |
| 531 observer.OnWillDestroyStub(); | 581 observer.OnWillDestroyStub(); |
| 532 | 582 |
| 533 if (decoder_) { | 583 if (decoder_) { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 627 } else { | 677 } else { |
| 628 surface_ = ImageTransportSurface::CreateNativeSurface( | 678 surface_ = ImageTransportSurface::CreateNativeSurface( |
| 629 AsWeakPtr(), surface_handle_, surface_format); | 679 AsWeakPtr(), surface_handle_, surface_format); |
| 630 if (!surface_ || !surface_->Initialize(surface_format)) { | 680 if (!surface_ || !surface_->Initialize(surface_format)) { |
| 631 surface_ = nullptr; | 681 surface_ = nullptr; |
| 632 DLOG(ERROR) << "Failed to create surface."; | 682 DLOG(ERROR) << "Failed to create surface."; |
| 633 return false; | 683 return false; |
| 634 } | 684 } |
| 635 } | 685 } |
| 636 | 686 |
| 687 if (IsGpuVSyncSignalSupported()) { | |
| 688 vsync_provider_ = GpuVSyncProvider::Create( | |
|
jbauman
2017/01/25 00:00:16
Only create this for stubs that aren't "offscreen"
stanisc
2017/01/26 02:14:13
Done.
| |
| 689 base::Bind(&GpuCommandBufferStub::UpdateGpuVSync, | |
| 690 base::Unretained(this)), | |
| 691 surface_handle_); | |
| 692 } | |
| 693 | |
| 637 scoped_refptr<gl::GLContext> context; | 694 scoped_refptr<gl::GLContext> context; |
| 638 gl::GLShareGroup* gl_share_group = channel_->share_group(); | 695 gl::GLShareGroup* gl_share_group = channel_->share_group(); |
| 639 if (use_virtualized_gl_context_ && gl_share_group) { | 696 if (use_virtualized_gl_context_ && gl_share_group) { |
| 640 context = gl_share_group->GetSharedContext(surface_.get()); | 697 context = gl_share_group->GetSharedContext(surface_.get()); |
| 641 if (!context.get()) { | 698 if (!context.get()) { |
| 642 context = gl::init::CreateGLContext( | 699 context = gl::init::CreateGLContext( |
| 643 gl_share_group, surface_.get(), | 700 gl_share_group, surface_.get(), |
| 644 GenerateGLContextAttribs(init_params.attribs, | 701 GenerateGLContextAttribs(init_params.attribs, |
| 645 context_group_->gpu_preferences())); | 702 context_group_->gpu_preferences())); |
| 646 if (!context.get()) { | 703 if (!context.get()) { |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 763 } | 820 } |
| 764 | 821 |
| 765 void GpuCommandBufferStub::OnSetGetBuffer(int32_t shm_id, | 822 void GpuCommandBufferStub::OnSetGetBuffer(int32_t shm_id, |
| 766 IPC::Message* reply_message) { | 823 IPC::Message* reply_message) { |
| 767 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSetGetBuffer"); | 824 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSetGetBuffer"); |
| 768 if (command_buffer_) | 825 if (command_buffer_) |
| 769 command_buffer_->SetGetBuffer(shm_id); | 826 command_buffer_->SetGetBuffer(shm_id); |
| 770 Send(reply_message); | 827 Send(reply_message); |
| 771 } | 828 } |
| 772 | 829 |
| 830 void GpuCommandBufferStub::OnSetNeedsVSync(bool needs_vsync) { | |
| 831 DCHECK(vsync_provider_); | |
|
jbauman
2017/01/25 00:00:16
if (!vsync_provider_) return;
This message could
stanisc
2017/01/26 02:14:13
Done.
| |
| 832 vsync_provider_->SetNeedsVSync(needs_vsync); | |
| 833 } | |
| 834 | |
| 773 void GpuCommandBufferStub::OnTakeFrontBuffer(const Mailbox& mailbox) { | 835 void GpuCommandBufferStub::OnTakeFrontBuffer(const Mailbox& mailbox) { |
| 774 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnTakeFrontBuffer"); | 836 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnTakeFrontBuffer"); |
| 775 if (!decoder_) { | 837 if (!decoder_) { |
| 776 LOG(ERROR) << "Can't take front buffer before initialization."; | 838 LOG(ERROR) << "Can't take front buffer before initialization."; |
| 777 return; | 839 return; |
| 778 } | 840 } |
| 779 | 841 |
| 780 decoder_->TakeFrontBuffer(mailbox); | 842 decoder_->TakeFrontBuffer(mailbox); |
| 781 } | 843 } |
| 782 | 844 |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1202 command_buffer_->GetLastState().error == error::kLostContext) | 1264 command_buffer_->GetLastState().error == error::kLostContext) |
| 1203 return; | 1265 return; |
| 1204 | 1266 |
| 1205 command_buffer_->SetContextLostReason(error::kUnknown); | 1267 command_buffer_->SetContextLostReason(error::kUnknown); |
| 1206 if (decoder_) | 1268 if (decoder_) |
| 1207 decoder_->MarkContextLost(error::kUnknown); | 1269 decoder_->MarkContextLost(error::kUnknown); |
| 1208 command_buffer_->SetParseError(error::kLostContext); | 1270 command_buffer_->SetParseError(error::kLostContext); |
| 1209 } | 1271 } |
| 1210 | 1272 |
| 1211 } // namespace gpu | 1273 } // namespace gpu |
| OLD | NEW |