summaryrefslogtreecommitdiff
path: root/chromium/content/browser/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/browser/gpu')
-rw-r--r--chromium/content/browser/gpu/OWNERS1
-rw-r--r--chromium/content/browser/gpu/browser_gpu_channel_host_factory.cc23
-rw-r--r--chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.cc13
-rw-r--r--chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.h9
-rw-r--r--chromium/content/browser/gpu/ca_transaction_gpu_coordinator.cc115
-rw-r--r--chromium/content/browser/gpu/ca_transaction_gpu_coordinator.h60
-rw-r--r--chromium/content/browser/gpu/compositor_util.cc23
-rw-r--r--chromium/content/browser/gpu/gpu_client_impl.cc97
-rw-r--r--chromium/content/browser/gpu/gpu_client_impl.h62
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_impl.cc33
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_impl.h44
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_impl_private.cc179
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_impl_private.h33
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc42
-rw-r--r--chromium/content/browser/gpu/gpu_internals_ui.cc74
-rw-r--r--chromium/content/browser/gpu/gpu_process_host.cc345
-rw-r--r--chromium/content/browser/gpu/gpu_process_host.h42
17 files changed, 773 insertions, 422 deletions
diff --git a/chromium/content/browser/gpu/OWNERS b/chromium/content/browser/gpu/OWNERS
index c45f8fa6e23..55d9b9bde3d 100644
--- a/chromium/content/browser/gpu/OWNERS
+++ b/chromium/content/browser/gpu/OWNERS
@@ -1,5 +1,6 @@
kbr@chromium.org
piman@chromium.org
zmo@chromium.org
+backer@chromium.org
# COMPONENT: Internals>GPU>Internals
diff --git a/chromium/content/browser/gpu/browser_gpu_channel_host_factory.cc b/chromium/content/browser/gpu/browser_gpu_channel_host_factory.cc
index cdc4d3d678a..ca32413b3f3 100644
--- a/chromium/content/browser/gpu/browser_gpu_channel_host_factory.cc
+++ b/chromium/content/browser/gpu/browser_gpu_channel_host_factory.cc
@@ -4,6 +4,7 @@
#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
+#include "base/android/orderfile/orderfile_buildflags.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/location.h"
@@ -15,6 +16,7 @@
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
+#include "components/viz/common/features.h"
#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/gpu/gpu_process_host.h"
@@ -26,10 +28,15 @@
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "gpu/command_buffer/service/gpu_switches.h"
+#include "gpu/ipc/in_process_command_buffer.h"
#include "services/resource_coordinator/public/mojom/memory_instrumentation/constants.mojom.h"
#include "services/service_manager/runner/common/client_util.h"
#include "ui/base/ui_base_features.h"
+#if defined(OS_MACOSX)
+#include "ui/accelerated_widget_mac/window_resize_helper_mac.h"
+#endif
+
namespace content {
#if defined(OS_ANDROID)
@@ -105,7 +112,13 @@ BrowserGpuChannelHostFactory::EstablishRequest::EstablishRequest(
gpu_client_id_(gpu_client_id),
gpu_client_tracing_id_(gpu_client_tracing_id),
finished_(false),
- main_task_runner_(base::ThreadTaskRunnerHandle::Get()) {}
+#if defined(OS_MACOSX)
+ main_task_runner_(ui::WindowResizeHelperMac::Get()->task_runner())
+#else
+ main_task_runner_(base::ThreadTaskRunnerHandle::Get())
+#endif
+{
+}
void BrowserGpuChannelHostFactory::EstablishRequest::RestartTimeout() {
BrowserGpuChannelHostFactory* factory =
@@ -273,7 +286,7 @@ BrowserGpuChannelHostFactory::~BrowserGpuChannelHostFactory() {
void BrowserGpuChannelHostFactory::EstablishGpuChannel(
gpu::GpuChannelEstablishedCallback callback) {
#if defined(USE_AURA)
- DCHECK(!base::FeatureList::IsEnabled(::features::kMash));
+ DCHECK(features::IsAshInBrowserProcess());
#endif
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (gpu_channel_.get() && gpu_channel_->IsLost()) {
@@ -352,7 +365,7 @@ void BrowserGpuChannelHostFactory::RestartTimeout() {
return;
#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \
- defined(CYGPROFILE_INSTRUMENTATION)
+ BUILDFLAG(ORDERFILE_INSTRUMENTATION)
constexpr int64_t kGpuChannelTimeoutInSeconds = 40;
#else
// The GPU watchdog timeout is 15 seconds (1.5x the kGpuTimeout value due to
@@ -371,6 +384,10 @@ void BrowserGpuChannelHostFactory::InitializeShaderDiskCacheOnIO(
int gpu_client_id,
const base::FilePath& cache_dir) {
GetShaderCacheFactorySingleton()->SetCacheInfo(gpu_client_id, cache_dir);
+ if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor)) {
+ GetShaderCacheFactorySingleton()->SetCacheInfo(
+ gpu::InProcessCommandBuffer::kGpuClientId, cache_dir);
+ }
}
} // namespace content
diff --git a/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.cc b/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.cc
index 22d03d380b4..8568d3f5885 100644
--- a/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.cc
+++ b/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.cc
@@ -141,7 +141,7 @@ void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForChildProcess(
auto handle = gpu::GpuMemoryBufferImplSharedMemory::CreateGpuMemoryBuffer(
id, size, format, usage);
buffers.find(id)->second.shared_memory_guid = handle.handle.GetGUID();
- std::move(callback).Run(handle);
+ std::move(callback).Run(std::move(handle));
}
void BrowserGpuMemoryBufferManager::SetDestructionSyncToken(
@@ -310,7 +310,7 @@ void BrowserGpuMemoryBufferManager::HandleCreateGpuMemoryBufferOnIO(
void BrowserGpuMemoryBufferManager::HandleGpuMemoryBufferCreatedOnIO(
CreateGpuMemoryBufferRequest* request,
- const gfx::GpuMemoryBufferHandle& handle) {
+ gfx::GpuMemoryBufferHandle handle) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// Early out if factory failed to create the buffer.
@@ -321,15 +321,16 @@ void BrowserGpuMemoryBufferManager::HandleGpuMemoryBufferCreatedOnIO(
// Note: Unretained is safe as IO thread is stopped before manager is
// destroyed.
+ auto handle_id = handle.id;
request->result =
gpu_memory_buffer_support_->CreateGpuMemoryBufferImplFromHandle(
- handle, request->size, request->format, request->usage,
+ std::move(handle), request->size, request->format, request->usage,
base::Bind(
&GpuMemoryBufferDeleted,
BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
base::Bind(
&BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO,
- base::Unretained(this), handle.id, request->client_id)));
+ base::Unretained(this), handle_id, request->client_id)));
request->event.Signal();
}
@@ -377,7 +378,7 @@ void BrowserGpuMemoryBufferManager::GpuMemoryBufferCreatedOnIO(
int client_id,
int gpu_host_id,
CreateCallback callback,
- const gfx::GpuMemoryBufferHandle& handle,
+ gfx::GpuMemoryBufferHandle handle,
GpuProcessHost::BufferCreationStatus status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -432,7 +433,7 @@ void BrowserGpuMemoryBufferManager::GpuMemoryBufferCreatedOnIO(
buffer_it->second.gpu_host_id = gpu_host_id;
buffer_it->second.shared_memory_guid = handle.handle.GetGUID();
- std::move(callback).Run(handle);
+ std::move(callback).Run(std::move(handle));
}
void BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO(
diff --git a/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.h b/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.h
index 41843a9309c..4cf2b632fb0 100644
--- a/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.h
+++ b/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.h
@@ -33,7 +33,7 @@ class CONTENT_EXPORT BrowserGpuMemoryBufferManager
public base::trace_event::MemoryDumpProvider {
public:
using CreateCallback =
- base::OnceCallback<void(const gfx::GpuMemoryBufferHandle& handle)>;
+ base::OnceCallback<void(gfx::GpuMemoryBufferHandle handle)>;
using AllocationCallback = CreateCallback;
BrowserGpuMemoryBufferManager(int gpu_client_id,
@@ -98,9 +98,8 @@ class CONTENT_EXPORT BrowserGpuMemoryBufferManager
// Functions that handle synchronous buffer creation requests.
void HandleCreateGpuMemoryBufferOnIO(CreateGpuMemoryBufferRequest* request);
- void HandleGpuMemoryBufferCreatedOnIO(
- CreateGpuMemoryBufferRequest* request,
- const gfx::GpuMemoryBufferHandle& handle);
+ void HandleGpuMemoryBufferCreatedOnIO(CreateGpuMemoryBufferRequest* request,
+ gfx::GpuMemoryBufferHandle handle);
// Functions that implement asynchronous buffer creation.
void CreateGpuMemoryBufferOnIO(gfx::GpuMemoryBufferId id,
@@ -115,7 +114,7 @@ class CONTENT_EXPORT BrowserGpuMemoryBufferManager
int client_id,
int gpu_host_id,
CreateCallback callback,
- const gfx::GpuMemoryBufferHandle& handle,
+ gfx::GpuMemoryBufferHandle handle,
GpuProcessHost::BufferCreationStatus status);
void DestroyGpuMemoryBufferOnIO(gfx::GpuMemoryBufferId id,
int client_id,
diff --git a/chromium/content/browser/gpu/ca_transaction_gpu_coordinator.cc b/chromium/content/browser/gpu/ca_transaction_gpu_coordinator.cc
new file mode 100644
index 00000000000..8f3efa6a705
--- /dev/null
+++ b/chromium/content/browser/gpu/ca_transaction_gpu_coordinator.cc
@@ -0,0 +1,115 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/gpu/ca_transaction_gpu_coordinator.h"
+
+#include "base/cancelable_callback.h"
+#include "content/browser/gpu/gpu_process_host.h"
+#include "content/public/browser/browser_thread.h"
+#include "services/viz/privileged/interfaces/gl/gpu_service.mojom.h"
+#include "ui/accelerated_widget_mac/ca_transaction_observer.h"
+#include "ui/accelerated_widget_mac/window_resize_helper_mac.h"
+
+namespace content {
+
+// static
+scoped_refptr<CATransactionGPUCoordinator> CATransactionGPUCoordinator::Create(
+ GpuProcessHost* host) {
+ scoped_refptr<CATransactionGPUCoordinator> result(
+ new CATransactionGPUCoordinator(host));
+ // Avoid modifying result's refcount in the constructor by performing this
+ // PostTask afterward.
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ ui::WindowResizeHelperMac::Get()->task_runner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &CATransactionGPUCoordinator::AddPostCommitObserverOnUIThread,
+ result));
+ return result;
+}
+
+CATransactionGPUCoordinator::CATransactionGPUCoordinator(GpuProcessHost* host)
+ : host_(host) {}
+
+CATransactionGPUCoordinator::~CATransactionGPUCoordinator() {
+ DCHECK(!host_);
+ DCHECK(!registered_as_observer_);
+}
+
+void CATransactionGPUCoordinator::HostWillBeDestroyed() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ ui::WindowResizeHelperMac::Get()->task_runner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &CATransactionGPUCoordinator::RemovePostCommitObserverOnUIThread,
+ this));
+ host_ = nullptr;
+}
+
+void CATransactionGPUCoordinator::AddPostCommitObserverOnUIThread() {
+ DCHECK(!registered_as_observer_);
+ ui::CATransactionCoordinator::Get().AddPostCommitObserver(this);
+ registered_as_observer_ = true;
+}
+
+void CATransactionGPUCoordinator::RemovePostCommitObserverOnUIThread() {
+ DCHECK(registered_as_observer_);
+ ui::CATransactionCoordinator::Get().RemovePostCommitObserver(this);
+ registered_as_observer_ = false;
+}
+
+void CATransactionGPUCoordinator::OnActivateForTransaction() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&CATransactionGPUCoordinator::OnActivateForTransactionOnIO,
+ this));
+}
+
+void CATransactionGPUCoordinator::OnEnterPostCommit() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ // If HostWillBeDestroyed() is called during a commit, pending_commit_count_
+ // may be left non-zero. That's fine as long as this instance is destroyed
+ // (and removed from the list of post-commit observers) soon after.
+ pending_commit_count_++;
+
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&CATransactionGPUCoordinator::OnEnterPostCommitOnIO,
+ this));
+}
+
+bool CATransactionGPUCoordinator::ShouldWaitInPostCommit() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ return pending_commit_count_ > 0;
+}
+
+void CATransactionGPUCoordinator::OnActivateForTransactionOnIO() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (host_)
+ host_->gpu_service()->BeginCATransaction();
+}
+
+void CATransactionGPUCoordinator::OnEnterPostCommitOnIO() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (host_)
+ host_->gpu_service()->CommitCATransaction(base::BindOnce(
+ &CATransactionGPUCoordinator::OnCommitCompletedOnIO, this));
+}
+
+void CATransactionGPUCoordinator::OnCommitCompletedOnIO() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ ui::WindowResizeHelperMac::Get()->task_runner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&CATransactionGPUCoordinator::OnCommitCompletedOnUI,
+ this));
+}
+
+void CATransactionGPUCoordinator::OnCommitCompletedOnUI() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ pending_commit_count_--;
+}
+
+} // namespace content
diff --git a/chromium/content/browser/gpu/ca_transaction_gpu_coordinator.h b/chromium/content/browser/gpu/ca_transaction_gpu_coordinator.h
new file mode 100644
index 00000000000..53b52a25d3f
--- /dev/null
+++ b/chromium/content/browser/gpu/ca_transaction_gpu_coordinator.h
@@ -0,0 +1,60 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_GPU_CA_TRANSACTION_GPU_COORDINATOR_H_
+#define CONTENT_BROWSER_GPU_CA_TRANSACTION_GPU_COORDINATOR_H_
+
+#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
+#include "ui/accelerated_widget_mac/ca_transaction_observer.h"
+
+#include <memory>
+
+namespace content {
+
+class GpuProcessHost;
+
+// Synchronizes CATransaction commits between the browser and GPU processes.
+class CATransactionGPUCoordinator
+ : public ui::CATransactionCoordinator::PostCommitObserver {
+ public:
+ static scoped_refptr<CATransactionGPUCoordinator> Create(
+ GpuProcessHost* host);
+ void HostWillBeDestroyed();
+
+ private:
+ friend class base::RefCountedThreadSafe<CATransactionGPUCoordinator>;
+ CATransactionGPUCoordinator(GpuProcessHost* host);
+ ~CATransactionGPUCoordinator() override;
+
+ // ui::CATransactionObserver implementation
+ void OnActivateForTransaction() override;
+ void OnEnterPostCommit() override;
+ bool ShouldWaitInPostCommit() override;
+
+ void AddPostCommitObserverOnUIThread();
+ void RemovePostCommitObserverOnUIThread();
+
+ void OnActivateForTransactionOnIO();
+ void OnEnterPostCommitOnIO();
+ void OnCommitCompletedOnIO();
+ void OnCommitCompletedOnUI();
+
+ // The GpuProcessHost to use to initiate GPU-side CATransactions. This is only
+ // to be accessed on the IO thread.
+ GpuProcessHost* host_ = nullptr;
+
+ // The number CATransactions that have not yet completed. This is only to be
+ // accessed on the UI thread.
+ int pending_commit_count_ = 0;
+
+ // Egregious state tracking to debug https://crbug.com/871430
+ bool registered_as_observer_ = false;
+
+ DISALLOW_COPY_AND_ASSIGN(CATransactionGPUCoordinator);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_GPU_CA_TRANSACTION_GPU_COORDINATOR_H_
diff --git a/chromium/content/browser/gpu/compositor_util.cc b/chromium/content/browser/gpu/compositor_util.cc
index db3b6606770..9773ec885ea 100644
--- a/chromium/content/browser/gpu/compositor_util.cc
+++ b/chromium/content/browser/gpu/compositor_util.cc
@@ -161,6 +161,13 @@ const GpuFeatureData GetGpuFeatureData(
"Accelerated rasterization has been disabled, either via blacklist, "
"about:flags or the command line.",
true, true},
+ {"oop_rasterization",
+ SafeGetFeatureStatus(gpu_feature_info,
+ gpu::GPU_FEATURE_TYPE_OOP_RASTERIZATION),
+ command_line.HasSwitch(switches::kDisableOopRasterization),
+ "Out-of-process accelerated rasterization has been disabled, either "
+ "via blacklist, about:flags or the command line.",
+ false, true},
{"multiple_raster_threads", gpu::kGpuFeatureStatusEnabled,
NumberOfRendererRasterThreads() == 1, "Raster is using a single thread.",
false, true},
@@ -215,8 +222,12 @@ std::unique_ptr<base::DictionaryValue> GetFeatureStatusImpl(
const GpuFeatureData gpu_feature_data =
GetGpuFeatureData(gpu_feature_info, type, i, &eof);
std::string status;
- if (gpu_feature_data.disabled || gpu_access_blocked ||
- gpu_feature_data.status == gpu::kGpuFeatureStatusDisabled) {
+ if (gpu_feature_data.name == "surface_synchronization") {
+ status = (!gpu_feature_data.disabled ? "enabled_on" : "disabled_off");
+ } else if (gpu_feature_data.name == "viz_display_compositor") {
+ status = (!gpu_feature_data.disabled ? "enabled_on" : "disabled_off");
+ } else if (gpu_feature_data.disabled || gpu_access_blocked ||
+ gpu_feature_data.status == gpu::kGpuFeatureStatusDisabled) {
status = "disabled";
if (gpu_feature_data.fallback_to_software)
status += "_software";
@@ -244,14 +255,6 @@ std::unique_ptr<base::DictionaryValue> GetFeatureStatusImpl(
status += "_force";
status += "_on";
}
- if (gpu_feature_data.name == "surface_synchronization") {
- if (features::IsSurfaceSynchronizationEnabled())
- status += "_on";
- }
- if (gpu_feature_data.name == "viz_display_compositor") {
- if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor))
- status += "_on";
- }
if (gpu_feature_data.name == "skia_renderer") {
if (features::IsUsingSkiaRenderer())
status += "_on";
diff --git a/chromium/content/browser/gpu/gpu_client_impl.cc b/chromium/content/browser/gpu/gpu_client_impl.cc
index a591794d329..c2ef9591cd3 100644
--- a/chromium/content/browser/gpu/gpu_client_impl.cc
+++ b/chromium/content/browser/gpu/gpu_client_impl.cc
@@ -7,7 +7,6 @@
#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/common/child_process_host_impl.h"
-#include "content/public/browser/browser_thread.h"
#include "gpu/ipc/client/gpu_channel_host.h"
#include "gpu/ipc/common/gpu_memory_buffer_impl.h"
#include "gpu/ipc/common/gpu_memory_buffer_impl_shared_memory.h"
@@ -15,51 +14,67 @@
namespace content {
// static
-std::unique_ptr<GpuClient, BrowserThread::DeleteOnIOThread> GpuClient::Create(
+std::unique_ptr<GpuClient, base::OnTaskRunnerDeleter> GpuClient::Create(
ui::mojom::GpuRequest request,
- ConnectionErrorHandlerClosure connection_error_handler) {
- std::unique_ptr<GpuClientImpl, BrowserThread::DeleteOnIOThread> gpu_client(
- new GpuClientImpl(ChildProcessHostImpl::GenerateChildProcessUniqueId()));
+ ConnectionErrorHandlerClosure connection_error_handler,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
+ const int client_id = ChildProcessHostImpl::GenerateChildProcessUniqueId();
+ const uint64_t client_tracing_id =
+ ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId(client_id);
+ std::unique_ptr<GpuClientImpl, base::OnTaskRunnerDeleter> gpu_client(
+ new GpuClientImpl(client_id, client_tracing_id, task_runner),
+ base::OnTaskRunnerDeleter(task_runner));
gpu_client->SetConnectionErrorHandler(std::move(connection_error_handler));
gpu_client->Add(std::move(request));
return gpu_client;
}
-GpuClientImpl::GpuClientImpl(int render_process_id)
- : render_process_id_(render_process_id), weak_factory_(this) {
- bindings_.set_connection_error_handler(
- base::Bind(&GpuClientImpl::OnError, base::Unretained(this),
- ErrorReason::kConnectionLost));
+GpuClientImpl::GpuClientImpl(
+ int client_id,
+ uint64_t client_tracing_id,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ : client_id_(client_id),
+ client_tracing_id_(client_tracing_id),
+ task_runner_(std::move(task_runner)),
+ weak_factory_(this) {
+ gpu_bindings_.set_connection_error_handler(
+ base::BindRepeating(&GpuClientImpl::OnError, base::Unretained(this),
+ ErrorReason::kConnectionLost));
}
GpuClientImpl::~GpuClientImpl() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- bindings_.CloseAllBindings();
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ gpu_bindings_.CloseAllBindings();
OnError(ErrorReason::kInDestructor);
}
void GpuClientImpl::Add(ui::mojom::GpuRequest request) {
- bindings_.AddBinding(this, std::move(request));
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ gpu_bindings_.AddBinding(this, std::move(request));
}
void GpuClientImpl::OnError(ErrorReason reason) {
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
ClearCallback();
- if (bindings_.empty()) {
+ if (gpu_bindings_.empty()) {
BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager =
BrowserGpuMemoryBufferManager::current();
if (gpu_memory_buffer_manager)
- gpu_memory_buffer_manager->ProcessRemoved(render_process_id_);
+ gpu_memory_buffer_manager->ProcessRemoved(client_id_);
}
if (reason == ErrorReason::kConnectionLost && connection_error_handler_)
std::move(connection_error_handler_).Run(this);
}
void GpuClientImpl::PreEstablishGpuChannel() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&GpuClientImpl::EstablishGpuChannel,
- base::Unretained(this), EstablishGpuChannelCallback()));
+ if (task_runner_->RunsTasksInCurrentSequence()) {
+ EstablishGpuChannel(EstablishGpuChannelCallback());
+ } else {
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&GpuClientImpl::EstablishGpuChannel,
+ base::Unretained(this), EstablishGpuChannelCallback()));
+ }
}
void GpuClientImpl::SetConnectionErrorHandler(
@@ -85,8 +100,8 @@ void GpuClientImpl::OnEstablishGpuChannel(
}
if (callback) {
// A request is waiting.
- std::move(callback).Run(render_process_id_, std::move(channel_handle),
- gpu_info, gpu_feature_info);
+ std::move(callback).Run(client_id_, std::move(channel_handle), gpu_info,
+ gpu_feature_info);
return;
}
if (status == GpuProcessHost::EstablishChannelStatus::SUCCESS) {
@@ -100,21 +115,21 @@ void GpuClientImpl::OnEstablishGpuChannel(
void GpuClientImpl::OnCreateGpuMemoryBuffer(
CreateGpuMemoryBufferCallback callback,
- const gfx::GpuMemoryBufferHandle& handle) {
- std::move(callback).Run(handle);
+ gfx::GpuMemoryBufferHandle handle) {
+ std::move(callback).Run(std::move(handle));
}
void GpuClientImpl::ClearCallback() {
if (!callback_)
return;
EstablishGpuChannelCallback callback = std::move(callback_);
- std::move(callback).Run(render_process_id_, mojo::ScopedMessagePipeHandle(),
+ std::move(callback).Run(client_id_, mojo::ScopedMessagePipeHandle(),
gpu::GPUInfo(), gpu::GpuFeatureInfo());
DCHECK(!callback_);
}
void GpuClientImpl::EstablishGpuChannel(EstablishGpuChannelCallback callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
// At most one channel should be requested. So clear previous request first.
ClearCallback();
if (channel_handle_.is_valid()) {
@@ -123,8 +138,8 @@ void GpuClientImpl::EstablishGpuChannel(EstablishGpuChannelCallback callback) {
// 2) if callback is empty, it's PreEstablishGpyChannel() being called
// more than once, no need to do anything.
if (callback) {
- std::move(callback).Run(render_process_id_, std::move(channel_handle_),
- gpu_info_, gpu_feature_info_);
+ std::move(callback).Run(client_id_, std::move(channel_handle_), gpu_info_,
+ gpu_feature_info_);
DCHECK(!channel_handle_.is_valid());
}
return;
@@ -132,9 +147,8 @@ void GpuClientImpl::EstablishGpuChannel(EstablishGpuChannelCallback callback) {
GpuProcessHost* host = GpuProcessHost::Get();
if (!host) {
if (callback) {
- std::move(callback).Run(render_process_id_,
- mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
- gpu::GpuFeatureInfo());
+ std::move(callback).Run(client_id_, mojo::ScopedMessagePipeHandle(),
+ gpu::GPUInfo(), gpu::GpuFeatureInfo());
}
return;
}
@@ -146,12 +160,10 @@ void GpuClientImpl::EstablishGpuChannel(EstablishGpuChannelCallback callback) {
bool allow_view_command_buffers = false;
bool allow_real_time_streams = false;
host->EstablishGpuChannel(
- render_process_id_,
- ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId(
- render_process_id_),
- preempts, allow_view_command_buffers, allow_real_time_streams,
- base::Bind(&GpuClientImpl::OnEstablishGpuChannel,
- weak_factory_.GetWeakPtr()));
+ client_id_, client_tracing_id_, preempts, allow_view_command_buffers,
+ allow_real_time_streams,
+ base::BindRepeating(&GpuClientImpl::OnEstablishGpuChannel,
+ weak_factory_.GetWeakPtr()));
}
void GpuClientImpl::CreateJpegDecodeAccelerator(
@@ -175,7 +187,7 @@ void GpuClientImpl::CreateGpuMemoryBuffer(
const gfx::Size& size,
gfx::BufferFormat format,
gfx::BufferUsage usage,
- ui::mojom::Gpu::CreateGpuMemoryBufferCallback callback) {
+ ui::mojom::GpuMemoryBufferFactory::CreateGpuMemoryBufferCallback callback) {
DCHECK(BrowserGpuMemoryBufferManager::current());
base::CheckedNumeric<int> bytes = size.width();
@@ -187,7 +199,7 @@ void GpuClientImpl::CreateGpuMemoryBuffer(
BrowserGpuMemoryBufferManager::current()
->AllocateGpuMemoryBufferForChildProcess(
- id, size, format, usage, render_process_id_,
+ id, size, format, usage, client_id_,
base::BindOnce(&GpuClientImpl::OnCreateGpuMemoryBuffer,
weak_factory_.GetWeakPtr(), std::move(callback)));
}
@@ -197,7 +209,12 @@ void GpuClientImpl::DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
DCHECK(BrowserGpuMemoryBufferManager::current());
BrowserGpuMemoryBufferManager::current()->ChildProcessDeletedGpuMemoryBuffer(
- id, render_process_id_, sync_token);
+ id, client_id_, sync_token);
+}
+
+void GpuClientImpl::CreateGpuMemoryBufferFactory(
+ ui::mojom::GpuMemoryBufferFactoryRequest request) {
+ gpu_memory_buffer_factory_bindings_.AddBinding(this, std::move(request));
}
} // namespace content
diff --git a/chromium/content/browser/gpu/gpu_client_impl.h b/chromium/content/browser/gpu/gpu_client_impl.h
index 03e29bf4b5f..70e684a68be 100644
--- a/chromium/content/browser/gpu/gpu_client_impl.h
+++ b/chromium/content/browser/gpu/gpu_client_impl.h
@@ -13,11 +13,19 @@
namespace content {
-class GpuClientImpl : public ui::mojom::Gpu, public GpuClient {
+class GpuClientImpl : public ui::mojom::GpuMemoryBufferFactory,
+ public ui::mojom::Gpu,
+ public GpuClient {
public:
- explicit GpuClientImpl(int render_process_id);
+ // GpuClientImpl must be destroyed on the thread associated with
+ // |task_runner|.
+ GpuClientImpl(int client_id,
+ uint64_t client_tracing_id,
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
+
~GpuClientImpl() override;
+ // This needs to be run on the thread associated with |task_runner_|.
void Add(ui::mojom::GpuRequest request);
void PreEstablishGpuChannel();
@@ -25,6 +33,27 @@ class GpuClientImpl : public ui::mojom::Gpu, public GpuClient {
void SetConnectionErrorHandler(
ConnectionErrorHandlerClosure connection_error_handler);
+ // ui::mojom::GpuMemoryBufferFactory overrides:
+ void CreateGpuMemoryBuffer(
+ gfx::GpuMemoryBufferId id,
+ const gfx::Size& size,
+ gfx::BufferFormat format,
+ gfx::BufferUsage usage,
+ ui::mojom::GpuMemoryBufferFactory::CreateGpuMemoryBufferCallback callback)
+ override;
+ void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
+ const gpu::SyncToken& sync_token) override;
+
+ // ui::mojom::Gpu overrides:
+ void CreateGpuMemoryBufferFactory(
+ ui::mojom::GpuMemoryBufferFactoryRequest request) override;
+ void EstablishGpuChannel(EstablishGpuChannelCallback callback) override;
+ void CreateJpegDecodeAccelerator(
+ media::mojom::JpegDecodeAcceleratorRequest jda_request) override;
+ void CreateVideoEncodeAcceleratorProvider(
+ media::mojom::VideoEncodeAcceleratorProviderRequest vea_provider_request)
+ override;
+
private:
enum class ErrorReason {
// OnError() is being called from the destructor.
@@ -38,33 +67,24 @@ class GpuClientImpl : public ui::mojom::Gpu, public GpuClient {
const gpu::GpuFeatureInfo& gpu_feature_info,
GpuProcessHost::EstablishChannelStatus status);
void OnCreateGpuMemoryBuffer(CreateGpuMemoryBufferCallback callback,
- const gfx::GpuMemoryBufferHandle& handle);
+ gfx::GpuMemoryBufferHandle handle);
void ClearCallback();
- // ui::mojom::Gpu overrides:
- void EstablishGpuChannel(EstablishGpuChannelCallback callback) override;
- void CreateJpegDecodeAccelerator(
- media::mojom::JpegDecodeAcceleratorRequest jda_request) override;
- void CreateVideoEncodeAcceleratorProvider(
- media::mojom::VideoEncodeAcceleratorProviderRequest vea_provider_request)
- override;
- void CreateGpuMemoryBuffer(
- gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- ui::mojom::Gpu::CreateGpuMemoryBufferCallback callback) override;
- void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
- const gpu::SyncToken& sync_token) override;
-
- const int render_process_id_;
- mojo::BindingSet<ui::mojom::Gpu> bindings_;
+ const int client_id_;
+ const uint64_t client_tracing_id_;
+ mojo::BindingSet<ui::mojom::GpuMemoryBufferFactory>
+ gpu_memory_buffer_factory_bindings_;
+ mojo::BindingSet<ui::mojom::Gpu> gpu_bindings_;
bool gpu_channel_requested_ = false;
EstablishGpuChannelCallback callback_;
mojo::ScopedMessagePipeHandle channel_handle_;
gpu::GPUInfo gpu_info_;
gpu::GpuFeatureInfo gpu_feature_info_;
ConnectionErrorHandlerClosure connection_error_handler_;
+ // |task_runner_| is associated with the thread |gpu_bindings_| is bound on.
+ // GpuClientImpl instance is bound to this thread, and must be destroyed on
+ // this thread.
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
base::WeakPtrFactory<GpuClientImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(GpuClientImpl);
diff --git a/chromium/content/browser/gpu/gpu_data_manager_impl.cc b/chromium/content/browser/gpu/gpu_data_manager_impl.cc
index 3c8b665a48a..f6d3d4c18f1 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_impl.cc
+++ b/chromium/content/browser/gpu/gpu_data_manager_impl.cc
@@ -16,7 +16,8 @@ GpuDataManager* GpuDataManager::GetInstance() {
// static
GpuDataManagerImpl* GpuDataManagerImpl::GetInstance() {
- return base::Singleton<GpuDataManagerImpl>::get();
+ static base::NoDestructor<GpuDataManagerImpl> instance;
+ return instance.get();
}
void GpuDataManagerImpl::BlacklistWebGLForTesting() {
@@ -79,16 +80,6 @@ void GpuDataManagerImpl::DisableHardwareAcceleration() {
private_->DisableHardwareAcceleration();
}
-void GpuDataManagerImpl::BlockSwiftShader() {
- base::AutoLock auto_lock(lock_);
- private_->BlockSwiftShader();
-}
-
-bool GpuDataManagerImpl::SwiftShaderAllowed() const {
- base::AutoLock auto_lock(lock_);
- return private_->SwiftShaderAllowed();
-}
-
bool GpuDataManagerImpl::HardwareAccelerationEnabled() const {
base::AutoLock auto_lock(lock_);
return private_->HardwareAccelerationEnabled();
@@ -207,9 +198,14 @@ void GpuDataManagerImpl::NotifyGpuInfoUpdate() {
private_->NotifyGpuInfoUpdate();
}
-void GpuDataManagerImpl::OnGpuProcessInitFailure() {
+gpu::GpuMode GpuDataManagerImpl::GetGpuMode() const {
+ base::AutoLock auto_lock(lock_);
+ return private_->GetGpuMode();
+}
+
+void GpuDataManagerImpl::FallBackToNextGpuMode() {
base::AutoLock auto_lock(lock_);
- private_->OnGpuProcessInitFailure();
+ private_->FallBackToNextGpuMode();
}
bool GpuDataManagerImpl::IsGpuProcessUsingHardwareGpu() const {
@@ -217,11 +213,14 @@ bool GpuDataManagerImpl::IsGpuProcessUsingHardwareGpu() const {
return private_->IsGpuProcessUsingHardwareGpu();
}
-GpuDataManagerImpl::GpuDataManagerImpl()
- : private_(GpuDataManagerImplPrivate::Create(this)) {
+void GpuDataManagerImpl::SetApplicationVisible(bool is_visible) {
+ base::AutoLock auto_lock(lock_);
+ private_->SetApplicationVisible(is_visible);
}
-GpuDataManagerImpl::~GpuDataManagerImpl() {
-}
+GpuDataManagerImpl::GpuDataManagerImpl()
+ : private_(std::make_unique<GpuDataManagerImplPrivate>(this)) {}
+
+GpuDataManagerImpl::~GpuDataManagerImpl() = default;
} // namespace content
diff --git a/chromium/content/browser/gpu/gpu_data_manager_impl.h b/chromium/content/browser/gpu/gpu_data_manager_impl.h
index 06210a34e80..d91d77659f3 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_impl.h
+++ b/chromium/content/browser/gpu/gpu_data_manager_impl.h
@@ -14,7 +14,7 @@
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/macros.h"
-#include "base/memory/singleton.h"
+#include "base/no_destructor.h"
#include "base/process/kill.h"
#include "base/synchronization/lock.h"
#include "base/time/time.h"
@@ -24,6 +24,7 @@
#include "gpu/config/gpu_control_list.h"
#include "gpu/config/gpu_feature_info.h"
#include "gpu/config/gpu_info.h"
+#include "gpu/config/gpu_mode.h"
class GURL;
@@ -149,44 +150,27 @@ class CONTENT_EXPORT GpuDataManagerImpl : public GpuDataManager {
// status update.
void NotifyGpuInfoUpdate();
- // Called when GPU process initialization failed.
- void OnGpuProcessInitFailure();
+ // Return mode describing what the GPU process will be launched to run.
+ gpu::GpuMode GetGpuMode() const;
- void BlockSwiftShader();
- bool SwiftShaderAllowed() const;
+ // Called when GPU process initialization failed or the GPU process has
+ // crashed repeatedly. This will try to disable hardware acceleration and then
+ // SwiftShader WebGL. It will also crash the browser process as a last resort
+ // on Android and Chrome OS.
+ void FallBackToNextGpuMode();
// Returns false if the latest GPUInfo gl_renderer is from SwiftShader or
// Disabled (in the viz case).
bool IsGpuProcessUsingHardwareGpu() const;
+ // State tracking allows us to customize GPU process launch depending on
+ // whether we are in the foreground or background.
+ void SetApplicationVisible(bool is_visible);
+
private:
friend class GpuDataManagerImplPrivate;
friend class GpuDataManagerImplPrivateTest;
- friend struct base::DefaultSingletonTraits<GpuDataManagerImpl>;
-
- // It's similar to AutoUnlock, but we want to make it a no-op
- // if the owner GpuDataManagerImpl is null.
- // This should only be used by GpuDataManagerImplPrivate where
- // callbacks are called, during which re-entering
- // GpuDataManagerImpl is possible.
- class UnlockedSession {
- public:
- explicit UnlockedSession(GpuDataManagerImpl* owner)
- : owner_(owner) {
- DCHECK(owner_);
- owner_->lock_.AssertAcquired();
- owner_->lock_.Release();
- }
-
- ~UnlockedSession() {
- DCHECK(owner_);
- owner_->lock_.Acquire();
- }
-
- private:
- GpuDataManagerImpl* owner_;
- DISALLOW_COPY_AND_ASSIGN(UnlockedSession);
- };
+ friend class base::NoDestructor<GpuDataManagerImpl>;
GpuDataManagerImpl();
~GpuDataManagerImpl() override;
diff --git a/chromium/content/browser/gpu/gpu_data_manager_impl_private.cc b/chromium/content/browser/gpu/gpu_data_manager_impl_private.cc
index e3b41337158..63797576500 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_impl_private.cc
+++ b/chromium/content/browser/gpu/gpu_data_manager_impl_private.cc
@@ -32,17 +32,16 @@
#include "content/public/common/content_constants.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
-#include "gpu/command_buffer/service/gpu_preferences.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "gpu/config/gpu_blacklist.h"
#include "gpu/config/gpu_driver_bug_list.h"
#include "gpu/config/gpu_driver_bug_workaround_type.h"
#include "gpu/config/gpu_finch_features.h"
#include "gpu/config/gpu_info_collector.h"
+#include "gpu/config/gpu_preferences.h"
#include "gpu/config/gpu_switches.h"
#include "gpu/config/gpu_util.h"
#include "gpu/config/software_rendering_list_autogen.h"
-#include "gpu/ipc/common/gpu_preferences_util.h"
#include "gpu/ipc/common/memory_stats.h"
#include "gpu/ipc/host/gpu_memory_buffer_support.h"
#include "gpu/ipc/host/shader_disk_cache.h"
@@ -118,18 +117,21 @@ void UpdateFeatureStats(const gpu::GpuFeatureInfo& gpu_feature_info) {
gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS,
gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING,
gpu::GPU_FEATURE_TYPE_GPU_RASTERIZATION,
+ gpu::GPU_FEATURE_TYPE_OOP_RASTERIZATION,
gpu::GPU_FEATURE_TYPE_ACCELERATED_WEBGL,
gpu::GPU_FEATURE_TYPE_ACCELERATED_WEBGL2};
const std::string kGpuBlacklistFeatureHistogramNames[] = {
"GPU.BlacklistFeatureTestResults.Accelerated2dCanvas",
"GPU.BlacklistFeatureTestResults.GpuCompositing",
"GPU.BlacklistFeatureTestResults.GpuRasterization",
+ "GPU.BlacklistFeatureTestResults.OopRasterization",
"GPU.BlacklistFeatureTestResults.Webgl",
"GPU.BlacklistFeatureTestResults.Webgl2"};
const bool kGpuFeatureUserFlags[] = {
command_line.HasSwitch(switches::kDisableAccelerated2dCanvas),
command_line.HasSwitch(switches::kDisableGpu),
command_line.HasSwitch(switches::kDisableGpuRasterization),
+ command_line.HasSwitch(switches::kDisableOopRasterization),
command_line.HasSwitch(switches::kDisableWebGL),
(command_line.HasSwitch(switches::kDisableWebGL) ||
command_line.HasSwitch(switches::kDisableWebGL2))};
@@ -138,6 +140,7 @@ void UpdateFeatureStats(const gpu::GpuFeatureInfo& gpu_feature_info) {
"GPU.BlacklistFeatureTestResultsWindows2.Accelerated2dCanvas",
"GPU.BlacklistFeatureTestResultsWindows2.GpuCompositing",
"GPU.BlacklistFeatureTestResultsWindows2.GpuRasterization",
+ "GPU.BlacklistFeatureTestResultsWindows2.OopRasterization",
"GPU.BlacklistFeatureTestResultsWindows2.Webgl",
"GPU.BlacklistFeatureTestResultsWindows2.Webgl2"};
#endif
@@ -263,6 +266,35 @@ void UpdateGpuInfoOnIO(const gpu::GPUInfo& gpu_info) {
} // anonymous namespace
+GpuDataManagerImplPrivate::GpuDataManagerImplPrivate(GpuDataManagerImpl* owner)
+ : owner_(owner),
+ observer_list_(base::MakeRefCounted<GpuDataManagerObserverList>()) {
+ DCHECK(owner_);
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switches::kDisableGpu))
+ DisableHardwareAcceleration();
+
+ if (command_line->HasSwitch(switches::kSingleProcess) ||
+ command_line->HasSwitch(switches::kInProcessGPU)) {
+ in_process_gpu_ = true;
+ AppendGpuCommandLine(command_line);
+ }
+
+#if defined(OS_MACOSX)
+ CGDisplayRegisterReconfigurationCallback(DisplayReconfigCallback, owner_);
+#endif // OS_MACOSX
+
+ // For testing only.
+ if (command_line->HasSwitch(switches::kDisableDomainBlockingFor3DAPIs))
+ domain_blocking_enabled_ = false;
+}
+
+GpuDataManagerImplPrivate::~GpuDataManagerImplPrivate() {
+#if defined(OS_MACOSX)
+ CGDisplayRemoveReconfigurationCallback(DisplayReconfigCallback, owner_);
+#endif
+}
+
void GpuDataManagerImplPrivate::BlacklistWebGLForTesting() {
// This function is for testing only, so disable histograms.
update_histograms_ = false;
@@ -286,8 +318,7 @@ gpu::GPUInfo GpuDataManagerImplPrivate::GetGPUInfoForHardwareGpu() const {
return gpu_info_for_hardware_gpu_;
}
-bool GpuDataManagerImplPrivate::GpuAccessAllowed(
- std::string* reason) const {
+bool GpuDataManagerImplPrivate::GpuAccessAllowed(std::string* reason) const {
bool swiftshader_available = false;
#if BUILDFLAG(ENABLE_SWIFTSHADER)
if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
@@ -322,8 +353,19 @@ bool GpuDataManagerImplPrivate::GpuAccessAllowed(
}
bool GpuDataManagerImplPrivate::GpuProcessStartAllowed() const {
- return base::FeatureList::IsEnabled(features::kVizDisplayCompositor) ||
- GpuAccessAllowed(nullptr);
+ if (GpuAccessAllowed(nullptr))
+ return true;
+
+#if defined(USE_X11) || defined(OS_MACOSX)
+ // If GPU access is disabled with OOP-D we run the display compositor in:
+ // Browser process: Windows
+ // GPU process: Linux and Mac
+ // N/A: Android and Chrome OS (GPU access can't be disabled)
+ if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor))
+ return true;
+#endif
+
+ return false;
}
void GpuDataManagerImplPrivate::RequestCompleteGpuInfoIfNeeded() {
@@ -395,13 +437,11 @@ void GpuDataManagerImplPrivate::RequestVideoMemoryUsageStatsUpdate(
}
void GpuDataManagerImplPrivate::AddObserver(GpuDataManagerObserver* observer) {
- GpuDataManagerImpl::UnlockedSession session(owner_);
observer_list_->AddObserver(observer);
}
void GpuDataManagerImplPrivate::RemoveObserver(
GpuDataManagerObserver* observer) {
- GpuDataManagerImpl::UnlockedSession session(owner_);
observer_list_->RemoveObserver(observer);
}
@@ -514,7 +554,7 @@ void GpuDataManagerImplPrivate::AppendGpuCommandLine(
gpu::GpuPreferences gpu_prefs = GetGpuPreferencesFromCommandLine();
UpdateGpuPreferences(&gpu_prefs);
command_line->AppendSwitchASCII(switches::kGpuPreferences,
- gpu::GpuPreferencesToSwitchValue(gpu_prefs));
+ gpu_prefs.ToSwitchValue());
std::string use_gl;
if (card_disabled_ && SwiftShaderAllowed()) {
@@ -560,6 +600,8 @@ void GpuDataManagerImplPrivate::UpdateGpuPreferences(
gpu_preferences->texture_target_exception_list =
gpu::CreateBufferUsageAndFormatExceptionList();
+
+ gpu_preferences->watchdog_starts_backgrounded = !application_is_visible_;
}
void GpuDataManagerImplPrivate::DisableHardwareAcceleration() {
@@ -572,11 +614,6 @@ bool GpuDataManagerImplPrivate::HardwareAccelerationEnabled() const {
return !card_disabled_;
}
-void GpuDataManagerImplPrivate::BlockSwiftShader() {
- swiftshader_blocked_ = true;
- OnGpuBlocked();
-}
-
bool GpuDataManagerImplPrivate::SwiftShaderAllowed() const {
#if !BUILDFLAG(ENABLE_SWIFTSHADER)
return false;
@@ -613,27 +650,15 @@ void GpuDataManagerImplPrivate::AddLogMessage(
void GpuDataManagerImplPrivate::ProcessCrashed(
base::TerminationStatus exit_code) {
- if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- // Unretained is ok, because it's posted to UI thread, the thread
- // where the singleton GpuDataManagerImpl lives until the end.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(&GpuDataManagerImpl::ProcessCrashed,
- base::Unretained(owner_), exit_code));
- return;
- }
- {
- GpuDataManagerImpl::UnlockedSession session(owner_);
- observer_list_->Notify(
- FROM_HERE, &GpuDataManagerObserver::OnGpuProcessCrashed, exit_code);
- }
+ observer_list_->Notify(
+ FROM_HERE, &GpuDataManagerObserver::OnGpuProcessCrashed, exit_code);
}
std::unique_ptr<base::ListValue> GpuDataManagerImplPrivate::GetLogMessages()
const {
auto value = std::make_unique<base::ListValue>();
for (size_t ii = 0; ii < log_messages_.size(); ++ii) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ auto dict = std::make_unique<base::DictionaryValue>();
dict->SetInteger("level", log_messages_[ii].level);
dict->SetString("header", log_messages_[ii].header);
dict->SetString("message", log_messages_[ii].message);
@@ -643,7 +668,7 @@ std::unique_ptr<base::ListValue> GpuDataManagerImplPrivate::GetLogMessages()
}
void GpuDataManagerImplPrivate::HandleGpuSwitch() {
- GpuDataManagerImpl::UnlockedSession session(owner_);
+ base::AutoUnlock unlock(owner_->lock_);
// Notify observers in the browser process.
ui::GpuSwitchingManager::GetInstance()->NotifyGpuSwitched();
// Pass the notification to the GPU process to notify observers there.
@@ -701,48 +726,6 @@ void GpuDataManagerImplPrivate::DisableDomainBlockingFor3DAPIsForTesting() {
domain_blocking_enabled_ = false;
}
-// static
-GpuDataManagerImplPrivate* GpuDataManagerImplPrivate::Create(
- GpuDataManagerImpl* owner) {
- return new GpuDataManagerImplPrivate(owner);
-}
-
-GpuDataManagerImplPrivate::GpuDataManagerImplPrivate(GpuDataManagerImpl* owner)
- : complete_gpu_info_already_requested_(false),
- observer_list_(new GpuDataManagerObserverList),
- card_disabled_(false),
- swiftshader_blocked_(false),
- update_histograms_(true),
- domain_blocking_enabled_(true),
- owner_(owner),
- in_process_gpu_(false) {
- DCHECK(owner_);
- base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
- if (command_line->HasSwitch(switches::kDisableGpu))
- DisableHardwareAcceleration();
-
- if (command_line->HasSwitch(switches::kSingleProcess) ||
- command_line->HasSwitch(switches::kInProcessGPU)) {
- in_process_gpu_ = true;
- AppendGpuCommandLine(command_line);
- }
-
-#if defined(OS_MACOSX)
- CGDisplayRegisterReconfigurationCallback(DisplayReconfigCallback, owner_);
-#endif // OS_MACOSX
-
- // For testing only.
- if (command_line->HasSwitch(switches::kDisableDomainBlockingFor3DAPIs)) {
- domain_blocking_enabled_ = false;
- }
-}
-
-GpuDataManagerImplPrivate::~GpuDataManagerImplPrivate() {
-#if defined(OS_MACOSX)
- CGDisplayRemoveReconfigurationCallback(DisplayReconfigCallback, owner_);
-#endif
-}
-
void GpuDataManagerImplPrivate::NotifyGpuInfoUpdate() {
observer_list_->Notify(FROM_HERE, &GpuDataManagerObserver::OnGpuInfoUpdate);
}
@@ -756,8 +739,11 @@ bool GpuDataManagerImplPrivate::IsGpuProcessUsingHardwareGpu() const {
return true;
}
-std::string GpuDataManagerImplPrivate::GetDomainFromURL(
- const GURL& url) const {
+void GpuDataManagerImplPrivate::SetApplicationVisible(bool is_visible) {
+ application_is_visible_ = is_visible;
+}
+
+std::string GpuDataManagerImplPrivate::GetDomainFromURL(const GURL& url) const {
// For the moment, we just use the host, or its IP address, as the
// entry in the set, rather than trying to figure out the top-level
// domain. This does mean that a.foo.com and b.foo.com will be
@@ -860,21 +846,44 @@ bool GpuDataManagerImplPrivate::NeedsCompleteGpuInfoCollection() const {
#endif
}
-void GpuDataManagerImplPrivate::OnGpuProcessInitFailure() {
+gpu::GpuMode GpuDataManagerImplPrivate::GetGpuMode() const {
+ if (HardwareAccelerationEnabled()) {
+ return gpu::GpuMode::HARDWARE_ACCELERATED;
+ } else if (SwiftShaderAllowed()) {
+ return gpu::GpuMode::SWIFTSHADER;
+ } else if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor)) {
+ return gpu::GpuMode::DISPLAY_COMPOSITOR;
+ } else {
+ return gpu::GpuMode::DISABLED;
+ }
+}
+
+void GpuDataManagerImplPrivate::FallBackToNextGpuMode() {
+#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
+ // Android and Chrome OS can't switch to software compositing. If the GPU
+ // process initialization fails or GPU process is too unstable then crash the
+ // browser process to reset everything.
+ LOG(FATAL) << "GPU process isn't usable. Goodbye.";
+#else
+ // TODO(kylechar): Use GpuMode to store the current mode instead of
+ // multiple bools.
+
if (!card_disabled_) {
DisableHardwareAcceleration();
- return;
- }
- if (SwiftShaderAllowed()) {
- BlockSwiftShader();
- return;
- }
- if (!base::FeatureList::IsEnabled(features::kVizDisplayCompositor)) {
- // When Viz display compositor is not enabled, if GPU process fails to
- // launch with hardware GPU, and then fails to launch with SwiftShader if
- // available, then GPU process should not launch again.
+ } else if (SwiftShaderAllowed()) {
+ swiftshader_blocked_ = true;
+ OnGpuBlocked();
+ } else if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor)) {
+ // The GPU process is frequently crashing with only the display compositor
+ // running. This should never happen so something is wrong. Crash the
+ // browser process to reset everything.
+ LOG(FATAL) << "The display compositor is frequently crashing. Goodbye.";
+ } else {
+ // We are already at GpuMode::DISABLED. We shouldn't be launching the GPU
+ // process for it to fail.
NOTREACHED();
}
+#endif
}
} // namespace content
diff --git a/chromium/content/browser/gpu/gpu_data_manager_impl_private.h b/chromium/content/browser/gpu/gpu_data_manager_impl_private.h
index a84efd1a461..68fc14b5286 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_impl_private.h
+++ b/chromium/content/browser/gpu/gpu_data_manager_impl_private.h
@@ -37,7 +37,8 @@ namespace content {
class CONTENT_EXPORT GpuDataManagerImplPrivate {
public:
- static GpuDataManagerImplPrivate* Create(GpuDataManagerImpl* owner);
+ explicit GpuDataManagerImplPrivate(GpuDataManagerImpl* owner);
+ virtual ~GpuDataManagerImplPrivate();
void BlacklistWebGLForTesting();
gpu::GPUInfo GetGPUInfo() const;
@@ -57,7 +58,6 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
void UnblockDomainFrom3DAPIs(const GURL& url);
void DisableHardwareAcceleration();
bool HardwareAccelerationEnabled() const;
- void BlockSwiftShader();
bool SwiftShaderAllowed() const;
void UpdateGpuInfo(
@@ -99,14 +99,15 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
bool UpdateActiveGpu(uint32_t vendor_id, uint32_t device_id);
- void OnGpuProcessInitFailure();
+ gpu::GpuMode GetGpuMode() const;
+ void FallBackToNextGpuMode();
// Notify all observers whenever there is a GPU info update.
void NotifyGpuInfoUpdate();
bool IsGpuProcessUsingHardwareGpu() const;
- virtual ~GpuDataManagerImplPrivate();
+ void SetApplicationVisible(bool is_visible);
private:
friend class GpuDataManagerImplPrivateTest;
@@ -128,10 +129,10 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
GpuDataManagerImpl::DomainGuilt last_guilt;
};
- typedef std::map<std::string, DomainBlockEntry> DomainBlockMap;
+ using DomainBlockMap = std::map<std::string, DomainBlockEntry>;
- typedef base::ObserverListThreadSafe<GpuDataManagerObserver>
- GpuDataManagerObserverList;
+ using GpuDataManagerObserverList =
+ base::ObserverListThreadSafe<GpuDataManagerObserver>;
struct LogMessage {
int level;
@@ -146,8 +147,6 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
message(_message) { }
};
- explicit GpuDataManagerImplPrivate(GpuDataManagerImpl* owner);
-
// Called when GPU access (hardware acceleration and swiftshader) becomes
// blocked.
void OnGpuBlocked();
@@ -170,7 +169,9 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
// 3) all other platforms, this returns false.
bool NeedsCompleteGpuInfoCollection() const;
- bool complete_gpu_info_already_requested_;
+ GpuDataManagerImpl* const owner_;
+
+ bool complete_gpu_info_already_requested_ = false;
gpu::GpuFeatureInfo gpu_feature_info_;
gpu::GPUInfo gpu_info_;
@@ -187,23 +188,23 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
// Current card force-disabled due to GPU crashes, or disabled through
// the --disable-gpu commandline switch.
- bool card_disabled_;
+ bool card_disabled_ = false;
// SwiftShader force-blocked due to GPU crashes using SwiftShader.
- bool swiftshader_blocked_;
+ bool swiftshader_blocked_ = false;
// We disable histogram stuff in testing, especially in unit tests because
// they cause random failures.
- bool update_histograms_;
+ bool update_histograms_ = true;
DomainBlockMap blocked_domains_;
mutable std::list<base::Time> timestamps_of_gpu_resets_;
- bool domain_blocking_enabled_;
+ bool domain_blocking_enabled_ = true;
- GpuDataManagerImpl* owner_;
+ bool application_is_visible_ = true;
// True if --single-process or --in-process-gpu is passed in.
- bool in_process_gpu_;
+ bool in_process_gpu_ = false;
DISALLOW_COPY_AND_ASSIGN(GpuDataManagerImplPrivate);
};
diff --git a/chromium/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc b/chromium/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc
index a105555d01f..bb1ddc7b334 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc
+++ b/chromium/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc
@@ -21,12 +21,6 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
-#if defined(OS_WIN)
-#include "base/win/windows_version.h"
-#endif
-
-#define LONG_STRING_CONST(...) #__VA_ARGS__
-
namespace content {
namespace {
@@ -72,18 +66,14 @@ class GpuDataManagerImplPrivateTest : public testing::Test {
// so we can make a little helper class here.
class ScopedGpuDataManagerImpl {
public:
- ScopedGpuDataManagerImpl() : impl_(new GpuDataManagerImpl()) {
- EXPECT_TRUE(impl_);
- EXPECT_TRUE(impl_->private_.get());
- }
- ~ScopedGpuDataManagerImpl() { delete impl_; }
-
- GpuDataManagerImpl* get() const { return impl_; }
+ ScopedGpuDataManagerImpl() { EXPECT_TRUE(impl_.private_.get()); }
+ ~ScopedGpuDataManagerImpl() = default;
- GpuDataManagerImpl* operator->() const { return impl_; }
+ GpuDataManagerImpl* get() { return &impl_; }
+ GpuDataManagerImpl* operator->() { return &impl_; }
private:
- GpuDataManagerImpl* impl_;
+ GpuDataManagerImpl impl_;
DISALLOW_COPY_AND_ASSIGN(ScopedGpuDataManagerImpl);
};
@@ -91,29 +81,17 @@ class GpuDataManagerImplPrivateTest : public testing::Test {
// in the GpuDataManagerImpl constructor.
class ScopedGpuDataManagerImplPrivate {
public:
- ScopedGpuDataManagerImplPrivate() : impl_(new GpuDataManagerImpl()) {
- EXPECT_TRUE(impl_);
- EXPECT_TRUE(impl_->private_.get());
- }
- ~ScopedGpuDataManagerImplPrivate() { delete impl_; }
+ ScopedGpuDataManagerImplPrivate() { EXPECT_TRUE(impl_.private_.get()); }
+ ~ScopedGpuDataManagerImplPrivate() = default;
- GpuDataManagerImplPrivate* get() const {
- return impl_->private_.get();
- }
-
- GpuDataManagerImplPrivate* operator->() const {
- return impl_->private_.get();
- }
+ GpuDataManagerImplPrivate* get() { return impl_.private_.get(); }
+ GpuDataManagerImplPrivate* operator->() { return impl_.private_.get(); }
private:
- GpuDataManagerImpl* impl_;
+ GpuDataManagerImpl impl_;
DISALLOW_COPY_AND_ASSIGN(ScopedGpuDataManagerImplPrivate);
};
- void SetUp() override {}
-
- void TearDown() override {}
-
base::Time JustBeforeExpiration(const GpuDataManagerImplPrivate* manager);
base::Time JustAfterExpiration(const GpuDataManagerImplPrivate* manager);
void TestBlockingDomainFrom3DAPIs(
diff --git a/chromium/content/browser/gpu/gpu_internals_ui.cc b/chromium/content/browser/gpu/gpu_internals_ui.cc
index 54537e236ac..a64a4419064 100644
--- a/chromium/content/browser/gpu/gpu_internals_ui.cc
+++ b/chromium/content/browser/gpu/gpu_internals_ui.cc
@@ -64,6 +64,8 @@ namespace {
WebUIDataSource* CreateGpuHTMLSource() {
WebUIDataSource* source = WebUIDataSource::Create(kChromeUIGpuHost);
+ source->OverrideContentSecurityPolicyScriptSrc(
+ "script-src chrome://resources 'self' 'unsafe-eval';");
source->SetJsonPath("strings.js");
source->AddResourcePath("gpu_internals.js", IDR_GPU_INTERNALS_JS);
@@ -147,6 +149,7 @@ std::string GPUDeviceToString(const gpu::GPUInfo::GPUDevice& gpu) {
std::unique_ptr<base::ListValue> BasicGpuInfoAsListValue(
const gpu::GPUInfo& gpu_info,
const gpu::GpuFeatureInfo& gpu_feature_info) {
+ const gpu::GPUInfo::GPUDevice& active_gpu = gpu_info.active_gpu();
auto basic_info = std::make_unique<base::ListValue>();
basic_info->Append(NewDescriptionValuePair(
"Initialization time",
@@ -158,15 +161,9 @@ std::unique_ptr<base::ListValue> BasicGpuInfoAsListValue(
"Passthrough Command Decoder",
std::make_unique<base::Value>(gpu_info.passthrough_cmd_decoder)));
basic_info->Append(NewDescriptionValuePair(
- "Direct Composition",
- std::make_unique<base::Value>(gpu_info.direct_composition)));
- basic_info->Append(NewDescriptionValuePair(
- "Supports overlays",
- std::make_unique<base::Value>(gpu_info.supports_overlays)));
- basic_info->Append(NewDescriptionValuePair(
"Sandboxed", std::make_unique<base::Value>(gpu_info.sandboxed)));
- basic_info->Append(NewDescriptionValuePair(
- "GPU0", GPUDeviceToString(gpu_info.gpu)));
+ basic_info->Append(
+ NewDescriptionValuePair("GPU0", GPUDeviceToString(gpu_info.gpu)));
for (size_t i = 0; i < gpu_info.secondary_gpus.size(); ++i) {
basic_info->Append(NewDescriptionValuePair(
base::StringPrintf("GPU%d", static_cast<int>(i + 1)),
@@ -183,6 +180,22 @@ std::unique_ptr<base::ListValue> BasicGpuInfoAsListValue(
basic_info->Append(
NewDescriptionValuePair("Desktop compositing", compositor));
+ basic_info->Append(NewDescriptionValuePair(
+ "Direct Composition",
+ std::make_unique<base::Value>(gpu_info.direct_composition)));
+ basic_info->Append(NewDescriptionValuePair(
+ "Supports overlays",
+ std::make_unique<base::Value>(gpu_info.supports_overlays)));
+
+ auto overlay_capabilities = std::make_unique<base::ListValue>();
+ for (const auto& cap : gpu_info.overlay_capabilities) {
+ overlay_capabilities->Append(NewDescriptionValuePair(
+ gpu::OverlayFormatToString(cap.format),
+ cap.is_scaling_supported ? "SCALING" : "DIRECT"));
+ }
+ basic_info->Append(NewDescriptionValuePair("Overlay capabilities",
+ std::move(overlay_capabilities)));
+
std::vector<gfx::PhysicalDisplaySize> display_sizes =
gfx::GetPhysicalSizeForDisplays();
for (const auto& display_size : display_sizes) {
@@ -208,29 +221,28 @@ std::unique_ptr<base::ListValue> BasicGpuInfoAsListValue(
#endif
basic_info->Append(
- NewDescriptionValuePair("Driver vendor", gpu_info.driver_vendor));
- basic_info->Append(NewDescriptionValuePair("Driver version",
- gpu_info.driver_version));
- basic_info->Append(NewDescriptionValuePair("Driver date",
- gpu_info.driver_date));
+ NewDescriptionValuePair("Driver vendor", active_gpu.driver_vendor));
+ basic_info->Append(
+ NewDescriptionValuePair("Driver version", active_gpu.driver_version));
+ basic_info->Append(
+ NewDescriptionValuePair("Driver date", active_gpu.driver_date));
basic_info->Append(NewDescriptionValuePair("Pixel shader version",
gpu_info.pixel_shader_version));
basic_info->Append(NewDescriptionValuePair("Vertex shader version",
gpu_info.vertex_shader_version));
- basic_info->Append(NewDescriptionValuePair("Max. MSAA samples",
- gpu_info.max_msaa_samples));
+ basic_info->Append(
+ NewDescriptionValuePair("Max. MSAA samples", gpu_info.max_msaa_samples));
basic_info->Append(NewDescriptionValuePair("Machine model name",
gpu_info.machine_model_name));
basic_info->Append(NewDescriptionValuePair("Machine model version",
gpu_info.machine_model_version));
- basic_info->Append(NewDescriptionValuePair("GL_VENDOR",
- gpu_info.gl_vendor));
- basic_info->Append(NewDescriptionValuePair("GL_RENDERER",
- gpu_info.gl_renderer));
- basic_info->Append(NewDescriptionValuePair("GL_VERSION",
- gpu_info.gl_version));
- basic_info->Append(NewDescriptionValuePair("GL_EXTENSIONS",
- gpu_info.gl_extensions));
+ basic_info->Append(NewDescriptionValuePair("GL_VENDOR", gpu_info.gl_vendor));
+ basic_info->Append(
+ NewDescriptionValuePair("GL_RENDERER", gpu_info.gl_renderer));
+ basic_info->Append(
+ NewDescriptionValuePair("GL_VERSION", gpu_info.gl_version));
+ basic_info->Append(
+ NewDescriptionValuePair("GL_EXTENSIONS", gpu_info.gl_extensions));
basic_info->Append(NewDescriptionValuePair(
"Disabled Extensions", gpu_feature_info.disabled_extensions));
basic_info->Append(NewDescriptionValuePair(
@@ -242,8 +254,8 @@ std::unique_ptr<base::ListValue> BasicGpuInfoAsListValue(
basic_info->Append(NewDescriptionValuePair("Window system binding extensions",
gpu_info.gl_ws_extensions));
#if defined(USE_X11)
- basic_info->Append(NewDescriptionValuePair("Window manager",
- ui::GuessWindowManagerName()));
+ basic_info->Append(
+ NewDescriptionValuePair("Window manager", ui::GuessWindowManagerName()));
{
std::unique_ptr<base::Environment> env(base::Environment::Create());
std::string value;
@@ -264,8 +276,8 @@ std::unique_ptr<base::ListValue> BasicGpuInfoAsListValue(
std::string reset_strategy =
base::StringPrintf("0x%04x", gpu_info.gl_reset_notification_strategy);
- basic_info->Append(NewDescriptionValuePair(
- "Reset notification strategy", reset_strategy));
+ basic_info->Append(
+ NewDescriptionValuePair("Reset notification strategy", reset_strategy));
basic_info->Append(NewDescriptionValuePair(
"GPU process crash count",
@@ -436,8 +448,12 @@ std::string GetProfileName(gpu::VideoCodecProfile profile) {
return "dolby vision profile 7";
case gpu::THEORAPROFILE_ANY:
return "theora";
- case gpu::AV1PROFILE_PROFILE0:
- return "av1 profile0";
+ case gpu::AV1PROFILE_PROFILE_MAIN:
+ return "av1 profile main";
+ case gpu::AV1PROFILE_PROFILE_HIGH:
+ return "av1 profile high";
+ case gpu::AV1PROFILE_PROFILE_PRO:
+ return "av1 profile pro";
}
NOTREACHED();
return "";
diff --git a/chromium/content/browser/gpu/gpu_process_host.cc b/chromium/content/browser/gpu/gpu_process_host.cc
index 72708d0f0c7..bdecceea7e6 100644
--- a/chromium/content/browser/gpu/gpu_process_host.cc
+++ b/chromium/content/browser/gpu/gpu_process_host.cc
@@ -15,6 +15,7 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/command_line.h"
+#include "base/debug/alias.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/macros.h"
@@ -23,6 +24,7 @@
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
+#include "base/no_destructor.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -34,14 +36,17 @@
#include "components/viz/common/switches.h"
#include "content/browser/browser_child_process_host_impl.h"
#include "content/browser/browser_main_loop.h"
+#include "content/browser/compositor/image_transport_factory.h"
#include "content/browser/field_trial_recorder.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/gpu/gpu_main_thread_factory.h"
#include "content/browser/gpu/shader_cache_factory.h"
+#include "content/browser/memory/memory_coordinator_impl.h"
#include "content/browser/service_manager/service_manager_context.h"
#include "content/common/child_process_host_impl.h"
#include "content/common/in_process_child_thread_params.h"
+#include "content/common/memory_coordinator.mojom.h"
#include "content/common/service_manager/child_connection.h"
#include "content/common/view_messages.h"
#include "content/public/browser/browser_thread.h"
@@ -55,14 +60,14 @@
#include "content/public/common/sandboxed_process_launcher_delegate.h"
#include "content/public/common/service_manager_connection.h"
#include "content/public/common/service_names.mojom.h"
-#include "gpu/command_buffer/service/gpu_preferences.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "gpu/config/gpu_driver_bug_list.h"
#include "gpu/config/gpu_driver_bug_workaround_type.h"
+#include "gpu/config/gpu_preferences.h"
#include "gpu/ipc/host/shader_disk_cache.h"
+#include "gpu/ipc/in_process_command_buffer.h"
#include "media/base/media_switches.h"
#include "media/media_buildflags.h"
-#include "mojo/edk/embedder/embedder.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/interface_provider.h"
@@ -73,6 +78,7 @@
#include "ui/base/ui_base_features.h"
#include "ui/base/ui_base_switches.h"
#include "ui/display/display_switches.h"
+#include "ui/gfx/font_render_params.h"
#include "ui/gfx/switches.h"
#include "ui/gl/gl_switches.h"
#include "ui/latency/latency_info.h"
@@ -104,18 +110,35 @@
#include "gpu/ipc/common/gpu_surface_tracker.h"
#endif
+#if defined(OS_MACOSX)
+#include "content/browser/gpu/ca_transaction_gpu_coordinator.h"
+#endif
+
namespace content {
base::subtle::Atomic32 GpuProcessHost::gpu_crash_count_ = 0;
-int GpuProcessHost::gpu_recent_crash_count_ = 0;
bool GpuProcessHost::crashed_before_ = false;
-int GpuProcessHost::swiftshader_crash_count_ = 0;
+int GpuProcessHost::hardware_accelerated_recent_crash_count_ = 0;
int GpuProcessHost::swiftshader_recent_crash_count_ = 0;
-int GpuProcessHost::display_compositor_crash_count_ = 0;
int GpuProcessHost::display_compositor_recent_crash_count_ = 0;
namespace {
+// UMA histogram names.
+constexpr char kProcessLifetimeEventsHardwareAccelerated[] =
+ "GPU.ProcessLifetimeEvents.HardwareAccelerated";
+constexpr char kProcessLifetimeEventsSwiftShader[] =
+ "GPU.ProcessLifetimeEvents.SwiftShader";
+constexpr char kProcessLifetimeEventsDisplayCompositor[] =
+ "GPU.ProcessLifetimeEvents.DisplayCompositor";
+
+// Forgive one GPU process crash after this many minutes.
+constexpr int kForgiveGpuCrashMinutes = 60;
+
+// Forgive one GPU process crash, when the GPU process is launched to run only
+// the display compositor, after this many minutes.
+constexpr int kForgiveDisplayCompositorCrashMinutes = 10;
+
// This matches base::TerminationStatus.
// These values are persisted to logs. Entries (except MAX_ENUM) should not be
// renumbered and numeric values should never be reused. Should also avoid
@@ -185,19 +208,21 @@ static const char* const kSwitchNames[] = {
switches::kDisableGLExtensions,
switches::kDisableLogging,
switches::kDisableShaderNameHashing,
+ switches::kDisableSkiaRuntimeOpts,
switches::kDisableWebRtcHWEncoding,
#if defined(OS_WIN)
switches::kEnableAcceleratedVpxDecode,
#endif
switches::kEnableGpuRasterization,
switches::kEnableLogging,
- switches::kEnableOOPRasterization,
switches::kEnableVizDevTools,
switches::kHeadless,
switches::kLoggingLevel,
switches::kEnableLowEndDeviceMode,
switches::kDisableLowEndDeviceMode,
switches::kRunAllCompositorStagesBeforeDraw,
+ switches::kSkiaFontCacheLimitMb,
+ switches::kSkiaResourceCacheLimitMb,
switches::kTestGLLib,
switches::kTraceToConsole,
switches::kUseFakeJpegDecodeAccelerator,
@@ -226,15 +251,19 @@ static const char* const kSwitchNames[] = {
#if defined(OS_ANDROID)
switches::kOrderfileMemoryOptimization,
#endif
+ switches::kWebglAntialiasingMode,
+ switches::kWebglMSAASampleCount,
};
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
enum GPUProcessLifetimeEvent {
- LAUNCHED,
- DIED_FIRST_TIME,
- DIED_SECOND_TIME,
- DIED_THIRD_TIME,
- DIED_FOURTH_TIME,
- GPU_PROCESS_LIFETIME_EVENT_MAX = 100
+ LAUNCHED = 0,
+ // When the GPU process crashes the (DIED_FIRST_TIME + recent_crash_count - 1)
+ // bucket in the appropriate UMA histogram will be incremented. The first
+ // crash will be DIED_FIRST_TIME, the second DIED_FIRST_TIME+1, etc.
+ DIED_FIRST_TIME = 1,
+ GPU_PROCESS_LIFETIME_EVENT_MAX = 100,
};
// Indexed by GpuProcessKind. There is one of each kind maximum. This array may
@@ -442,7 +471,7 @@ void BindDiscardableMemoryRequestOnUI(
DCHECK_CURRENTLY_ON(BrowserThread::UI);
#if defined(USE_AURA)
- if (features::IsMashEnabled()) {
+ if (!features::IsAshInBrowserProcess()) {
ServiceManagerConnection::GetForProcess()->GetConnector()->BindInterface(
ui::mojom::kServiceName, std::move(request));
return;
@@ -455,11 +484,28 @@ void BindDiscardableMemoryRequestOnUI(
BrowserMainLoop::GetInstance()->discardable_shared_memory_manager()));
}
+struct FontRenderParamsOnIO {
+ bool initialized = false;
+ gfx::FontRenderParams params;
+};
+
+FontRenderParamsOnIO& GetFontRenderParamsOnIO() {
+ static base::NoDestructor<FontRenderParamsOnIO> instance;
+ return *instance;
+}
+
+void CreateMemoryCoordinatorHandleForGpuProcess(
+ int gpu_process_id,
+ mojom::MemoryCoordinatorHandleRequest request) {
+ MemoryCoordinatorImpl::GetInstance()->CreateHandle(gpu_process_id,
+ std::move(request));
+}
+
} // anonymous namespace
class GpuProcessHost::ConnectionFilterImpl : public ConnectionFilter {
public:
- ConnectionFilterImpl() {
+ explicit ConnectionFilterImpl(int gpu_process_id) {
auto task_runner = BrowserThread::GetTaskRunnerForThread(BrowserThread::UI);
registry_.AddInterface(base::Bind(&FieldTrialRecorder::Create),
task_runner);
@@ -468,6 +514,11 @@ class GpuProcessHost::ConnectionFilterImpl : public ConnectionFilter {
base::Bind(&BindJavaInterface<media::mojom::AndroidOverlayProvider>),
task_runner);
#endif
+
+ registry_.AddInterface(
+ base::BindRepeating(&CreateMemoryCoordinatorHandleForGpuProcess,
+ gpu_process_id),
+ task_runner);
}
private:
@@ -488,6 +539,16 @@ class GpuProcessHost::ConnectionFilterImpl : public ConnectionFilter {
};
// static
+void GpuProcessHost::InitFontRenderParamsOnIO(
+ const gfx::FontRenderParams& params) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(!GetFontRenderParamsOnIO().initialized);
+
+ GetFontRenderParamsOnIO().initialized = true;
+ GetFontRenderParamsOnIO().params = params;
+}
+
+// static
bool GpuProcessHost::ValidateHost(GpuProcessHost* host) {
// The Gpu process is invalid if it's not using SwiftShader, the card is
// blacklisted, and we can kill it and start over.
@@ -612,17 +673,20 @@ int GpuProcessHost::GetGpuCrashCount() {
}
// static
-void GpuProcessHost::IncrementCrashCount(int* crash_count) {
+void GpuProcessHost::IncrementCrashCount(int forgive_minutes,
+ int* crash_count) {
+ DCHECK_GT(forgive_minutes, 0);
+
// Last time the process crashed.
- static base::Time last_crash_time;
+ static base::TimeTicks last_crash_time;
- // Allow about 1 crash per hour to be removed from the crash count, so very
- // occasional crashes won't eventually add up and prevent the process from
- // launching.
- base::Time current_time = base::Time::Now();
+ // Remove one crash per |forgive_minutes| from the crash count, so occasional
+ // crashes won't add up and eventually prevent using the GPU process.
+ base::TimeTicks current_time = base::TimeTicks::Now();
if (crashed_before_) {
- int hours_different = (current_time - last_crash_time).InHours();
- *crash_count = std::max(0, *crash_count - hours_different);
+ int minutes_delta = (current_time - last_crash_time).InMinutes();
+ int crashes_to_forgive = minutes_delta / forgive_minutes;
+ *crash_count = std::max(0, *crash_count - crashes_to_forgive);
}
++(*crash_count);
@@ -663,6 +727,13 @@ GpuProcessHost::~GpuProcessHost() {
SendOutstandingReplies(EstablishChannelStatus::GPU_HOST_INVALID);
+#if defined(OS_MACOSX)
+ if (ca_transaction_gpu_coordinator_) {
+ ca_transaction_gpu_coordinator_->HostWillBeDestroyed();
+ ca_transaction_gpu_coordinator_ = nullptr;
+ }
+#endif
+
if (status_ == UNKNOWN) {
RunRequestGPUInfoCallbacks(gpu::GPUInfo());
} else {
@@ -806,11 +877,14 @@ bool GpuProcessHost::Init() {
// May be null during test execution.
if (ServiceManagerConnection::GetForProcess()) {
ServiceManagerConnection::GetForProcess()->AddConnectionFilter(
- std::make_unique<ConnectionFilterImpl>());
+ std::make_unique<ConnectionFilterImpl>(process_->GetData().id));
}
process_->GetHost()->CreateChannelMojo();
+ mode_ = GpuDataManagerImpl::GetInstance()->GetGpuMode();
+ DCHECK_NE(mode_, gpu::GpuMode::DISABLED);
+
if (in_process_) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(GetGpuMainThreadFactory());
@@ -819,7 +893,7 @@ bool GpuProcessHost::Init() {
in_process_gpu_thread_.reset(GetGpuMainThreadFactory()(
InProcessChildThreadParams(
base::ThreadTaskRunnerHandle::Get(),
- process_->GetInProcessBrokerClientInvitation(),
+ process_->GetInProcessMojoInvitation(),
process_->child_connection()->service_token()),
gpu_preferences));
base::Thread::Options options;
@@ -850,14 +924,20 @@ bool GpuProcessHost::Init() {
base::BindOnce(&BindDiscardableMemoryRequestOnUI,
std::move(discardable_request)));
+ DCHECK(GetFontRenderParamsOnIO().initialized);
gpu_main_ptr_->CreateGpuService(
mojo::MakeRequest(&gpu_service_ptr_), std::move(host_proxy),
- std::move(discardable_manager_ptr), activity_flags_.CloneHandle());
+ std::move(discardable_manager_ptr), activity_flags_.CloneHandle(),
+ GetFontRenderParamsOnIO().params.subpixel_rendering);
#if defined(USE_OZONE)
InitOzone();
#endif // defined(USE_OZONE)
+#if defined(OS_MACOSX)
+ ca_transaction_gpu_coordinator_ = CATransactionGPUCoordinator::Create(this);
+#endif
+
return true;
}
@@ -916,6 +996,16 @@ void GpuProcessHost::EstablishGpuChannel(
return;
}
+ bool oopd_enabled =
+ base::FeatureList::IsEnabled(features::kVizDisplayCompositor);
+ if (oopd_enabled && client_id == gpu::InProcessCommandBuffer::kGpuClientId) {
+ // The display-compositor in the gpu process uses this special client id.
+ callback.Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
+ gpu::GpuFeatureInfo(),
+ EstablishChannelStatus::GPU_ACCESS_DENIED);
+ return;
+ }
+
DCHECK_EQ(preempts, allow_view_command_buffers);
DCHECK_EQ(preempts, allow_real_time_streams);
bool is_gpu_host = preempts;
@@ -929,6 +1019,8 @@ void GpuProcessHost::EstablishGpuChannel(
if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableGpuShaderDiskCache)) {
CreateChannelCache(client_id);
+ if (oopd_enabled)
+ CreateChannelCache(gpu::InProcessCommandBuffer::kGpuClientId);
}
}
@@ -987,19 +1079,6 @@ void GpuProcessHost::RequestHDRStatus(RequestHDRStatusCallback request_cb) {
gpu_service_ptr_->RequestHDRStatus(std::move(request_cb));
}
-#if defined(OS_ANDROID)
-void GpuProcessHost::SendDestroyingVideoSurface(int surface_id,
- const base::Closure& done_cb) {
- TRACE_EVENT0("gpu", "GpuProcessHost::SendDestroyingVideoSurface");
- DCHECK(send_destroying_video_surface_done_cb_.is_null());
- DCHECK(!done_cb.is_null());
- send_destroying_video_surface_done_cb_ = done_cb;
- gpu_service_ptr_->DestroyingVideoSurface(
- surface_id, base::Bind(&GpuProcessHost::OnDestroyingVideoSurfaceAck,
- weak_ptr_factory_.GetWeakPtr()));
-}
-#endif
-
void GpuProcessHost::OnChannelEstablished(
int client_id,
const EstablishChannelCallback& callback,
@@ -1029,13 +1108,13 @@ void GpuProcessHost::OnChannelEstablished(
}
void GpuProcessHost::OnGpuMemoryBufferCreated(
- const gfx::GpuMemoryBufferHandle& handle) {
+ gfx::GpuMemoryBufferHandle handle) {
TRACE_EVENT0("gpu", "GpuProcessHost::OnGpuMemoryBufferCreated");
DCHECK(!create_gpu_memory_buffer_requests_.empty());
auto callback = std::move(create_gpu_memory_buffer_requests_.front());
create_gpu_memory_buffer_requests_.pop();
- std::move(callback).Run(handle, BufferCreationStatus::SUCCESS);
+ std::move(callback).Run(std::move(handle), BufferCreationStatus::SUCCESS);
}
#if defined(OS_ANDROID)
@@ -1056,6 +1135,11 @@ void GpuProcessHost::OnProcessLaunched() {
}
void GpuProcessHost::OnProcessLaunchFailed(int error_code) {
+ // TODO(crbug.com/849639): Ensure |error_code| is included in crash minidumps.
+ // This is for debugging and should be removed when bug is closed.
+ int process_launch_error_code = error_code;
+ base::debug::Alias(&process_launch_error_code);
+
#if defined(OS_WIN)
if (kind_ == GPU_PROCESS_KIND_SANDBOXED)
RecordAppContainerStatus(error_code, crashed_before_);
@@ -1064,6 +1148,14 @@ void GpuProcessHost::OnProcessLaunchFailed(int error_code) {
}
void GpuProcessHost::OnProcessCrashed(int exit_code) {
+ // TODO(crbug.com/849639): Ensure |exit_code| is included in crash minidumps.
+ // This is for debugging and should be removed when bug is closed.
+ int process_crash_exit_code = exit_code;
+ base::debug::Alias(&process_crash_exit_code);
+
+ // Record crash before doing anything that could start a new GPU process.
+ RecordProcessCrash();
+
// If the GPU process crashed while compiling a shader, we may have invalid
// cached binaries. Completely clear the shader cache to force shader binaries
// to be re-created.
@@ -1079,7 +1171,6 @@ void GpuProcessHost::OnProcessCrashed(int exit_code) {
}
}
SendOutstandingReplies(EstablishChannelStatus::GPU_HOST_INVALID);
- RecordProcessCrash();
ChildProcessTerminationInfo info =
process_->GetTerminationInfo(true /* known_dead */);
@@ -1117,7 +1208,8 @@ void GpuProcessHost::DidFailInitialize() {
UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessInitialized", false);
status_ = FAILURE;
GpuDataManagerImpl* gpu_data_manager = GpuDataManagerImpl::GetInstance();
- gpu_data_manager->OnGpuProcessInitFailure();
+ if (kind_ == GPU_PROCESS_KIND_SANDBOXED)
+ gpu_data_manager->FallBackToNextGpuMode();
RunRequestGPUInfoCallbacks(gpu_data_manager->GetGPUInfo());
}
@@ -1126,7 +1218,7 @@ void GpuProcessHost::DidCreateContextSuccessfully() {
// Android may kill the GPU process to free memory, especially when the app
// is the background, so Android cannot have a hard limit on GPU starts.
// Reset crash count on Android when context creation succeeds.
- gpu_recent_crash_count_ = 0;
+ hardware_accelerated_recent_crash_count_ = 0;
#endif
}
@@ -1193,6 +1285,18 @@ void GpuProcessHost::DidLoseContext(bool offscreen,
GpuDataManagerImpl::GetInstance()->BlockDomainFrom3DAPIs(active_url, guilt);
}
+void GpuProcessHost::DisableGpuCompositing() {
+#if !defined(OS_ANDROID)
+ // TODO(crbug.com/819474): The switch from GPU to software compositing should
+ // be handled here instead of by ImageTransportFactory.
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE, base::BindOnce([]() {
+ if (auto* factory = ImageTransportFactory::GetInstance())
+ factory->DisableGpuCompositing();
+ }));
+#endif
+}
+
void GpuProcessHost::SetChildSurface(gpu::SurfaceHandle parent_handle,
gpu::SurfaceHandle window_handle) {
#if defined(OS_WIN)
@@ -1317,6 +1421,8 @@ bool GpuProcessHost::LaunchGpuProcess() {
GetContentClient()->browser()->AppendExtraCommandLineSwitches(
cmd_line.get(), process_->GetData().id);
+ // TODO(kylechar): The command line flags added here should be based on
+ // |mode_|.
GpuDataManagerImpl::GetInstance()->AppendGpuCommandLine(cmd_line.get());
bool swiftshader_rendering =
(cmd_line->GetSwitchValueASCII(switches::kUseGL) ==
@@ -1338,8 +1444,19 @@ bool GpuProcessHost::LaunchGpuProcess() {
process_->Launch(std::move(delegate), std::move(cmd_line), true);
process_launched_ = true;
- UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents",
- LAUNCHED, GPU_PROCESS_LIFETIME_EVENT_MAX);
+ if (kind_ == GPU_PROCESS_KIND_SANDBOXED) {
+ if (mode_ == gpu::GpuMode::HARDWARE_ACCELERATED) {
+ UMA_HISTOGRAM_ENUMERATION(kProcessLifetimeEventsHardwareAccelerated,
+ LAUNCHED, GPU_PROCESS_LIFETIME_EVENT_MAX);
+ } else if (mode_ == gpu::GpuMode::SWIFTSHADER) {
+ UMA_HISTOGRAM_ENUMERATION(kProcessLifetimeEventsSwiftShader, LAUNCHED,
+ GPU_PROCESS_LIFETIME_EVENT_MAX);
+ } else if (mode_ == gpu::GpuMode::DISPLAY_COMPOSITOR) {
+ UMA_HISTOGRAM_ENUMERATION(kProcessLifetimeEventsDisplayCompositor,
+ LAUNCHED, GPU_PROCESS_LIFETIME_EVENT_MAX);
+ }
+ }
+
return true;
}
@@ -1384,89 +1501,85 @@ void GpuProcessHost::BlockLiveOffscreenContexts() {
}
void GpuProcessHost::RecordProcessCrash() {
-#if !defined(OS_ANDROID)
- // Maximum number of times the GPU process is allowed to crash in a session.
- // Once this limit is reached, any request to launch the GPU process will
- // fail.
- const int kGpuMaxCrashCount = 3;
+#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+ // Maximum number of times the GPU process can crash before we try something
+ // different, like disabling hardware acceleration or all GL.
+ constexpr int kGpuFallbackCrashCount = 3;
#else
- // On android there is no way to recover without gpu, and the OS can kill the
- // gpu process arbitrarily, so use a higher count to allow for that.
- const int kGpuMaxCrashCount = 6;
+ // Android and Chrome OS switch to software compositing and fallback crashes
+ // the browser process. For Android the OS can also kill the GPU process
+ // arbitrarily. Use a larger maximum crash count here.
+ constexpr int kGpuFallbackCrashCount = 6;
#endif
- bool disable_crash_limit = base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableGpuProcessCrashLimit);
-
// Ending only acts as a failure if the GPU process was actually started and
// was intended for actual rendering (and not just checking caps or other
// options).
- if (process_launched_ && kind_ == GPU_PROCESS_KIND_SANDBOXED) {
- if (GpuDataManagerImpl::GetInstance()->HardwareAccelerationEnabled()) {
- int count = static_cast<int>(
- base::subtle::NoBarrier_AtomicIncrement(&gpu_crash_count_, 1));
- UMA_HISTOGRAM_EXACT_LINEAR(
- "GPU.GPUProcessLifetimeEvents",
- std::min(DIED_FIRST_TIME + count, GPU_PROCESS_LIFETIME_EVENT_MAX - 1),
- static_cast<int>(GPU_PROCESS_LIFETIME_EVENT_MAX));
-
- IncrementCrashCount(&gpu_recent_crash_count_);
- if ((gpu_recent_crash_count_ >= kGpuMaxCrashCount ||
- status_ == FAILURE) &&
- !disable_crash_limit) {
-#if defined(OS_ANDROID)
- // Android can not fall back to software. If things are too unstable
- // then we just crash chrome to reset everything. Sorry.
- LOG(FATAL) << "Unable to start gpu process, giving up.";
-#elif defined(OS_CHROMEOS)
- // ChromeOS also can not fall back to software. There we will just
- // keep retrying to make the gpu process forever. Good luck.
- DLOG(ERROR) << "Gpu process is unstable and crashing repeatedly, if "
- "you didn't notice already.";
-#else
- // The GPU process is too unstable to use. Disable it for current
- // session.
- GpuDataManagerImpl::GetInstance()->DisableHardwareAcceleration();
-#endif
- }
- } else if (GpuDataManagerImpl::GetInstance()->SwiftShaderAllowed()) {
- UMA_HISTOGRAM_EXACT_LINEAR(
- "GPU.SwiftShaderLifetimeEvents",
- DIED_FIRST_TIME + swiftshader_crash_count_,
- static_cast<int>(GPU_PROCESS_LIFETIME_EVENT_MAX));
- ++swiftshader_crash_count_;
-
- IncrementCrashCount(&swiftshader_recent_crash_count_);
- if (swiftshader_recent_crash_count_ >= kGpuMaxCrashCount &&
- !disable_crash_limit) {
- // SwiftShader is too unstable to use. Disable it for current session.
- GpuDataManagerImpl::GetInstance()->BlockSwiftShader();
- }
- } else {
- UMA_HISTOGRAM_EXACT_LINEAR(
- "GPU.DisplayCompositorLifetimeEvents",
- DIED_FIRST_TIME + display_compositor_crash_count_,
- static_cast<int>(GPU_PROCESS_LIFETIME_EVENT_MAX));
- ++display_compositor_crash_count_;
-
- IncrementCrashCount(&display_compositor_recent_crash_count_);
- if (display_compositor_recent_crash_count_ >= kGpuMaxCrashCount &&
- !disable_crash_limit) {
- // Viz display compositor is too unstable. Crash chrome to reset
- // everything.
- LOG(FATAL) << "Unable to start viz process, giving up.";
- }
- }
+ if (!process_launched_ || kind_ != GPU_PROCESS_KIND_SANDBOXED)
+ return;
+
+ // Keep track of the total number of GPU crashes.
+ base::subtle::NoBarrier_AtomicIncrement(&gpu_crash_count_, 1);
+
+ int recent_crash_count = 0;
+ if (mode_ == gpu::GpuMode::HARDWARE_ACCELERATED) {
+ IncrementCrashCount(kForgiveGpuCrashMinutes,
+ &hardware_accelerated_recent_crash_count_);
+ UMA_HISTOGRAM_EXACT_LINEAR(
+ kProcessLifetimeEventsHardwareAccelerated,
+ DIED_FIRST_TIME + hardware_accelerated_recent_crash_count_ - 1,
+ static_cast<int>(GPU_PROCESS_LIFETIME_EVENT_MAX));
+ recent_crash_count = hardware_accelerated_recent_crash_count_;
+ } else if (mode_ == gpu::GpuMode::SWIFTSHADER) {
+ IncrementCrashCount(kForgiveGpuCrashMinutes,
+ &swiftshader_recent_crash_count_);
+ UMA_HISTOGRAM_EXACT_LINEAR(
+ kProcessLifetimeEventsSwiftShader,
+ DIED_FIRST_TIME + swiftshader_recent_crash_count_ - 1,
+ static_cast<int>(GPU_PROCESS_LIFETIME_EVENT_MAX));
+ recent_crash_count = swiftshader_recent_crash_count_;
+ } else if (mode_ == gpu::GpuMode::DISPLAY_COMPOSITOR) {
+ IncrementCrashCount(kForgiveDisplayCompositorCrashMinutes,
+ &display_compositor_recent_crash_count_);
+ UMA_HISTOGRAM_EXACT_LINEAR(
+ kProcessLifetimeEventsDisplayCompositor,
+ DIED_FIRST_TIME + display_compositor_recent_crash_count_ - 1,
+ static_cast<int>(GPU_PROCESS_LIFETIME_EVENT_MAX));
+ recent_crash_count = display_compositor_recent_crash_count_;
}
+
+ // TODO(crbug.com/849639): Ensure crash counts are included in crash
+ // minidumps. This is for debugging and should be removed when bug is closed.
+ int hardware_accelerated_crash_count =
+ hardware_accelerated_recent_crash_count_;
+ base::debug::Alias(&hardware_accelerated_crash_count);
+ int swiftshader_crash_count = swiftshader_recent_crash_count_;
+ base::debug::Alias(&swiftshader_crash_count);
+ int display_compositor_crash_count = display_compositor_recent_crash_count_;
+ base::debug::Alias(&display_compositor_crash_count);
+
+ // GPU process initialization failed and fallback already happened.
+ if (status_ == FAILURE)
+ return;
+
+ bool disable_crash_limit = base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableGpuProcessCrashLimit);
+
+ // GPU process crashed too many times, fallback on a different GPU process
+ // mode.
+ if (recent_crash_count >= kGpuFallbackCrashCount && !disable_crash_limit)
+ GpuDataManagerImpl::GetInstance()->FallBackToNextGpuMode();
}
std::string GpuProcessHost::GetShaderPrefixKey() {
if (shader_prefix_key_.empty()) {
- gpu::GPUInfo info = GpuDataManagerImpl::GetInstance()->GetGPUInfo();
+ const gpu::GPUInfo info = GpuDataManagerImpl::GetInstance()->GetGPUInfo();
+ const gpu::GPUInfo::GPUDevice& active_gpu = info.active_gpu();
shader_prefix_key_ = GetContentClient()->GetProduct() + "-" +
info.gl_vendor + "-" + info.gl_renderer + "-" +
- info.driver_version + "-" + info.driver_vendor;
+ active_gpu.driver_version + "-" +
+ active_gpu.driver_vendor;
#if defined(OS_ANDROID)
std::string build_fp =
@@ -1511,4 +1624,8 @@ void GpuProcessHost::CreateChannelCache(int32_t client_id) {
client_id_to_shader_cache_[client_id] = cache;
}
+int GpuProcessHost::GetIDForTesting() const {
+ return process_->GetData().id;
+}
+
} // namespace content
diff --git a/chromium/content/browser/gpu/gpu_process_host.h b/chromium/content/browser/gpu/gpu_process_host.h
index e08bcf72fc1..3ca9cf5c561 100644
--- a/chromium/content/browser/gpu/gpu_process_host.h
+++ b/chromium/content/browser/gpu/gpu_process_host.h
@@ -28,6 +28,7 @@
#include "gpu/command_buffer/common/constants.h"
#include "gpu/config/gpu_feature_info.h"
#include "gpu/config/gpu_info.h"
+#include "gpu/config/gpu_mode.h"
#include "gpu/ipc/common/surface_handle.h"
#include "ipc/ipc_sender.h"
#include "mojo/public/cpp/bindings/binding.h"
@@ -43,6 +44,10 @@ namespace base {
class Thread;
}
+namespace gfx {
+struct FontRenderParams;
+}
+
namespace gpu {
class ShaderDiskCache;
struct SyncToken;
@@ -51,6 +56,10 @@ struct SyncToken;
namespace content {
class BrowserChildProcessHostImpl;
+#if defined(OS_MACOSX)
+class CATransactionGPUCoordinator;
+#endif
+
class GpuProcessHost : public BrowserChildProcessHostDelegate,
public IPC::Sender,
public viz::mojom::GpuHost {
@@ -80,7 +89,7 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
SUCCESS,
};
using CreateGpuMemoryBufferCallback =
- base::OnceCallback<void(const gfx::GpuMemoryBufferHandle& handle,
+ base::OnceCallback<void(gfx::GpuMemoryBufferHandle handle,
BufferCreationStatus status)>;
using RequestGPUInfoCallback = base::Callback<void(const gpu::GPUInfo&)>;
@@ -110,6 +119,8 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
bool force_create,
const base::Callback<void(GpuProcessHost*)>& callback);
+ static void InitFontRenderParamsOnIO(const gfx::FontRenderParams& params);
+
void BindInterface(const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe);
@@ -155,12 +166,6 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
void RequestGPUInfo(RequestGPUInfoCallback request_cb);
void RequestHDRStatus(RequestHDRStatusCallback request_cb);
-#if defined(OS_ANDROID)
- // Tells the GPU process that the given surface is being destroyed so that it
- // can stop using it.
- void SendDestroyingVideoSurface(int surface_id, const base::Closure& done_cb);
-#endif
-
// What kind of GPU process, e.g. sandboxed or unsandboxed.
GpuProcessKind kind();
@@ -175,6 +180,8 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
return wake_up_gpu_before_drawing_;
}
+ CONTENT_EXPORT int GetIDForTesting() const;
+
private:
class ConnectionFilterImpl;
@@ -182,9 +189,10 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
static bool ValidateHost(GpuProcessHost* host);
- // Increments the given crash count. Also, for each hour passed since the
- // previous crash, removes an old crash from the count.
- static void IncrementCrashCount(int* crash_count);
+ // Increments |crash_count| by one. Before incrementing |crash_count|, for
+ // each |forgive_minutes| that has passed since the previous crash remove one
+ // old crash.
+ static void IncrementCrashCount(int forgive_minutes, int* crash_count);
GpuProcessHost(int host_id, GpuProcessKind kind);
~GpuProcessHost() override;
@@ -217,6 +225,7 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
void DidLoseContext(bool offscreen,
gpu::error::ContextLostReason reason,
const GURL& active_url) override;
+ void DisableGpuCompositing() override;
void SetChildSurface(gpu::SurfaceHandle parent,
gpu::SurfaceHandle child) override;
void StoreShaderToDisk(int32_t client_id,
@@ -229,7 +238,7 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
void OnChannelEstablished(int client_id,
const EstablishChannelCallback& callback,
mojo::ScopedMessagePipeHandle channel_handle);
- void OnGpuMemoryBufferCreated(const gfx::GpuMemoryBufferHandle& handle);
+ void OnGpuMemoryBufferCreated(gfx::GpuMemoryBufferHandle handle);
// Message handlers.
#if defined(OS_ANDROID)
@@ -279,6 +288,8 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
GpuProcessKind kind_;
+ gpu::GpuMode mode_ = gpu::GpuMode::UNKNOWN;
+
// Whether we actually launched a GPU process.
bool process_launched_;
@@ -287,12 +298,11 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
// Time Init started. Used to log total GPU process startup time to UMA.
base::TimeTicks init_start_time_;
+ // The total number of GPU process crashes.
static base::subtle::Atomic32 gpu_crash_count_;
- static int gpu_recent_crash_count_;
static bool crashed_before_;
- static int swiftshader_crash_count_;
+ static int hardware_accelerated_recent_crash_count_;
static int swiftshader_recent_crash_count_;
- static int display_compositor_crash_count_;
static int display_compositor_recent_crash_count_;
// Here the bottom-up destruction order matters:
@@ -302,6 +312,10 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
std::unique_ptr<BrowserChildProcessHostImpl> process_;
std::unique_ptr<base::Thread> in_process_gpu_thread_;
+#if defined(OS_MACOSX)
+ scoped_refptr<CATransactionGPUCoordinator> ca_transaction_gpu_coordinator_;
+#endif
+
// Track the URLs of the pages which have live offscreen contexts,
// assumed to be associated with untrusted content such as WebGL.
// For best robustness, when any context lost notification is