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

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

Issue 2626413002: Route D3D VSync signal to Compositor (Closed)
Patch Set: Merged with recent BeginFrameSource changes 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)
70 #include "base/win/windows_version.h"
69 #include "components/display_compositor/compositor_overlay_candidate_validator_w in.h" 71 #include "components/display_compositor/compositor_overlay_candidate_validator_w in.h"
70 #include "content/browser/compositor/software_output_device_win.h" 72 #include "content/browser/compositor/software_output_device_win.h"
71 #include "ui/gfx/win/rendering_window_manager.h" 73 #include "ui/gfx/win/rendering_window_manager.h"
72 #elif defined(USE_OZONE) 74 #elif defined(USE_OZONE)
73 #include "components/display_compositor/compositor_overlay_candidate_validator_o zone.h" 75 #include "components/display_compositor/compositor_overlay_candidate_validator_o zone.h"
74 #include "content/browser/compositor/software_output_device_ozone.h" 76 #include "content/browser/compositor/software_output_device_ozone.h"
75 #include "ui/ozone/public/overlay_candidates_ozone.h" 77 #include "ui/ozone/public/overlay_candidates_ozone.h"
76 #include "ui/ozone/public/overlay_manager_ozone.h" 78 #include "ui/ozone/public/overlay_manager_ozone.h"
77 #include "ui/ozone/public/ozone_platform.h" 79 #include "ui/ozone/public/ozone_platform.h"
78 #include "ui/ozone/public/ozone_switches.h" 80 #include "ui/ozone/public/ozone_switches.h"
(...skipping 25 matching lines...) Expand all
104 106
105 const int kNumRetriesBeforeSoftwareFallback = 4; 107 const int kNumRetriesBeforeSoftwareFallback = 4;
106 // The client_id used here should not conflict with the client_id generated 108 // The client_id used here should not conflict with the client_id generated
107 // from RenderWidgetHostImpl. 109 // from RenderWidgetHostImpl.
108 constexpr uint32_t kDefaultClientId = 0u; 110 constexpr uint32_t kDefaultClientId = 0u;
109 111
110 bool IsUsingMus() { 112 bool IsUsingMus() {
111 return service_manager::ServiceManagerIsRemote(); 113 return service_manager::ServiceManagerIsRemote();
112 } 114 }
113 115
116 bool IsGpuVSyncSignalSupported() {
117 #if defined(OS_WIN)
118 // TODO(stanisc): http://crbug.com/467617 Limit to Windows 8+ for now because
119 // of locking issue caused by waiting for VSync on Win7.
120 return base::win::GetVersion() >= base::win::VERSION_WIN8 &&
121 base::FeatureList::IsEnabled(features::kD3DVsync);
122 #else
123 return false;
124 #endif // defined(OS_WIN)
125 }
126
114 scoped_refptr<ui::ContextProviderCommandBuffer> CreateContextCommon( 127 scoped_refptr<ui::ContextProviderCommandBuffer> CreateContextCommon(
115 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host, 128 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host,
116 gpu::SurfaceHandle surface_handle, 129 gpu::SurfaceHandle surface_handle,
117 bool need_alpha_channel, 130 bool need_alpha_channel,
118 bool need_stencil_bits, 131 bool need_stencil_bits,
119 bool support_locking, 132 bool support_locking,
120 ui::ContextProviderCommandBuffer* shared_context_provider, 133 ui::ContextProviderCommandBuffer* shared_context_provider,
121 ui::command_buffer_metrics::ContextType type) { 134 ui::command_buffer_metrics::ContextType type) {
122 DCHECK( 135 DCHECK(
123 content::GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor()); 136 content::GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor());
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 } 177 }
165 #endif 178 #endif
166 179
167 } // namespace 180 } // namespace
168 181
169 namespace content { 182 namespace content {
170 183
171 struct GpuProcessTransportFactory::PerCompositorData { 184 struct GpuProcessTransportFactory::PerCompositorData {
172 gpu::SurfaceHandle surface_handle = gpu::kNullSurfaceHandle; 185 gpu::SurfaceHandle surface_handle = gpu::kNullSurfaceHandle;
173 BrowserCompositorOutputSurface* display_output_surface = nullptr; 186 BrowserCompositorOutputSurface* display_output_surface = nullptr;
174 std::unique_ptr<cc::SyntheticBeginFrameSource> begin_frame_source; 187 // Either |synthetic_begin_frame_source| or |gpu_vsync_begin_frame_source| is
188 // valid but not both at the same time.
189 std::unique_ptr<cc::SyntheticBeginFrameSource> synthetic_begin_frame_source;
190 std::unique_ptr<GpuVSyncBeginFrameSource> gpu_vsync_begin_frame_source;
175 ReflectorImpl* reflector = nullptr; 191 ReflectorImpl* reflector = nullptr;
176 std::unique_ptr<cc::Display> display; 192 std::unique_ptr<cc::Display> display;
177 bool output_is_secure = false; 193 bool output_is_secure = false;
178 }; 194 };
179 195
180 GpuProcessTransportFactory::GpuProcessTransportFactory() 196 GpuProcessTransportFactory::GpuProcessTransportFactory()
181 : frame_sink_id_allocator_(kDefaultClientId), 197 : frame_sink_id_allocator_(kDefaultClientId),
182 task_graph_runner_(new cc::SingleThreadTaskGraphRunner), 198 task_graph_runner_(new cc::SingleThreadTaskGraphRunner),
183 callback_factory_(this) { 199 callback_factory_(this) {
184 cc::SetClientNameForMetrics("Browser"); 200 cc::SetClientNameForMetrics("Browser");
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 gpu::GpuChannelEstablishedCallback callback( 473 gpu::GpuChannelEstablishedCallback callback(
458 base::Bind(&GpuProcessTransportFactory::EstablishedGpuChannel, 474 base::Bind(&GpuProcessTransportFactory::EstablishedGpuChannel,
459 callback_factory_.GetWeakPtr(), compositor, 475 callback_factory_.GetWeakPtr(), compositor,
460 create_gpu_output_surface, num_attempts + 1)); 476 create_gpu_output_surface, num_attempts + 1));
461 DCHECK(gpu_channel_factory_); 477 DCHECK(gpu_channel_factory_);
462 gpu_channel_factory_->EstablishGpuChannel(callback); 478 gpu_channel_factory_->EstablishGpuChannel(callback);
463 return; 479 return;
464 } 480 }
465 } 481 }
466 482
467 std::unique_ptr<cc::SyntheticBeginFrameSource> synthetic_begin_frame_source;
468 if (!compositor->GetRendererSettings().disable_display_vsync) {
469 synthetic_begin_frame_source.reset(new cc::DelayBasedBeginFrameSource(
470 base::MakeUnique<cc::DelayBasedTimeSource>(
471 compositor->task_runner().get())));
472 } else {
473 synthetic_begin_frame_source.reset(new cc::BackToBackBeginFrameSource(
474 base::MakeUnique<cc::DelayBasedTimeSource>(
475 compositor->task_runner().get())));
476 }
477 cc::BeginFrameSource* begin_frame_source = synthetic_begin_frame_source.get();
478
479 BrowserCompositorOutputSurface::UpdateVSyncParametersCallback vsync_callback = 483 BrowserCompositorOutputSurface::UpdateVSyncParametersCallback vsync_callback =
480 base::Bind(&ui::Compositor::SetDisplayVSyncParameters, compositor); 484 base::Bind(&ui::Compositor::SetDisplayVSyncParameters, compositor);
485 cc::BeginFrameSource* begin_frame_source = nullptr;
486 GpuVSyncControl* gpu_vsync_control = nullptr;
481 487
482 std::unique_ptr<BrowserCompositorOutputSurface> display_output_surface; 488 std::unique_ptr<BrowserCompositorOutputSurface> display_output_surface;
483 #if defined(ENABLE_VULKAN) 489 #if defined(ENABLE_VULKAN)
484 std::unique_ptr<VulkanBrowserCompositorOutputSurface> vulkan_surface; 490 std::unique_ptr<VulkanBrowserCompositorOutputSurface> vulkan_surface;
485 if (vulkan_context_provider) { 491 if (vulkan_context_provider) {
486 vulkan_surface.reset(new VulkanBrowserCompositorOutputSurface( 492 vulkan_surface.reset(new VulkanBrowserCompositorOutputSurface(
487 vulkan_context_provider, vsync_callback)); 493 vulkan_context_provider, vsync_callback));
488 if (!vulkan_surface->Initialize(compositor.get()->widget())) { 494 if (!vulkan_surface->Initialize(compositor.get()->widget())) {
489 vulkan_surface->Destroy(); 495 vulkan_surface->Destroy();
490 vulkan_surface.reset(); 496 vulkan_surface.reset();
(...skipping 19 matching lines...) Expand all
510 std::unique_ptr< 516 std::unique_ptr<
511 display_compositor::CompositorOverlayCandidateValidator>()); 517 display_compositor::CompositorOverlayCandidateValidator>());
512 } else if (capabilities.surfaceless) { 518 } else if (capabilities.surfaceless) {
513 #if defined(OS_MACOSX) 519 #if defined(OS_MACOSX)
514 display_output_surface = base::MakeUnique<GpuOutputSurfaceMac>( 520 display_output_surface = base::MakeUnique<GpuOutputSurfaceMac>(
515 compositor->widget(), context_provider, data->surface_handle, 521 compositor->widget(), context_provider, data->surface_handle,
516 vsync_callback, 522 vsync_callback,
517 CreateOverlayCandidateValidator(compositor->widget()), 523 CreateOverlayCandidateValidator(compositor->widget()),
518 GetGpuMemoryBufferManager()); 524 GetGpuMemoryBufferManager());
519 #else 525 #else
520 display_output_surface = 526 auto gpu_output_surface =
521 base::MakeUnique<GpuSurfacelessBrowserCompositorOutputSurface>( 527 base::MakeUnique<GpuSurfacelessBrowserCompositorOutputSurface>(
522 context_provider, data->surface_handle, vsync_callback, 528 context_provider, data->surface_handle, vsync_callback,
523 CreateOverlayCandidateValidator(compositor->widget()), 529 CreateOverlayCandidateValidator(compositor->widget()),
524 GL_TEXTURE_2D, GL_RGB, 530 GL_TEXTURE_2D, GL_RGB,
525 display::DisplaySnapshot::PrimaryFormat(), 531 display::DisplaySnapshot::PrimaryFormat(),
526 GetGpuMemoryBufferManager()); 532 GetGpuMemoryBufferManager());
533 gpu_vsync_control = gpu_output_surface.get();
534 display_output_surface = std::move(gpu_output_surface);
527 #endif 535 #endif
528 } else { 536 } else {
529 std::unique_ptr<display_compositor::CompositorOverlayCandidateValidator> 537 std::unique_ptr<display_compositor::CompositorOverlayCandidateValidator>
530 validator; 538 validator;
531 const bool use_mus = IsUsingMus(); 539 const bool use_mus = IsUsingMus();
532 #if !defined(OS_MACOSX) 540 #if !defined(OS_MACOSX)
533 // Overlays are only supported on surfaceless output surfaces on Mac. 541 // Overlays are only supported on surfaceless output surfaces on Mac.
534 if (!use_mus) 542 if (!use_mus)
535 validator = CreateOverlayCandidateValidator(compositor->widget()); 543 validator = CreateOverlayCandidateValidator(compositor->widget());
536 #endif 544 #endif
537 if (!use_mus) { 545 if (!use_mus) {
538 display_output_surface = 546 auto gpu_output_surface =
539 base::MakeUnique<GpuBrowserCompositorOutputSurface>( 547 base::MakeUnique<GpuBrowserCompositorOutputSurface>(
540 context_provider, vsync_callback, std::move(validator)); 548 context_provider, vsync_callback, std::move(validator));
549 gpu_vsync_control = gpu_output_surface.get();
550 display_output_surface = std::move(gpu_output_surface);
541 } else { 551 } else {
542 #if defined(USE_AURA) 552 #if defined(USE_AURA)
543 std::unique_ptr<MusBrowserCompositorOutputSurface> mus_output_surface;
544 aura::WindowTreeHost* host = 553 aura::WindowTreeHost* host =
545 aura::WindowTreeHost::GetForAcceleratedWidget( 554 aura::WindowTreeHost::GetForAcceleratedWidget(
546 compositor->widget()); 555 compositor->widget());
547 mus_output_surface = 556 auto mus_output_surface =
548 base::MakeUnique<MusBrowserCompositorOutputSurface>( 557 base::MakeUnique<MusBrowserCompositorOutputSurface>(
549 host->window(), context_provider, GetGpuMemoryBufferManager(), 558 host->window(), context_provider, GetGpuMemoryBufferManager(),
550 vsync_callback, std::move(validator)); 559 vsync_callback, std::move(validator));
551 // We use the ExternalBeginFrameSource provided by the output surface 560 // We use the ExternalBeginFrameSource provided by the output surface
552 // instead of our own synthetic one. 561 // instead of our own synthetic one.
553 synthetic_begin_frame_source.reset();
554 begin_frame_source = mus_output_surface->GetBeginFrameSource(); 562 begin_frame_source = mus_output_surface->GetBeginFrameSource();
555 DCHECK(begin_frame_source); 563 DCHECK(begin_frame_source);
556 display_output_surface = std::move(mus_output_surface); 564 display_output_surface = std::move(mus_output_surface);
557 #else 565 #else
558 NOTREACHED(); 566 NOTREACHED();
559 #endif 567 #endif
560 } 568 }
561 } 569 }
562 } 570 }
563 } 571 }
564 572
565 data->display_output_surface = display_output_surface.get(); 573 std::unique_ptr<cc::SyntheticBeginFrameSource> synthetic_begin_frame_source;
574 std::unique_ptr<GpuVSyncBeginFrameSource> gpu_vsync_begin_frame_source;
575
576 if (!begin_frame_source) {
577 if (!compositor->GetRendererSettings().disable_display_vsync) {
578 if (gpu_vsync_control && IsGpuVSyncSignalSupported()) {
579 gpu_vsync_begin_frame_source =
580 base::MakeUnique<GpuVSyncBeginFrameSource>(gpu_vsync_control);
581 begin_frame_source = gpu_vsync_begin_frame_source.get();
582 } else {
583 synthetic_begin_frame_source =
584 base::MakeUnique<cc::DelayBasedBeginFrameSource>(
585 base::MakeUnique<cc::DelayBasedTimeSource>(
586 compositor->task_runner().get()));
587 begin_frame_source = synthetic_begin_frame_source.get();
588 }
589 } else {
590 synthetic_begin_frame_source =
591 base::MakeUnique<cc::BackToBackBeginFrameSource>(
592 base::MakeUnique<cc::DelayBasedTimeSource>(
593 compositor->task_runner().get()));
594 begin_frame_source = synthetic_begin_frame_source.get();
595 }
596 }
597
566 if (data->reflector) 598 if (data->reflector)
567 data->reflector->OnSourceSurfaceReady(data->display_output_surface); 599 data->reflector->OnSourceSurfaceReady(data->display_output_surface);
568 600
569 #if defined(OS_WIN) 601 #if defined(OS_WIN)
570 gfx::RenderingWindowManager::GetInstance()->DoSetParentOnChild( 602 gfx::RenderingWindowManager::GetInstance()->DoSetParentOnChild(
571 compositor->widget()); 603 compositor->widget());
572 #endif 604 #endif
573 605
574 std::unique_ptr<cc::DisplayScheduler> scheduler(new cc::DisplayScheduler( 606 std::unique_ptr<cc::DisplayScheduler> scheduler(new cc::DisplayScheduler(
575 compositor->task_runner().get(), 607 compositor->task_runner().get(),
576 display_output_surface->capabilities().max_frames_pending)); 608 display_output_surface->capabilities().max_frames_pending));
577 609
578 // The Display owns and uses the |display_output_surface| created above. 610 // The Display owns and uses the |display_output_surface| created above.
579 data->display = base::MakeUnique<cc::Display>( 611 data->display = base::MakeUnique<cc::Display>(
580 HostSharedBitmapManager::current(), GetGpuMemoryBufferManager(), 612 HostSharedBitmapManager::current(), GetGpuMemoryBufferManager(),
581 compositor->GetRendererSettings(), compositor->frame_sink_id(), 613 compositor->GetRendererSettings(), compositor->frame_sink_id(),
582 begin_frame_source, std::move(display_output_surface), 614 begin_frame_source, std::move(display_output_surface),
583 std::move(scheduler), base::MakeUnique<cc::TextureMailboxDeleter>( 615 std::move(scheduler), base::MakeUnique<cc::TextureMailboxDeleter>(
584 compositor->task_runner().get())); 616 compositor->task_runner().get()));
585 // Note that we are careful not to destroy a prior |data->begin_frame_source| 617 // Note that we are careful not to destroy prior BeginFrameSource objects
586 // until we have reset |data->display|. 618 // until we have reset |data->display|.
587 data->begin_frame_source = std::move(synthetic_begin_frame_source); 619 data->synthetic_begin_frame_source = std::move(synthetic_begin_frame_source);
620 data->gpu_vsync_begin_frame_source = std::move(gpu_vsync_begin_frame_source);
588 621
589 // The |delegated_output_surface| is given back to the compositor, it 622 // The |delegated_output_surface| is given back to the compositor, it
590 // delegates to the Display as its root surface. Importantly, it shares the 623 // delegates to the Display as its root surface. Importantly, it shares the
591 // same ContextProvider as the Display's output surface. 624 // same ContextProvider as the Display's output surface.
592 auto compositor_frame_sink = 625 auto compositor_frame_sink =
593 vulkan_context_provider 626 vulkan_context_provider
594 ? base::MakeUnique<cc::DirectCompositorFrameSink>( 627 ? base::MakeUnique<cc::DirectCompositorFrameSink>(
595 compositor->frame_sink_id(), surface_manager_.get(), 628 compositor->frame_sink_id(), surface_manager_.get(),
596 data->display.get(), 629 data->display.get(),
597 static_cast<scoped_refptr<cc::VulkanContextProvider>>( 630 static_cast<scoped_refptr<cc::VulkanContextProvider>>(
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
735 } 768 }
736 769
737 void GpuProcessTransportFactory::SetAuthoritativeVSyncInterval( 770 void GpuProcessTransportFactory::SetAuthoritativeVSyncInterval(
738 ui::Compositor* compositor, 771 ui::Compositor* compositor,
739 base::TimeDelta interval) { 772 base::TimeDelta interval) {
740 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor); 773 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
741 if (it == per_compositor_data_.end()) 774 if (it == per_compositor_data_.end())
742 return; 775 return;
743 PerCompositorData* data = it->second.get(); 776 PerCompositorData* data = it->second.get();
744 DCHECK(data); 777 DCHECK(data);
745 if (data->begin_frame_source) 778 if (data->synthetic_begin_frame_source)
746 data->begin_frame_source->SetAuthoritativeVSyncInterval(interval); 779 data->synthetic_begin_frame_source->SetAuthoritativeVSyncInterval(interval);
747 } 780 }
748 781
749 void GpuProcessTransportFactory::SetDisplayVSyncParameters( 782 void GpuProcessTransportFactory::SetDisplayVSyncParameters(
750 ui::Compositor* compositor, 783 ui::Compositor* compositor,
751 base::TimeTicks timebase, 784 base::TimeTicks timebase,
752 base::TimeDelta interval) { 785 base::TimeDelta interval) {
753 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor); 786 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
754 if (it == per_compositor_data_.end()) 787 if (it == per_compositor_data_.end())
755 return; 788 return;
756 PerCompositorData* data = it->second.get(); 789 PerCompositorData* data = it->second.get();
757 DCHECK(data); 790 DCHECK(data);
758 if (data->begin_frame_source) 791 if (data->synthetic_begin_frame_source) {
759 data->begin_frame_source->OnUpdateVSyncParameters(timebase, interval); 792 data->synthetic_begin_frame_source->OnUpdateVSyncParameters(timebase,
793 interval);
794 } else if (data->gpu_vsync_begin_frame_source) {
795 data->gpu_vsync_begin_frame_source->OnVSync(timebase, interval);
796 }
760 } 797 }
761 798
762 void GpuProcessTransportFactory::SetOutputIsSecure(ui::Compositor* compositor, 799 void GpuProcessTransportFactory::SetOutputIsSecure(ui::Compositor* compositor,
763 bool secure) { 800 bool secure) {
764 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor); 801 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
765 if (it == per_compositor_data_.end()) 802 if (it == per_compositor_data_.end())
766 return; 803 return;
767 PerCompositorData* data = it->second.get(); 804 PerCompositorData* data = it->second.get();
768 DCHECK(data); 805 DCHECK(data);
769 data->output_is_secure = secure; 806 data->output_is_secure = secure;
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 shared_vulkan_context_provider_ = 950 shared_vulkan_context_provider_ =
914 cc::VulkanInProcessContextProvider::Create(); 951 cc::VulkanInProcessContextProvider::Create();
915 } 952 }
916 953
917 shared_vulkan_context_provider_initialized_ = true; 954 shared_vulkan_context_provider_initialized_ = true;
918 } 955 }
919 return shared_vulkan_context_provider_; 956 return shared_vulkan_context_provider_;
920 } 957 }
921 958
922 } // namespace content 959 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698