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

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

Issue 2626413002: Route D3D VSync signal to Compositor (Closed)
Patch Set: Implement GPU VSync provider as gl::VSyncProvider 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 return base::FeatureList::IsEnabled(features::kD3DVsync);
115 #else
116 return false;
117 #endif // defined(OS_WIN)
118 }
119
111 scoped_refptr<ui::ContextProviderCommandBuffer> CreateContextCommon( 120 scoped_refptr<ui::ContextProviderCommandBuffer> CreateContextCommon(
112 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host, 121 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host,
113 gpu::SurfaceHandle surface_handle, 122 gpu::SurfaceHandle surface_handle,
114 bool need_alpha_channel, 123 bool need_alpha_channel,
115 bool need_stencil_bits, 124 bool need_stencil_bits,
116 bool support_locking, 125 bool support_locking,
117 ui::ContextProviderCommandBuffer* shared_context_provider, 126 ui::ContextProviderCommandBuffer* shared_context_provider,
118 ui::command_buffer_metrics::ContextType type) { 127 ui::command_buffer_metrics::ContextType type) {
119 DCHECK( 128 DCHECK(
120 content::GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor()); 129 content::GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor());
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 } 170 }
162 #endif 171 #endif
163 172
164 } // namespace 173 } // namespace
165 174
166 namespace content { 175 namespace content {
167 176
168 struct GpuProcessTransportFactory::PerCompositorData { 177 struct GpuProcessTransportFactory::PerCompositorData {
169 gpu::SurfaceHandle surface_handle = gpu::kNullSurfaceHandle; 178 gpu::SurfaceHandle surface_handle = gpu::kNullSurfaceHandle;
170 BrowserCompositorOutputSurface* display_output_surface = nullptr; 179 BrowserCompositorOutputSurface* display_output_surface = nullptr;
171 std::unique_ptr<cc::SyntheticBeginFrameSource> begin_frame_source; 180 // Either |synthetic_begin_frame_source| or |gpu_vsync_begin_frame_source| is
181 // valid but not both at the same time.
182 std::unique_ptr<cc::SyntheticBeginFrameSource> synthetic_begin_frame_source;
183 std::unique_ptr<GpuVSyncBeginFrameSource> gpu_vsync_begin_frame_source;
172 ReflectorImpl* reflector = nullptr; 184 ReflectorImpl* reflector = nullptr;
173 std::unique_ptr<cc::Display> display; 185 std::unique_ptr<cc::Display> display;
174 bool output_is_secure = false; 186 bool output_is_secure = false;
175 }; 187 };
176 188
177 GpuProcessTransportFactory::GpuProcessTransportFactory() 189 GpuProcessTransportFactory::GpuProcessTransportFactory()
178 : task_graph_runner_(new cc::SingleThreadTaskGraphRunner), 190 : task_graph_runner_(new cc::SingleThreadTaskGraphRunner),
179 callback_factory_(this) { 191 callback_factory_(this) {
180 cc::SetClientNameForMetrics("Browser"); 192 cc::SetClientNameForMetrics("Browser");
181 193
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 gpu::GpuChannelEstablishedCallback callback( 465 gpu::GpuChannelEstablishedCallback callback(
454 base::Bind(&GpuProcessTransportFactory::EstablishedGpuChannel, 466 base::Bind(&GpuProcessTransportFactory::EstablishedGpuChannel,
455 callback_factory_.GetWeakPtr(), compositor, 467 callback_factory_.GetWeakPtr(), compositor,
456 create_gpu_output_surface, num_attempts + 1)); 468 create_gpu_output_surface, num_attempts + 1));
457 DCHECK(gpu_channel_factory_); 469 DCHECK(gpu_channel_factory_);
458 gpu_channel_factory_->EstablishGpuChannel(callback); 470 gpu_channel_factory_->EstablishGpuChannel(callback);
459 return; 471 return;
460 } 472 }
461 } 473 }
462 474
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 = 475 BrowserCompositorOutputSurface::UpdateVSyncParametersCallback vsync_callback =
476 base::Bind(&ui::Compositor::SetDisplayVSyncParameters, compositor); 476 base::Bind(&ui::Compositor::SetDisplayVSyncParameters, compositor);
477 cc::BeginFrameSource* begin_frame_source = nullptr;
478 GpuVSyncControl* gpu_vsync_control = nullptr;
477 479
478 std::unique_ptr<BrowserCompositorOutputSurface> display_output_surface; 480 std::unique_ptr<BrowserCompositorOutputSurface> display_output_surface;
479 #if defined(ENABLE_VULKAN) 481 #if defined(ENABLE_VULKAN)
480 std::unique_ptr<VulkanBrowserCompositorOutputSurface> vulkan_surface; 482 std::unique_ptr<VulkanBrowserCompositorOutputSurface> vulkan_surface;
481 if (vulkan_context_provider) { 483 if (vulkan_context_provider) {
482 vulkan_surface.reset(new VulkanBrowserCompositorOutputSurface( 484 vulkan_surface.reset(new VulkanBrowserCompositorOutputSurface(
483 vulkan_context_provider, vsync_callback)); 485 vulkan_context_provider, vsync_callback));
484 if (!vulkan_surface->Initialize(compositor.get()->widget())) { 486 if (!vulkan_surface->Initialize(compositor.get()->widget())) {
485 vulkan_surface->Destroy(); 487 vulkan_surface->Destroy();
486 vulkan_surface.reset(); 488 vulkan_surface.reset();
(...skipping 19 matching lines...) Expand all
506 std::unique_ptr< 508 std::unique_ptr<
507 display_compositor::CompositorOverlayCandidateValidator>()); 509 display_compositor::CompositorOverlayCandidateValidator>());
508 } else if (capabilities.surfaceless) { 510 } else if (capabilities.surfaceless) {
509 #if defined(OS_MACOSX) 511 #if defined(OS_MACOSX)
510 display_output_surface = base::MakeUnique<GpuOutputSurfaceMac>( 512 display_output_surface = base::MakeUnique<GpuOutputSurfaceMac>(
511 compositor->widget(), context_provider, data->surface_handle, 513 compositor->widget(), context_provider, data->surface_handle,
512 vsync_callback, 514 vsync_callback,
513 CreateOverlayCandidateValidator(compositor->widget()), 515 CreateOverlayCandidateValidator(compositor->widget()),
514 GetGpuMemoryBufferManager()); 516 GetGpuMemoryBufferManager());
515 #else 517 #else
516 display_output_surface = 518 auto gpu_output_surface =
517 base::MakeUnique<GpuSurfacelessBrowserCompositorOutputSurface>( 519 base::MakeUnique<GpuSurfacelessBrowserCompositorOutputSurface>(
518 context_provider, data->surface_handle, vsync_callback, 520 context_provider, data->surface_handle, vsync_callback,
519 CreateOverlayCandidateValidator(compositor->widget()), 521 CreateOverlayCandidateValidator(compositor->widget()),
520 GL_TEXTURE_2D, GL_RGB, 522 GL_TEXTURE_2D, GL_RGB,
521 display::DisplaySnapshot::PrimaryFormat(), 523 display::DisplaySnapshot::PrimaryFormat(),
522 GetGpuMemoryBufferManager()); 524 GetGpuMemoryBufferManager());
525 gpu_vsync_control = gpu_output_surface.get();
526 display_output_surface = std::move(gpu_output_surface);
523 #endif 527 #endif
524 } else { 528 } else {
525 std::unique_ptr<display_compositor::CompositorOverlayCandidateValidator> 529 std::unique_ptr<display_compositor::CompositorOverlayCandidateValidator>
526 validator; 530 validator;
527 const bool use_mus = IsUsingMus(); 531 const bool use_mus = IsUsingMus();
528 #if !defined(OS_MACOSX) 532 #if !defined(OS_MACOSX)
529 // Overlays are only supported on surfaceless output surfaces on Mac. 533 // Overlays are only supported on surfaceless output surfaces on Mac.
530 if (!use_mus) 534 if (!use_mus)
531 validator = CreateOverlayCandidateValidator(compositor->widget()); 535 validator = CreateOverlayCandidateValidator(compositor->widget());
532 #endif 536 #endif
533 if (!use_mus) { 537 if (!use_mus) {
534 display_output_surface = 538 auto gpu_output_surface =
535 base::MakeUnique<GpuBrowserCompositorOutputSurface>( 539 base::MakeUnique<GpuBrowserCompositorOutputSurface>(
536 context_provider, vsync_callback, std::move(validator), 540 context_provider, vsync_callback, std::move(validator),
537 support_stencil); 541 support_stencil);
542 gpu_vsync_control = gpu_output_surface.get();
543 display_output_surface = std::move(gpu_output_surface);
538 } else { 544 } else {
539 #if defined(USE_AURA) 545 #if defined(USE_AURA)
540 std::unique_ptr<MusBrowserCompositorOutputSurface> mus_output_surface;
541 aura::WindowTreeHost* host = 546 aura::WindowTreeHost* host =
542 aura::WindowTreeHost::GetForAcceleratedWidget( 547 aura::WindowTreeHost::GetForAcceleratedWidget(
543 compositor->widget()); 548 compositor->widget());
544 mus_output_surface = 549 auto mus_output_surface =
545 base::MakeUnique<MusBrowserCompositorOutputSurface>( 550 base::MakeUnique<MusBrowserCompositorOutputSurface>(
546 host->window(), context_provider, GetGpuMemoryBufferManager(), 551 host->window(), context_provider, GetGpuMemoryBufferManager(),
547 vsync_callback, std::move(validator)); 552 vsync_callback, std::move(validator));
548 // We use the ExternalBeginFrameSource provided by the output surface 553 // We use the ExternalBeginFrameSource provided by the output surface
549 // instead of our own synthetic one. 554 // instead of our own synthetic one.
550 synthetic_begin_frame_source.reset();
551 begin_frame_source = mus_output_surface->GetBeginFrameSource(); 555 begin_frame_source = mus_output_surface->GetBeginFrameSource();
552 DCHECK(begin_frame_source); 556 DCHECK(begin_frame_source);
553 display_output_surface = std::move(mus_output_surface); 557 display_output_surface = std::move(mus_output_surface);
554 #else 558 #else
555 NOTREACHED(); 559 NOTREACHED();
556 #endif 560 #endif
557 } 561 }
558 } 562 }
559 } 563 }
560 } 564 }
561 565
562 data->display_output_surface = display_output_surface.get(); 566 std::unique_ptr<cc::SyntheticBeginFrameSource> synthetic_begin_frame_source;
567 std::unique_ptr<GpuVSyncBeginFrameSource> gpu_vsync_begin_frame_source;
568
569 if (!begin_frame_source) {
570 if (!compositor->GetRendererSettings().disable_display_vsync) {
571 if (gpu_vsync_control && IsGpuVSyncSignalSupported()) {
572 gpu_vsync_begin_frame_source.reset(
573 new GpuVSyncBeginFrameSource(gpu_vsync_control));
574 begin_frame_source = gpu_vsync_begin_frame_source.get();
575 } else {
576 synthetic_begin_frame_source.reset(new cc::DelayBasedBeginFrameSource(
577 base::MakeUnique<cc::DelayBasedTimeSource>(
578 compositor->task_runner().get())));
579 begin_frame_source = synthetic_begin_frame_source.get();
580 }
581 } else {
582 synthetic_begin_frame_source.reset(new cc::BackToBackBeginFrameSource(
583 base::MakeUnique<cc::DelayBasedTimeSource>(
584 compositor->task_runner().get())));
585 begin_frame_source = synthetic_begin_frame_source.get();
586 }
587 }
588
563 if (data->reflector) 589 if (data->reflector)
564 data->reflector->OnSourceSurfaceReady(data->display_output_surface); 590 data->reflector->OnSourceSurfaceReady(data->display_output_surface);
565 591
566 #if defined(OS_WIN) 592 #if defined(OS_WIN)
567 gfx::RenderingWindowManager::GetInstance()->DoSetParentOnChild( 593 gfx::RenderingWindowManager::GetInstance()->DoSetParentOnChild(
568 compositor->widget()); 594 compositor->widget());
569 #endif 595 #endif
570 596
571 std::unique_ptr<cc::DisplayScheduler> scheduler(new cc::DisplayScheduler( 597 std::unique_ptr<cc::DisplayScheduler> scheduler(new cc::DisplayScheduler(
572 compositor->task_runner().get(), 598 compositor->task_runner().get(),
573 display_output_surface->capabilities().max_frames_pending)); 599 display_output_surface->capabilities().max_frames_pending));
574 600
575 // The Display owns and uses the |display_output_surface| created above. 601 // The Display owns and uses the |display_output_surface| created above.
576 data->display = base::MakeUnique<cc::Display>( 602 data->display = base::MakeUnique<cc::Display>(
577 HostSharedBitmapManager::current(), GetGpuMemoryBufferManager(), 603 HostSharedBitmapManager::current(), GetGpuMemoryBufferManager(),
578 compositor->GetRendererSettings(), compositor->frame_sink_id(), 604 compositor->GetRendererSettings(), compositor->frame_sink_id(),
579 begin_frame_source, std::move(display_output_surface), 605 begin_frame_source, std::move(display_output_surface),
580 std::move(scheduler), base::MakeUnique<cc::TextureMailboxDeleter>( 606 std::move(scheduler), base::MakeUnique<cc::TextureMailboxDeleter>(
581 compositor->task_runner().get())); 607 compositor->task_runner().get()));
582 // Note that we are careful not to destroy a prior |data->begin_frame_source| 608 // Note that we are careful not to destroy prior begin frame sources
583 // until we have reset |data->display|. 609 // until we have reset |data->display|.
584 data->begin_frame_source = std::move(synthetic_begin_frame_source); 610 data->synthetic_begin_frame_source = std::move(synthetic_begin_frame_source);
611 data->gpu_vsync_begin_frame_source = std::move(gpu_vsync_begin_frame_source);
585 612
586 // The |delegated_output_surface| is given back to the compositor, it 613 // The |delegated_output_surface| is given back to the compositor, it
587 // delegates to the Display as its root surface. Importantly, it shares the 614 // delegates to the Display as its root surface. Importantly, it shares the
588 // same ContextProvider as the Display's output surface. 615 // same ContextProvider as the Display's output surface.
589 auto compositor_frame_sink = 616 auto compositor_frame_sink =
590 vulkan_context_provider 617 vulkan_context_provider
591 ? base::MakeUnique<cc::DirectCompositorFrameSink>( 618 ? base::MakeUnique<cc::DirectCompositorFrameSink>(
592 compositor->frame_sink_id(), surface_manager_.get(), 619 compositor->frame_sink_id(), surface_manager_.get(),
593 data->display.get(), 620 data->display.get(),
594 static_cast<scoped_refptr<cc::VulkanContextProvider>>( 621 static_cast<scoped_refptr<cc::VulkanContextProvider>>(
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
732 } 759 }
733 760
734 void GpuProcessTransportFactory::SetAuthoritativeVSyncInterval( 761 void GpuProcessTransportFactory::SetAuthoritativeVSyncInterval(
735 ui::Compositor* compositor, 762 ui::Compositor* compositor,
736 base::TimeDelta interval) { 763 base::TimeDelta interval) {
737 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor); 764 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
738 if (it == per_compositor_data_.end()) 765 if (it == per_compositor_data_.end())
739 return; 766 return;
740 PerCompositorData* data = it->second.get(); 767 PerCompositorData* data = it->second.get();
741 DCHECK(data); 768 DCHECK(data);
742 if (data->begin_frame_source) 769 if (data->synthetic_begin_frame_source)
743 data->begin_frame_source->SetAuthoritativeVSyncInterval(interval); 770 data->synthetic_begin_frame_source->SetAuthoritativeVSyncInterval(interval);
744 } 771 }
745 772
746 void GpuProcessTransportFactory::SetDisplayVSyncParameters( 773 void GpuProcessTransportFactory::SetDisplayVSyncParameters(
747 ui::Compositor* compositor, 774 ui::Compositor* compositor,
748 base::TimeTicks timebase, 775 base::TimeTicks timebase,
749 base::TimeDelta interval) { 776 base::TimeDelta interval) {
750 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor); 777 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
751 if (it == per_compositor_data_.end()) 778 if (it == per_compositor_data_.end())
752 return; 779 return;
753 PerCompositorData* data = it->second.get(); 780 PerCompositorData* data = it->second.get();
754 DCHECK(data); 781 DCHECK(data);
755 if (data->begin_frame_source) 782 if (data->synthetic_begin_frame_source) {
756 data->begin_frame_source->OnUpdateVSyncParameters(timebase, interval); 783 data->synthetic_begin_frame_source->OnUpdateVSyncParameters(timebase,
784 interval);
785 } else if (data->gpu_vsync_begin_frame_source)
786 data->gpu_vsync_begin_frame_source->OnVSync(timebase, interval);
757 } 787 }
758 788
759 void GpuProcessTransportFactory::SetOutputIsSecure(ui::Compositor* compositor, 789 void GpuProcessTransportFactory::SetOutputIsSecure(ui::Compositor* compositor,
760 bool secure) { 790 bool secure) {
761 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor); 791 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
762 if (it == per_compositor_data_.end()) 792 if (it == per_compositor_data_.end())
763 return; 793 return;
764 PerCompositorData* data = it->second.get(); 794 PerCompositorData* data = it->second.get();
765 DCHECK(data); 795 DCHECK(data);
766 data->output_is_secure = secure; 796 data->output_is_secure = secure;
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 shared_vulkan_context_provider_ = 940 shared_vulkan_context_provider_ =
911 cc::VulkanInProcessContextProvider::Create(); 941 cc::VulkanInProcessContextProvider::Create();
912 } 942 }
913 943
914 shared_vulkan_context_provider_initialized_ = true; 944 shared_vulkan_context_provider_initialized_ = true;
915 } 945 }
916 return shared_vulkan_context_provider_; 946 return shared_vulkan_context_provider_;
917 } 947 }
918 948
919 } // namespace content 949 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698