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

Side by Side Diff: content/browser/compositor/gpu_process_transport_factory.cc

Issue 2626413002: Route D3D VSync signal to Compositor (Closed)
Patch Set: Limit GPU VSync to Win8+ Created 3 years, 10 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "content/browser/compositor/gpu_process_transport_factory.h" 5 #include "content/browser/compositor/gpu_process_transport_factory.h"
6 6
7 #include <string> 7 #include <string>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 #include "services/service_manager/runner/common/client_util.h" 51 #include "services/service_manager/runner/common/client_util.h"
52 #include "services/ui/public/cpp/gpu/context_provider_command_buffer.h" 52 #include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
53 #include "third_party/khronos/GLES2/gl2.h" 53 #include "third_party/khronos/GLES2/gl2.h"
54 #include "ui/compositor/compositor.h" 54 #include "ui/compositor/compositor.h"
55 #include "ui/compositor/compositor_constants.h" 55 #include "ui/compositor/compositor_constants.h"
56 #include "ui/compositor/compositor_switches.h" 56 #include "ui/compositor/compositor_switches.h"
57 #include "ui/compositor/layer.h" 57 #include "ui/compositor/layer.h"
58 #include "ui/display/types/display_snapshot.h" 58 #include "ui/display/types/display_snapshot.h"
59 #include "ui/gfx/geometry/size.h" 59 #include "ui/gfx/geometry/size.h"
60 #include "ui/gfx/switches.h" 60 #include "ui/gfx/switches.h"
61 #include "ui/gl/gl_switches.h"
61 62
62 #if defined(USE_AURA) 63 #if defined(USE_AURA)
63 #include "content/browser/compositor/mus_browser_compositor_output_surface.h" 64 #include "content/browser/compositor/mus_browser_compositor_output_surface.h"
64 #include "content/public/common/service_manager_connection.h" 65 #include "content/public/common/service_manager_connection.h"
65 #include "ui/aura/window_tree_host.h" 66 #include "ui/aura/window_tree_host.h"
66 #endif 67 #endif
67 68
68 #if defined(OS_WIN) 69 #if defined(OS_WIN)
69 #include "components/display_compositor/compositor_overlay_candidate_validator_w in.h" 70 #include "components/display_compositor/compositor_overlay_candidate_validator_w in.h"
70 #include "content/browser/compositor/software_output_device_win.h" 71 #include "content/browser/compositor/software_output_device_win.h"
(...skipping 30 matching lines...) Expand all
101 using gpu::gles2::GLES2Interface; 102 using gpu::gles2::GLES2Interface;
102 103
103 namespace { 104 namespace {
104 105
105 const int kNumRetriesBeforeSoftwareFallback = 4; 106 const int kNumRetriesBeforeSoftwareFallback = 4;
106 107
107 bool IsUsingMus() { 108 bool IsUsingMus() {
108 return service_manager::ServiceManagerIsRemote(); 109 return service_manager::ServiceManagerIsRemote();
109 } 110 }
110 111
112 bool IsGpuVSyncSignalSupported() {
113 #if defined(OS_WIN)
114 // TODO(stanisc): http://crbug.com/467617 Limit to Windows 8+ for now because
115 // of locking issue caused by waiting for VSync on Win7.
116 return base::win::GetVersion() >= base::win::VERSION_WIN8 &&
117 base::FeatureList::IsEnabled(features::kD3DVsync);
118 #else
119 return false;
120 #endif // defined(OS_WIN)
121 }
122
111 scoped_refptr<ui::ContextProviderCommandBuffer> CreateContextCommon( 123 scoped_refptr<ui::ContextProviderCommandBuffer> CreateContextCommon(
112 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host, 124 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host,
113 gpu::SurfaceHandle surface_handle, 125 gpu::SurfaceHandle surface_handle,
114 bool need_alpha_channel, 126 bool need_alpha_channel,
115 bool need_stencil_bits, 127 bool need_stencil_bits,
116 bool support_locking, 128 bool support_locking,
117 ui::ContextProviderCommandBuffer* shared_context_provider, 129 ui::ContextProviderCommandBuffer* shared_context_provider,
118 ui::command_buffer_metrics::ContextType type) { 130 ui::command_buffer_metrics::ContextType type) {
119 DCHECK( 131 DCHECK(
120 content::GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor()); 132 content::GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor());
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 } 173 }
162 #endif 174 #endif
163 175
164 } // namespace 176 } // namespace
165 177
166 namespace content { 178 namespace content {
167 179
168 struct GpuProcessTransportFactory::PerCompositorData { 180 struct GpuProcessTransportFactory::PerCompositorData {
169 gpu::SurfaceHandle surface_handle = gpu::kNullSurfaceHandle; 181 gpu::SurfaceHandle surface_handle = gpu::kNullSurfaceHandle;
170 BrowserCompositorOutputSurface* display_output_surface = nullptr; 182 BrowserCompositorOutputSurface* display_output_surface = nullptr;
171 std::unique_ptr<cc::SyntheticBeginFrameSource> begin_frame_source; 183 // Either |synthetic_begin_frame_source| or |gpu_vsync_begin_frame_source| is
184 // valid but not both at the same time.
185 std::unique_ptr<cc::SyntheticBeginFrameSource> synthetic_begin_frame_source;
186 std::unique_ptr<GpuVSyncBeginFrameSource> gpu_vsync_begin_frame_source;
172 ReflectorImpl* reflector = nullptr; 187 ReflectorImpl* reflector = nullptr;
173 std::unique_ptr<cc::Display> display; 188 std::unique_ptr<cc::Display> display;
174 bool output_is_secure = false; 189 bool output_is_secure = false;
175 }; 190 };
176 191
177 GpuProcessTransportFactory::GpuProcessTransportFactory() 192 GpuProcessTransportFactory::GpuProcessTransportFactory()
178 : task_graph_runner_(new cc::SingleThreadTaskGraphRunner), 193 : task_graph_runner_(new cc::SingleThreadTaskGraphRunner),
179 callback_factory_(this) { 194 callback_factory_(this) {
180 cc::SetClientNameForMetrics("Browser"); 195 cc::SetClientNameForMetrics("Browser");
181 196
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 gpu::GpuChannelEstablishedCallback callback( 468 gpu::GpuChannelEstablishedCallback callback(
454 base::Bind(&GpuProcessTransportFactory::EstablishedGpuChannel, 469 base::Bind(&GpuProcessTransportFactory::EstablishedGpuChannel,
455 callback_factory_.GetWeakPtr(), compositor, 470 callback_factory_.GetWeakPtr(), compositor,
456 create_gpu_output_surface, num_attempts + 1)); 471 create_gpu_output_surface, num_attempts + 1));
457 DCHECK(gpu_channel_factory_); 472 DCHECK(gpu_channel_factory_);
458 gpu_channel_factory_->EstablishGpuChannel(callback); 473 gpu_channel_factory_->EstablishGpuChannel(callback);
459 return; 474 return;
460 } 475 }
461 } 476 }
462 477
463 std::unique_ptr<cc::SyntheticBeginFrameSource> synthetic_begin_frame_source;
464 if (!compositor->GetRendererSettings().disable_display_vsync) {
465 synthetic_begin_frame_source.reset(new cc::DelayBasedBeginFrameSource(
466 base::MakeUnique<cc::DelayBasedTimeSource>(
467 compositor->task_runner().get())));
468 } else {
469 synthetic_begin_frame_source.reset(new cc::BackToBackBeginFrameSource(
470 base::MakeUnique<cc::DelayBasedTimeSource>(
471 compositor->task_runner().get())));
472 }
473 cc::BeginFrameSource* begin_frame_source = synthetic_begin_frame_source.get();
474
475 BrowserCompositorOutputSurface::UpdateVSyncParametersCallback vsync_callback = 478 BrowserCompositorOutputSurface::UpdateVSyncParametersCallback vsync_callback =
476 base::Bind(&ui::Compositor::SetDisplayVSyncParameters, compositor); 479 base::Bind(&ui::Compositor::SetDisplayVSyncParameters, compositor);
480 cc::BeginFrameSource* begin_frame_source = nullptr;
481 GpuVSyncControl* gpu_vsync_control = nullptr;
477 482
478 std::unique_ptr<BrowserCompositorOutputSurface> display_output_surface; 483 std::unique_ptr<BrowserCompositorOutputSurface> display_output_surface;
479 #if defined(ENABLE_VULKAN) 484 #if defined(ENABLE_VULKAN)
480 std::unique_ptr<VulkanBrowserCompositorOutputSurface> vulkan_surface; 485 std::unique_ptr<VulkanBrowserCompositorOutputSurface> vulkan_surface;
481 if (vulkan_context_provider) { 486 if (vulkan_context_provider) {
482 vulkan_surface.reset(new VulkanBrowserCompositorOutputSurface( 487 vulkan_surface.reset(new VulkanBrowserCompositorOutputSurface(
483 vulkan_context_provider, vsync_callback)); 488 vulkan_context_provider, vsync_callback));
484 if (!vulkan_surface->Initialize(compositor.get()->widget())) { 489 if (!vulkan_surface->Initialize(compositor.get()->widget())) {
485 vulkan_surface->Destroy(); 490 vulkan_surface->Destroy();
486 vulkan_surface.reset(); 491 vulkan_surface.reset();
(...skipping 19 matching lines...) Expand all
506 std::unique_ptr< 511 std::unique_ptr<
507 display_compositor::CompositorOverlayCandidateValidator>()); 512 display_compositor::CompositorOverlayCandidateValidator>());
508 } else if (capabilities.surfaceless) { 513 } else if (capabilities.surfaceless) {
509 #if defined(OS_MACOSX) 514 #if defined(OS_MACOSX)
510 display_output_surface = base::MakeUnique<GpuOutputSurfaceMac>( 515 display_output_surface = base::MakeUnique<GpuOutputSurfaceMac>(
511 compositor->widget(), context_provider, data->surface_handle, 516 compositor->widget(), context_provider, data->surface_handle,
512 vsync_callback, 517 vsync_callback,
513 CreateOverlayCandidateValidator(compositor->widget()), 518 CreateOverlayCandidateValidator(compositor->widget()),
514 GetGpuMemoryBufferManager()); 519 GetGpuMemoryBufferManager());
515 #else 520 #else
516 display_output_surface = 521 auto gpu_output_surface =
517 base::MakeUnique<GpuSurfacelessBrowserCompositorOutputSurface>( 522 base::MakeUnique<GpuSurfacelessBrowserCompositorOutputSurface>(
518 context_provider, data->surface_handle, vsync_callback, 523 context_provider, data->surface_handle, vsync_callback,
519 CreateOverlayCandidateValidator(compositor->widget()), 524 CreateOverlayCandidateValidator(compositor->widget()),
520 GL_TEXTURE_2D, GL_RGB, 525 GL_TEXTURE_2D, GL_RGB,
521 display::DisplaySnapshot::PrimaryFormat(), 526 display::DisplaySnapshot::PrimaryFormat(),
522 GetGpuMemoryBufferManager()); 527 GetGpuMemoryBufferManager());
528 gpu_vsync_control = gpu_output_surface.get();
529 display_output_surface = std::move(gpu_output_surface);
523 #endif 530 #endif
524 } else { 531 } else {
525 std::unique_ptr<display_compositor::CompositorOverlayCandidateValidator> 532 std::unique_ptr<display_compositor::CompositorOverlayCandidateValidator>
526 validator; 533 validator;
527 const bool use_mus = IsUsingMus(); 534 const bool use_mus = IsUsingMus();
528 #if !defined(OS_MACOSX) 535 #if !defined(OS_MACOSX)
529 // Overlays are only supported on surfaceless output surfaces on Mac. 536 // Overlays are only supported on surfaceless output surfaces on Mac.
530 if (!use_mus) 537 if (!use_mus)
531 validator = CreateOverlayCandidateValidator(compositor->widget()); 538 validator = CreateOverlayCandidateValidator(compositor->widget());
532 #endif 539 #endif
533 if (!use_mus) { 540 if (!use_mus) {
534 display_output_surface = 541 auto gpu_output_surface =
535 base::MakeUnique<GpuBrowserCompositorOutputSurface>( 542 base::MakeUnique<GpuBrowserCompositorOutputSurface>(
536 context_provider, vsync_callback, std::move(validator)); 543 context_provider, vsync_callback, std::move(validator));
544 gpu_vsync_control = gpu_output_surface.get();
545 display_output_surface = std::move(gpu_output_surface);
537 } else { 546 } else {
538 #if defined(USE_AURA) 547 #if defined(USE_AURA)
539 std::unique_ptr<MusBrowserCompositorOutputSurface> mus_output_surface;
540 aura::WindowTreeHost* host = 548 aura::WindowTreeHost* host =
541 aura::WindowTreeHost::GetForAcceleratedWidget( 549 aura::WindowTreeHost::GetForAcceleratedWidget(
542 compositor->widget()); 550 compositor->widget());
543 mus_output_surface = 551 auto mus_output_surface =
544 base::MakeUnique<MusBrowserCompositorOutputSurface>( 552 base::MakeUnique<MusBrowserCompositorOutputSurface>(
545 host->window(), context_provider, GetGpuMemoryBufferManager(), 553 host->window(), context_provider, GetGpuMemoryBufferManager(),
546 vsync_callback, std::move(validator)); 554 vsync_callback, std::move(validator));
547 // We use the ExternalBeginFrameSource provided by the output surface 555 // We use the ExternalBeginFrameSource provided by the output surface
548 // instead of our own synthetic one. 556 // instead of our own synthetic one.
549 synthetic_begin_frame_source.reset();
550 begin_frame_source = mus_output_surface->GetBeginFrameSource(); 557 begin_frame_source = mus_output_surface->GetBeginFrameSource();
551 DCHECK(begin_frame_source); 558 DCHECK(begin_frame_source);
552 display_output_surface = std::move(mus_output_surface); 559 display_output_surface = std::move(mus_output_surface);
553 #else 560 #else
554 NOTREACHED(); 561 NOTREACHED();
555 #endif 562 #endif
556 } 563 }
557 } 564 }
558 } 565 }
559 } 566 }
560 567
561 data->display_output_surface = display_output_surface.get(); 568 std::unique_ptr<cc::SyntheticBeginFrameSource> synthetic_begin_frame_source;
569 std::unique_ptr<GpuVSyncBeginFrameSource> gpu_vsync_begin_frame_source;
570
571 if (!begin_frame_source) {
572 if (!compositor->GetRendererSettings().disable_display_vsync) {
danakj 2017/02/16 15:56:02 nit: maybe it's just me but i think it's easier to
stanisc 2017/02/16 21:43:19 I see your point. The current if() case is predomi
573 if (gpu_vsync_control && IsGpuVSyncSignalSupported()) {
574 gpu_vsync_begin_frame_source.reset(
575 new GpuVSyncBeginFrameSource(gpu_vsync_control));
danakj 2017/02/16 15:56:02 prefer "= MakeUnique<T>" to ".reset(new T"
stanisc 2017/02/16 21:43:18 Done.
576 begin_frame_source = gpu_vsync_begin_frame_source.get();
577 } else {
578 synthetic_begin_frame_source.reset(new cc::DelayBasedBeginFrameSource(
579 base::MakeUnique<cc::DelayBasedTimeSource>(
580 compositor->task_runner().get())));
581 begin_frame_source = synthetic_begin_frame_source.get();
582 }
583 } else {
584 synthetic_begin_frame_source.reset(new cc::BackToBackBeginFrameSource(
585 base::MakeUnique<cc::DelayBasedTimeSource>(
586 compositor->task_runner().get())));
587 begin_frame_source = synthetic_begin_frame_source.get();
588 }
589 }
590
562 if (data->reflector) 591 if (data->reflector)
563 data->reflector->OnSourceSurfaceReady(data->display_output_surface); 592 data->reflector->OnSourceSurfaceReady(data->display_output_surface);
564 593
565 #if defined(OS_WIN) 594 #if defined(OS_WIN)
566 gfx::RenderingWindowManager::GetInstance()->DoSetParentOnChild( 595 gfx::RenderingWindowManager::GetInstance()->DoSetParentOnChild(
567 compositor->widget()); 596 compositor->widget());
568 #endif 597 #endif
569 598
570 std::unique_ptr<cc::DisplayScheduler> scheduler(new cc::DisplayScheduler( 599 std::unique_ptr<cc::DisplayScheduler> scheduler(new cc::DisplayScheduler(
571 compositor->task_runner().get(), 600 compositor->task_runner().get(),
572 display_output_surface->capabilities().max_frames_pending)); 601 display_output_surface->capabilities().max_frames_pending));
573 602
574 // The Display owns and uses the |display_output_surface| created above. 603 // The Display owns and uses the |display_output_surface| created above.
575 data->display = base::MakeUnique<cc::Display>( 604 data->display = base::MakeUnique<cc::Display>(
576 HostSharedBitmapManager::current(), GetGpuMemoryBufferManager(), 605 HostSharedBitmapManager::current(), GetGpuMemoryBufferManager(),
577 compositor->GetRendererSettings(), compositor->frame_sink_id(), 606 compositor->GetRendererSettings(), compositor->frame_sink_id(),
578 begin_frame_source, std::move(display_output_surface), 607 begin_frame_source, std::move(display_output_surface),
579 std::move(scheduler), base::MakeUnique<cc::TextureMailboxDeleter>( 608 std::move(scheduler), base::MakeUnique<cc::TextureMailboxDeleter>(
580 compositor->task_runner().get())); 609 compositor->task_runner().get()));
581 // Note that we are careful not to destroy a prior |data->begin_frame_source| 610 // Note that we are careful not to destroy prior begin frame sources
danakj 2017/02/16 15:56:02 BeginFrameSources will be more greppable and searc
stanisc 2017/02/16 21:43:18 Done.
582 // until we have reset |data->display|. 611 // until we have reset |data->display|.
583 data->begin_frame_source = std::move(synthetic_begin_frame_source); 612 data->synthetic_begin_frame_source = std::move(synthetic_begin_frame_source);
613 data->gpu_vsync_begin_frame_source = std::move(gpu_vsync_begin_frame_source);
584 614
585 // The |delegated_output_surface| is given back to the compositor, it 615 // The |delegated_output_surface| is given back to the compositor, it
586 // delegates to the Display as its root surface. Importantly, it shares the 616 // delegates to the Display as its root surface. Importantly, it shares the
587 // same ContextProvider as the Display's output surface. 617 // same ContextProvider as the Display's output surface.
588 auto compositor_frame_sink = 618 auto compositor_frame_sink =
589 vulkan_context_provider 619 vulkan_context_provider
590 ? base::MakeUnique<cc::DirectCompositorFrameSink>( 620 ? base::MakeUnique<cc::DirectCompositorFrameSink>(
591 compositor->frame_sink_id(), surface_manager_.get(), 621 compositor->frame_sink_id(), surface_manager_.get(),
592 data->display.get(), 622 data->display.get(),
593 static_cast<scoped_refptr<cc::VulkanContextProvider>>( 623 static_cast<scoped_refptr<cc::VulkanContextProvider>>(
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 } 766 }
737 767
738 void GpuProcessTransportFactory::SetAuthoritativeVSyncInterval( 768 void GpuProcessTransportFactory::SetAuthoritativeVSyncInterval(
739 ui::Compositor* compositor, 769 ui::Compositor* compositor,
740 base::TimeDelta interval) { 770 base::TimeDelta interval) {
741 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor); 771 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
742 if (it == per_compositor_data_.end()) 772 if (it == per_compositor_data_.end())
743 return; 773 return;
744 PerCompositorData* data = it->second.get(); 774 PerCompositorData* data = it->second.get();
745 DCHECK(data); 775 DCHECK(data);
746 if (data->begin_frame_source) 776 if (data->synthetic_begin_frame_source)
747 data->begin_frame_source->SetAuthoritativeVSyncInterval(interval); 777 data->synthetic_begin_frame_source->SetAuthoritativeVSyncInterval(interval);
748 } 778 }
749 779
750 void GpuProcessTransportFactory::SetDisplayVSyncParameters( 780 void GpuProcessTransportFactory::SetDisplayVSyncParameters(
751 ui::Compositor* compositor, 781 ui::Compositor* compositor,
752 base::TimeTicks timebase, 782 base::TimeTicks timebase,
753 base::TimeDelta interval) { 783 base::TimeDelta interval) {
754 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor); 784 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
755 if (it == per_compositor_data_.end()) 785 if (it == per_compositor_data_.end())
756 return; 786 return;
757 PerCompositorData* data = it->second.get(); 787 PerCompositorData* data = it->second.get();
758 DCHECK(data); 788 DCHECK(data);
759 if (data->begin_frame_source) 789 if (data->synthetic_begin_frame_source) {
760 data->begin_frame_source->OnUpdateVSyncParameters(timebase, interval); 790 data->synthetic_begin_frame_source->OnUpdateVSyncParameters(timebase,
791 interval);
792 } else if (data->gpu_vsync_begin_frame_source)
danakj 2017/02/16 15:56:02 if one block of if/else has {} then they all do h
stanisc 2017/02/16 21:43:18 Done.
793 data->gpu_vsync_begin_frame_source->OnVSync(timebase, interval);
761 } 794 }
762 795
763 void GpuProcessTransportFactory::SetOutputIsSecure(ui::Compositor* compositor, 796 void GpuProcessTransportFactory::SetOutputIsSecure(ui::Compositor* compositor,
764 bool secure) { 797 bool secure) {
765 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor); 798 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
766 if (it == per_compositor_data_.end()) 799 if (it == per_compositor_data_.end())
767 return; 800 return;
768 PerCompositorData* data = it->second.get(); 801 PerCompositorData* data = it->second.get();
769 DCHECK(data); 802 DCHECK(data);
770 data->output_is_secure = secure; 803 data->output_is_secure = secure;
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 shared_vulkan_context_provider_ = 947 shared_vulkan_context_provider_ =
915 cc::VulkanInProcessContextProvider::Create(); 948 cc::VulkanInProcessContextProvider::Create();
916 } 949 }
917 950
918 shared_vulkan_context_provider_initialized_ = true; 951 shared_vulkan_context_provider_initialized_ = true;
919 } 952 }
920 return shared_vulkan_context_provider_; 953 return shared_vulkan_context_provider_;
921 } 954 }
922 955
923 } // namespace content 956 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698