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

Unified Diff: content/browser/compositor/gpu_process_transport_factory.cc

Issue 953803005: ui: Move software fallback decisions to GpuProcessTransportFactory. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 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 side-by-side diff with in-line comments
Download patch
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(

Powered by Google App Engine
This is Rietveld 408576698