Index: content/browser/compositor/gpu_process_transport_factory.cc |
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc |
index 7107c03b7e7b2ae7b5980c2abf80900ece1d0b55..3ce13e83655057dcac32f37ab89a71b7ff1903f7 100644 |
--- a/content/browser/compositor/gpu_process_transport_factory.cc |
+++ b/content/browser/compositor/gpu_process_transport_factory.cc |
@@ -60,6 +60,8 @@ |
using cc::ContextProvider; |
using gpu::gles2::GLES2Interface; |
+static const int kNumRetriesBeforeSoftwareFallback = 4; |
no sievers
2015/02/25 01:51:00
nit: use anonymous namespace, drop static
|
+ |
namespace content { |
struct GpuProcessTransportFactory::PerCompositorData { |
@@ -126,139 +128,139 @@ scoped_ptr<cc::OverlayCandidateValidator> CreateOverlayCandidateValidator( |
return scoped_ptr<cc::OverlayCandidateValidator>(); |
} |
+static bool CreateGpuOutputSurface() { |
piman
2015/02/25 01:44:47
nit: ShouldCreateGpuOuputSurface? (this doesn't cr
no sievers
2015/02/25 01:51:00
nit: ShouldCreateGpuOutputSurface() or ShouldUseGp
danakj
2015/02/25 21:25:38
+1
|
+#if defined(OS_CHROMEOS) |
+ // Software fallback does not happen on Chrome OS. |
+ return true; |
+#endif |
+ |
+#if defined(OS_WIN) |
+ if (::GetProp(compositor->widget(), kForceSoftwareCompositor) && |
+ ::RemoveProp(compositor->widget(), kForceSoftwareCompositor)) |
+ return false; |
+#endif |
+ |
+ return GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor(); |
+} |
+ |
void GpuProcessTransportFactory::CreateOutputSurface( |
- base::WeakPtr<ui::Compositor> compositor, |
- bool software_fallback) { |
+ base::WeakPtr<ui::Compositor> compositor) { |
DCHECK(!!compositor); |
PerCompositorData* data = per_compositor_data_[compositor.get()]; |
if (!data) |
data = CreatePerCompositorData(compositor.get()); |
- bool create_software_renderer = software_fallback; |
-#if defined(OS_CHROMEOS) |
- // Software fallback does not happen on Chrome OS. |
- create_software_renderer = false; |
-#elif defined(OS_WIN) |
- if (::GetProp(compositor->widget(), kForceSoftwareCompositor)) { |
- if (::RemoveProp(compositor->widget(), kForceSoftwareCompositor)) |
- create_software_renderer = true; |
- } |
-#endif |
- if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor()) |
- create_software_renderer = true; |
- |
- if (!create_software_renderer) { |
+ bool create_gpu_output_surface = CreateGpuOutputSurface(); |
+ if (create_gpu_output_surface) { |
CauseForGpuLaunch cause = |
CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE; |
BrowserGpuChannelHostFactory::instance()->EstablishGpuChannel( |
- cause, |
- base::Bind(&GpuProcessTransportFactory::EstablishedGpuChannel, |
- callback_factory_.GetWeakPtr(), |
- compositor, |
- create_software_renderer)); |
+ cause, base::Bind(&GpuProcessTransportFactory::EstablishedGpuChannel, |
+ callback_factory_.GetWeakPtr(), compositor, |
+ create_gpu_output_surface, 0)); |
} else { |
- EstablishedGpuChannel(compositor, create_software_renderer); |
+ EstablishedGpuChannel(compositor, create_gpu_output_surface, 0); |
} |
} |
void GpuProcessTransportFactory::EstablishedGpuChannel( |
base::WeakPtr<ui::Compositor> compositor, |
- bool create_software_renderer) { |
+ bool create_gpu_output_surface, |
+ int num_attempts) { |
if (!compositor) |
return; |
PerCompositorData* data = per_compositor_data_[compositor.get()]; |
DCHECK(data); |
- scoped_refptr<GpuChannelHost> gpu_channel_host = |
- BrowserGpuChannelHostFactory::instance()->GetGpuChannel(); |
+ |
+ if (num_attempts > kNumRetriesBeforeSoftwareFallback) { |
+#if defined(OS_CHROMEOS) |
+ LOG(FATAL) << "Unable to create a UI graphics context, and cannot use " |
+ << "software compositing on ChromeOS."; |
+#endif |
+ create_gpu_output_surface = false; |
+ } |
+ |
scoped_refptr<ContextProviderCommandBuffer> context_provider; |
- if (gpu_channel_host.get() && !create_software_renderer) { |
- context_provider = ContextProviderCommandBuffer::Create( |
- GpuProcessTransportFactory::CreateContextCommon(gpu_channel_host, |
- data->surface_id), |
- "Compositor"); |
- if (!context_provider->BindToCurrentThread()) |
- context_provider = nullptr; |
+ if (create_gpu_output_surface) { |
+ scoped_refptr<GpuChannelHost> gpu_channel_host = |
+ BrowserGpuChannelHostFactory::instance()->GetGpuChannel(); |
+ if (gpu_channel_host.get()) { |
+ context_provider = ContextProviderCommandBuffer::Create( |
+ GpuProcessTransportFactory::CreateContextCommon(gpu_channel_host, |
+ data->surface_id), |
+ "Compositor"); |
+ if (context_provider && !context_provider->BindToCurrentThread()) |
+ context_provider = nullptr; |
+ } |
+ |
+ UMA_HISTOGRAM_BOOLEAN("Aura.CreatedGpuBrowserCompositor", |
+ !!context_provider.get()); |
+ |
+ if (!context_provider) { |
+ // Try again. |
+ CauseForGpuLaunch cause = |
+ CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE; |
+ BrowserGpuChannelHostFactory::instance()->EstablishGpuChannel( |
+ cause, base::Bind(&GpuProcessTransportFactory::EstablishedGpuChannel, |
+ callback_factory_.GetWeakPtr(), compositor, |
+ create_gpu_output_surface, num_attempts + 1)); |
+ return; |
+ } |
} |
- UMA_HISTOGRAM_BOOLEAN("Aura.CreatedGpuBrowserCompositor", |
- !!context_provider.get()); |
- |
- if (UseSurfacesEnabled()) { |
- // This gets a bit confusing. Here we have a ContextProvider configured to |
- // render directly to this widget. We need to make an OnscreenDisplayClient |
- // associated with this context, then return a SurfaceDisplayOutputSurface |
- // set up to draw to the display's surface. |
- cc::SurfaceManager* manager = surface_manager_.get(); |
- scoped_ptr<cc::OutputSurface> display_surface; |
- if (!context_provider.get()) { |
- display_surface = |
- make_scoped_ptr(new SoftwareBrowserCompositorOutputSurface( |
- CreateSoftwareOutputDevice(compositor.get()), |
- data->surface_id, |
- &output_surface_map_, |
- compositor->vsync_manager())); |
- } else { |
- display_surface = make_scoped_ptr(new GpuBrowserCompositorOutputSurface( |
- context_provider, |
- data->surface_id, |
- &output_surface_map_, |
+ scoped_ptr<BrowserCompositorOutputSurface> surface; |
+ if (!create_gpu_output_surface) { |
+ surface = make_scoped_ptr(new SoftwareBrowserCompositorOutputSurface( |
+ CreateSoftwareOutputDevice(compositor.get()), data->surface_id, |
+ &output_surface_map_, compositor->vsync_manager())); |
+ } else { |
+ DCHECK(context_provider); |
+#if defined(USE_OZONE) |
+ if (ui::SurfaceFactoryOzone::GetInstance() |
+ ->CanShowPrimaryPlaneAsOverlay()) { |
+ surface = |
+ make_scoped_ptr(new GpuSurfacelessBrowserCompositorOutputSurface( |
+ context_provider, data->surface_id, &output_surface_map_, |
+ compositor->vsync_manager(), |
+ CreateOverlayCandidateValidator(compositor->widget()), GL_RGB, |
+ BrowserGpuMemoryBufferManager::current())); |
+ } else |
+#endif |
+ { |
+ surface = make_scoped_ptr(new GpuBrowserCompositorOutputSurface( |
+ context_provider, data->surface_id, &output_surface_map_, |
compositor->vsync_manager(), |
CreateOverlayCandidateValidator(compositor->widget()))); |
} |
- scoped_ptr<cc::OnscreenDisplayClient> display_client( |
- new cc::OnscreenDisplayClient( |
- display_surface.Pass(), manager, HostSharedBitmapManager::current(), |
- BrowserGpuMemoryBufferManager::current(), |
- compositor->GetRendererSettings(), compositor->task_runner())); |
- |
- scoped_ptr<cc::SurfaceDisplayOutputSurface> output_surface( |
- new cc::SurfaceDisplayOutputSurface( |
- manager, compositor->surface_id_allocator(), context_provider)); |
- display_client->set_surface_output_surface(output_surface.get()); |
- output_surface->set_display_client(display_client.get()); |
- display_client->display()->Resize(compositor->size()); |
- data->display_client = display_client.Pass(); |
- compositor->SetOutputSurface(output_surface.Pass()); |
- return; |
} |
- if (!context_provider.get()) { |
-#if defined(OS_CHROMEOS) |
- LOG(FATAL) << "Shouldn't use software compositing on ChromeOS."; |
-#endif |
+ if (data->reflector) |
+ data->reflector->OnSourceSurfaceReady(surface.get()); |
- scoped_ptr<SoftwareBrowserCompositorOutputSurface> surface( |
- new SoftwareBrowserCompositorOutputSurface( |
- CreateSoftwareOutputDevice(compositor.get()), |
- data->surface_id, |
- &output_surface_map_, |
- compositor->vsync_manager())); |
+ if (!UseSurfacesEnabled()) { |
compositor->SetOutputSurface(surface.Pass()); |
return; |
} |
- scoped_ptr<BrowserCompositorOutputSurface> surface; |
-#if defined(USE_OZONE) |
- if (ui::SurfaceFactoryOzone::GetInstance()->CanShowPrimaryPlaneAsOverlay()) { |
- surface.reset(new GpuSurfacelessBrowserCompositorOutputSurface( |
- context_provider, data->surface_id, &output_surface_map_, |
- compositor->vsync_manager(), |
- CreateOverlayCandidateValidator(compositor->widget()), GL_RGB, |
- BrowserGpuMemoryBufferManager::current())); |
- } |
-#endif |
- if (!surface) |
- surface.reset(new GpuBrowserCompositorOutputSurface( |
- context_provider, |
- data->surface_id, |
- &output_surface_map_, |
- compositor->vsync_manager(), |
- CreateOverlayCandidateValidator(compositor->widget()))); |
- |
- if (data->reflector.get()) |
- data->reflector->OnSourceSurfaceReady(surface.get()); |
- |
- compositor->SetOutputSurface(surface.Pass()); |
+ // This gets a bit confusing. Here we have a ContextProvider in the |surface| |
+ // configured to render directly to this widget. We need to make an |
+ // OnscreenDisplayClient associated with that context, then return a |
+ // SurfaceDisplayOutputSurface set up to draw to the display's surface. |
+ cc::SurfaceManager* manager = surface_manager_.get(); |
+ scoped_ptr<cc::OnscreenDisplayClient> display_client( |
+ new cc::OnscreenDisplayClient( |
+ surface.Pass(), manager, HostSharedBitmapManager::current(), |
+ BrowserGpuMemoryBufferManager::current(), |
+ compositor->GetRendererSettings(), compositor->task_runner())); |
+ |
+ scoped_ptr<cc::SurfaceDisplayOutputSurface> output_surface( |
+ new cc::SurfaceDisplayOutputSurface( |
+ manager, compositor->surface_id_allocator(), context_provider)); |
+ display_client->set_surface_output_surface(output_surface.get()); |
+ output_surface->set_display_client(display_client.get()); |
+ display_client->display()->Resize(compositor->size()); |
+ data->display_client = display_client.Pass(); |
+ compositor->SetOutputSurface(output_surface.Pass()); |
} |
scoped_refptr<ui::Reflector> GpuProcessTransportFactory::CreateReflector( |