Commit e23f7526 authored by Zhenyao Mo's avatar Zhenyao Mo Committed by Commit Bot

Always collect GPUInfo on Android in GPU process/thread.

BUG=744658
TEST=bots
R=piman@chromium.org,boliu@chromium.org

Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel
Change-Id: Icb4f88dbbdca34541d3921b57574a9d843326254
Reviewed-on: https://chromium-review.googlesource.com/905791Reviewed-by: default avatarBo <boliu@chromium.org>
Reviewed-by: default avatarAntoine Labour <piman@chromium.org>
Commit-Queue: Zhenyao Mo <zmo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#534881}
parent 2b2a6047
......@@ -7,12 +7,8 @@
namespace android_webview {
AwContentGpuClient::AwContentGpuClient(
const GetSyncPointManagerCallback& sync_point_manager_callback,
const GetGPUInfoCallback gpu_info_callback,
const GetGpuFeatureInfoCallback gpu_feature_info_callback)
: sync_point_manager_callback_(sync_point_manager_callback),
gpu_info_callback_(gpu_info_callback),
gpu_feature_info_callback_(gpu_feature_info_callback) {}
const GetSyncPointManagerCallback& sync_point_manager_callback)
: sync_point_manager_callback_(sync_point_manager_callback) {}
AwContentGpuClient::~AwContentGpuClient() {}
......@@ -20,12 +16,4 @@ gpu::SyncPointManager* AwContentGpuClient::GetSyncPointManager() {
return sync_point_manager_callback_.Run();
}
const gpu::GPUInfo* AwContentGpuClient::GetGPUInfo() {
return &(gpu_info_callback_.Run());
}
const gpu::GpuFeatureInfo* AwContentGpuClient::GetGpuFeatureInfo() {
return &(gpu_feature_info_callback_.Run());
}
} // namespace android_webview
......@@ -14,25 +14,16 @@ namespace android_webview {
class AwContentGpuClient : public content::ContentGpuClient {
public:
using GetSyncPointManagerCallback = base::Callback<gpu::SyncPointManager*()>;
using GetGPUInfoCallback = base::Callback<const gpu::GPUInfo&()>;
using GetGpuFeatureInfoCallback =
base::Callback<const gpu::GpuFeatureInfo&()>;
explicit AwContentGpuClient(
const GetSyncPointManagerCallback& sync_point_manager_callback,
const GetGPUInfoCallback gpu_info_callback,
const GetGpuFeatureInfoCallback gpu_feature_info_callback);
const GetSyncPointManagerCallback& sync_point_manager_callback);
~AwContentGpuClient() override;
// content::ContentGpuClient implementation.
gpu::SyncPointManager* GetSyncPointManager() override;
const gpu::GPUInfo* GetGPUInfo() override;
const gpu::GpuFeatureInfo* GetGpuFeatureInfo() override;
private:
GetSyncPointManagerCallback sync_point_manager_callback_;
GetGPUInfoCallback gpu_info_callback_;
GetGpuFeatureInfoCallback gpu_feature_info_callback_;
DISALLOW_COPY_AND_ASSIGN(AwContentGpuClient);
};
......
......@@ -268,22 +268,11 @@ gpu::SyncPointManager* GetSyncPointManager() {
DCHECK(DeferredGpuCommandService::GetInstance());
return DeferredGpuCommandService::GetInstance()->sync_point_manager();
}
const gpu::GPUInfo& GetGPUInfo() {
DCHECK(DeferredGpuCommandService::GetInstance());
return DeferredGpuCommandService::GetInstance()->gpu_info();
}
const gpu::GpuFeatureInfo& GetGpuFeatureInfo() {
DCHECK(DeferredGpuCommandService::GetInstance());
return DeferredGpuCommandService::GetInstance()->gpu_feature_info();
}
} // namespace
content::ContentGpuClient* AwMainDelegate::CreateContentGpuClient() {
content_gpu_client_.reset(new AwContentGpuClient(
base::Bind(&GetSyncPointManager), base::Bind(&GetGPUInfo),
base::Bind(&GetGpuFeatureInfo)));
content_gpu_client_.reset(
new AwContentGpuClient(base::Bind(&GetSyncPointManager)));
return content_gpu_client_.get();
}
......
......@@ -299,7 +299,6 @@ int GpuMain(const MainFunctionParams& parameters) {
gpu_init->set_sandbox_helper(&sandbox_helper);
auto* client = GetContentClient()->gpu();
// Gpu initialization may fail for various reasons, in which case we will need
// to tear down this process. However, we can not do so safely until the IPC
// channel is set up, because the detection of early return of a child process
......@@ -309,9 +308,7 @@ int GpuMain(const MainFunctionParams& parameters) {
// defer tearing down the GPU process until receiving the initialization
// message from the browser (through mojom::VizMain::CreateGpuService()).
const bool init_success = gpu_init->InitializeAndStartSandbox(
const_cast<base::CommandLine*>(&command_line), gpu_preferences,
client ? client->GetGPUInfo() : nullptr,
client ? client->GetGpuFeatureInfo() : nullptr);
const_cast<base::CommandLine*>(&command_line), gpu_preferences);
const bool dead_on_arrival = !init_success;
logging::SetLogMessageHandler(nullptr);
......@@ -324,6 +321,7 @@ int GpuMain(const MainFunctionParams& parameters) {
GpuProcess gpu_process(io_thread_priority);
auto* client = GetContentClient()->gpu();
if (client)
client->PostIOThreadCreated(gpu_process.io_task_runner());
......
......@@ -11,21 +11,13 @@
#include "content/gpu/gpu_process.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "content/public/gpu/content_gpu_client.h"
#include "gpu/command_buffer/service/gpu_preferences.h"
#include "gpu/config/gpu_info_collector.h"
#include "gpu/config/gpu_util.h"
#include "gpu/ipc/service/gpu_init.h"
#include "ui/gl/init/gl_factory.h"
#if defined(OS_ANDROID)
#include "base/android/jni_android.h"
#endif
#if defined(USE_OZONE)
#include "ui/ozone/public/ozone_platform.h"
#endif
namespace content {
InProcessGpuThread::InProcessGpuThread(
......@@ -56,11 +48,8 @@ void InProcessGpuThread::Init() {
gpu_process_ = new GpuProcess(io_thread_priority);
auto gpu_init = std::make_unique<gpu::GpuInit>();
auto* client = GetContentClient()->gpu();
gpu_init->InitializeInProcess(base::CommandLine::ForCurrentProcess(),
gpu_preferences_,
client ? client->GetGPUInfo() : nullptr,
client ? client->GetGpuFeatureInfo() : nullptr);
gpu_preferences_);
GetContentClient()->SetGpuInfo(gpu_init->gpu_info());
......
......@@ -87,8 +87,9 @@ void ContentTestSuite::Initialize() {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
bool is_child_process = command_line->HasSwitch(switches::kTestChildProcess);
if (!is_child_process) {
gl::GLSurfaceTestSupport::InitializeNoExtensionsOneOff();
gpu::GPUInfo gpu_info;
gpu::CollectBasicGraphicsInfo(&gpu_info);
gpu::CollectGraphicsInfoForTesting(&gpu_info);
gpu::GpuFeatureInfo gpu_feature_info =
gpu::ComputeGpuFeatureInfo(gpu_info,
false, // ignore_gpu_blacklist
......@@ -97,7 +98,6 @@ void ContentTestSuite::Initialize() {
command_line, nullptr);
gpu::InProcessCommandBuffer::InitializeDefaultServiceForTesting(
gpu_feature_info);
gl::GLSurfaceTestSupport::InitializeNoExtensionsOneOff();
gl::init::SetDisabledExtensionsPlatform(
gpu_feature_info.disabled_extensions);
gl::init::InitializeExtensionSettingsOneOffPlatform();
......
......@@ -29,15 +29,15 @@ int RunHelper(base::TestSuite* testSuite) {
base::MessageLoopForIO message_loop;
#endif
base::FeatureList::InitializeInstance(std::string(), std::string());
gl::init::InitializeGLNoExtensionsOneOff();
gpu::GPUInfo gpu_info;
gpu::CollectBasicGraphicsInfo(&gpu_info);
gpu::CollectGraphicsInfoForTesting(&gpu_info);
gpu::GLManager::g_gpu_feature_info = gpu::ComputeGpuFeatureInfo(
gpu_info,
false, // ignore_gpu_blacklist
false, // disable_gpu_driver_bug_workarounds
false, // log_gpu_control_list_decisions
base::CommandLine::ForCurrentProcess(), nullptr);
gl::init::InitializeGLNoExtensionsOneOff();
gl::init::SetDisabledExtensionsPlatform(
gpu::GLManager::g_gpu_feature_info.disabled_extensions);
gl::init::InitializeExtensionSettingsOneOffPlatform();
......
......@@ -334,4 +334,13 @@ void FillGPUInfoFromSystemInfo(GPUInfo* gpu_info,
gpu_info->machine_model_version = system_info->machineModelVersion;
}
void CollectGraphicsInfoForTesting(GPUInfo* gpu_info) {
DCHECK(gpu_info);
#if defined(OS_ANDROID)
CollectContextGraphicsInfo(gpu_info);
#else
CollectBasicGraphicsInfo(gpu_info);
#endif // OS_ANDROID
}
} // namespace gpu
......@@ -57,6 +57,10 @@ GPU_EXPORT void IdentifyActiveGPU(GPUInfo* gpu_info);
void FillGPUInfoFromSystemInfo(GPUInfo* gpu_info,
angle::SystemInfo* system_info);
// On Android, this calls CollectContextGraphicsInfo().
// On other platforms, this calls CollectBasicGraphicsInfo().
GPU_EXPORT void CollectGraphicsInfoForTesting(GPUInfo* gpu_info);
} // namespace gpu
#endif // GPU_CONFIG_GPU_INFO_COLLECTOR_H_
......@@ -9,6 +9,7 @@
#include "base/logging.h"
#include "base/sys_info.h"
#include "build/build_config.h"
#include "gpu/config/gpu_info.h"
#include "gpu/config/gpu_info_collector.h"
#include "gpu/config/gpu_test_expectations_parser.h"
......@@ -244,7 +245,11 @@ bool GPUTestBotConfig::Matches(const std::string& config_data) const {
bool GPUTestBotConfig::LoadCurrentConfig(const GPUInfo* gpu_info) {
bool rt;
if (gpu_info == NULL) {
if (!gpu_info) {
#if defined(OS_ANDROID)
// TODO(zmo): Implement this.
rt = false;
#else
GPUInfo my_gpu_info;
CollectInfoResult result = CollectBasicGraphicsInfo(&my_gpu_info);
if (result != kCollectInfoSuccess) {
......@@ -253,6 +258,7 @@ bool GPUTestBotConfig::LoadCurrentConfig(const GPUInfo* gpu_info) {
} else {
rt = SetGPUInfo(my_gpu_info);
}
#endif // OS_ANDROID
} else {
rt = SetGPUInfo(*gpu_info);
}
......
......@@ -22,6 +22,12 @@
#include "ui/gl/extension_set.h"
#include "ui/gl/gl_switches.h"
#if defined(OS_ANDROID)
#include "base/no_destructor.h"
#include "base/synchronization/lock.h"
#include "ui/gl/init/gl_factory.h"
#endif // OS_ANDROID
namespace gpu {
namespace {
......@@ -245,7 +251,8 @@ GpuFeatureInfo ComputeGpuFeatureInfo(const GPUInfo& gpu_info,
GpuFeatureInfo gpu_feature_info;
std::set<int> blacklisted_features;
if (!ignore_gpu_blacklist) {
if (!ignore_gpu_blacklist &&
!command_line->HasSwitch(switches::kUseGpuInTests)) {
std::unique_ptr<GpuBlacklist> list(GpuBlacklist::Create());
if (log_gpu_control_list_decisions)
list->EnableControlListLogging("gpu_blacklist");
......@@ -392,4 +399,48 @@ bool PopGpuFeatureInfoCache(GpuFeatureInfo* gpu_feature_info) {
return true;
}
#if defined(OS_ANDROID)
bool InitializeGLThreadSafe(base::CommandLine* command_line,
bool ignore_gpu_blacklist,
bool disable_gpu_driver_bug_workarounds,
bool log_gpu_control_list_decisions,
GPUInfo* out_gpu_info,
GpuFeatureInfo* out_gpu_feature_info) {
static base::NoDestructor<base::Lock> gl_bindings_initialization_lock;
base::AutoLock auto_lock(*gl_bindings_initialization_lock);
DCHECK(command_line);
DCHECK(out_gpu_info && out_gpu_feature_info);
bool gpu_info_cached = PopGPUInfoCache(out_gpu_info);
bool gpu_feature_info_cached = PopGpuFeatureInfoCache(out_gpu_feature_info);
DCHECK_EQ(gpu_info_cached, gpu_feature_info_cached);
if (gpu_info_cached) {
// GL bindings have already been initialized in another thread.
DCHECK_NE(gl::kGLImplementationNone, gl::GetGLImplementation());
return true;
}
if (gl::GetGLImplementation() == gl::kGLImplementationNone) {
// Some tests initialize bindings by themselves.
if (!gl::init::InitializeGLNoExtensionsOneOff()) {
VLOG(1) << "gl::init::InitializeGLNoExtensionsOneOff failed";
return false;
}
}
CollectContextGraphicsInfo(out_gpu_info);
*out_gpu_feature_info = ComputeGpuFeatureInfo(
*out_gpu_info, ignore_gpu_blacklist, disable_gpu_driver_bug_workarounds,
log_gpu_control_list_decisions, command_line, nullptr);
if (!out_gpu_feature_info->disabled_extensions.empty()) {
gl::init::SetDisabledExtensionsPlatform(
out_gpu_feature_info->disabled_extensions);
}
if (!gl::init::InitializeExtensionSettingsOneOffPlatform()) {
VLOG(1) << "gl::init::InitializeExtensionSettingsOneOffPlatform failed";
return false;
}
CacheGPUInfo(*out_gpu_info);
CacheGpuFeatureInfo(*out_gpu_feature_info);
return true;
}
#endif // OS_ANDROID
} // namespace gpu
......@@ -52,6 +52,19 @@ GPU_EXPORT void CacheGpuFeatureInfo(const GpuFeatureInfo& gpu_feature_info);
// return true; otherwise, return false;
GPU_EXPORT bool PopGpuFeatureInfoCache(GpuFeatureInfo* gpu_feature_info);
#if defined(OS_ANDROID)
// Check if GL bindings are initialized. If not, initializes GL
// bindings, create a GL context, collects GPUInfo, make blacklist and
// GPU driver bug workaround decisions. This is intended to be called
// by Android WebView render thread and in-process GPU thread.
GPU_EXPORT bool InitializeGLThreadSafe(base::CommandLine* command_line,
bool ignore_gpu_blacklist,
bool disable_gpu_driver_bug_workarounds,
bool log_gpu_control_list_decisions,
GPUInfo* out_gpu_info,
GpuFeatureInfo* out_gpu_feature_info);
#endif // OS_ANDROID
} // namespace gpu
#endif // GPU_CONFIG_GPU_UTIL_H_
......@@ -78,10 +78,11 @@ egl::ThreadState* ThreadState::Get() {
// Need to call both Init and InitFromArgv, since Windows does not use
// argc, argv in CommandLine::Init(argc, argv).
command_line->InitFromArgv(argv);
gl::init::InitializeGLNoExtensionsOneOff();
gpu::GpuFeatureInfo gpu_feature_info;
if (!command_line->HasSwitch(switches::kDisableGpuDriverBugWorkarounds)) {
gpu::GPUInfo gpu_info;
gpu::CollectBasicGraphicsInfo(&gpu_info);
gpu::CollectGraphicsInfoForTesting(&gpu_info);
gpu_feature_info = gpu::ComputeGpuFeatureInfo(
gpu_info,
false, // ignore_gpu_blacklist
......@@ -91,7 +92,6 @@ egl::ThreadState* ThreadState::Get() {
Context::SetPlatformGpuFeatureInfo(gpu_feature_info);
}
gl::init::InitializeGLNoExtensionsOneOff();
gl::init::SetDisabledExtensionsPlatform(
gpu_feature_info.disabled_extensions);
gl::init::InitializeExtensionSettingsOneOffPlatform();
......
......@@ -43,6 +43,9 @@ component("service") {
"switches.h",
]
defines = [ "GPU_IPC_SERVICE_IMPLEMENTATION" ]
if (is_chromecast) {
defines += [ "IS_CHROMECAST" ]
}
public_deps = [
"//base",
"//ipc",
......
......@@ -86,7 +86,7 @@ void CollectGraphicsInfo(GPUInfo* gpu_info) {
}
#endif // defined(OS_MACOSX)
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && !defined(IS_CHROMECAST)
bool CanAccessNvidiaDeviceFile() {
bool res = true;
base::AssertBlockingAllowed();
......@@ -96,7 +96,7 @@ bool CanAccessNvidiaDeviceFile() {
}
return res;
}
#endif // defined(OS_LINUX) && !defined(OS_CHROMEOS)
#endif // OS_LINUX && !OS_CHROMEOS && !IS_CHROMECAST
} // namespace
......@@ -106,20 +106,15 @@ GpuInit::~GpuInit() {
gpu::StopForceDiscreteGPU();
}
bool GpuInit::InitializeAndStartSandbox(
base::CommandLine* command_line,
const GpuPreferences& gpu_preferences,
const GPUInfo* gpu_info,
const GpuFeatureInfo* gpu_feature_info) {
bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line,
const GpuPreferences& gpu_preferences) {
gpu_preferences_ = gpu_preferences;
// Blacklist decisions based on basic GPUInfo may not be final. It might
// need more context based GPUInfo. In such situations, switching to
// SwiftShader needs to wait until creating a context.
bool needs_more_info = false;
#if !defined(OS_ANDROID)
if (gpu_info) {
gpu_info_ = *gpu_info;
} else if (!PopGPUInfoCache(&gpu_info_)) {
#if !defined(OS_ANDROID) && !defined(IS_CHROMECAST)
if (!PopGPUInfoCache(&gpu_info_)) {
CollectBasicGraphicsInfo(command_line, &gpu_info_);
}
......@@ -132,9 +127,7 @@ bool GpuInit::InitializeAndStartSandbox(
gpu_info_.driver_vendor == "NVIDIA" && !CanAccessNvidiaDeviceFile())
return false;
#endif
if (gpu_feature_info) {
gpu_feature_info_ = *gpu_feature_info;
} else if (!PopGpuFeatureInfoCache(&gpu_feature_info_)) {
if (!PopGpuFeatureInfoCache(&gpu_feature_info_)) {
// Compute blacklist and driver bug workaround decisions based on basic GPU
// info.
gpu_feature_info_ = gpu::ComputeGpuFeatureInfo(
......@@ -147,7 +140,7 @@ bool GpuInit::InitializeAndStartSandbox(
gpu::InitializeSwitchableGPUs(
gpu_feature_info_.enabled_gpu_driver_bug_workarounds);
}
#endif // OS_ANDROID
#endif // !OS_ANDROID && !IS_CHROMECAST
gpu_info_.in_process_gpu = false;
bool enable_watchdog = !gpu_preferences.disable_gpu_watchdog &&
......@@ -317,10 +310,21 @@ bool GpuInit::InitializeAndStartSandbox(
return true;
}
#if defined(OS_ANDROID)
void GpuInit::InitializeInProcess(base::CommandLine* command_line,
const GpuPreferences& gpu_preferences,
const GPUInfo* gpu_info,
const GpuFeatureInfo* gpu_feature_info) {
const GpuPreferences& gpu_preferences) {
gpu_preferences_ = gpu_preferences;
init_successful_ = true;
DCHECK(!ShouldEnableSwiftShader(command_line, false));
InitializeGLThreadSafe(command_line, gpu_preferences.ignore_gpu_blacklist,
gpu_preferences.disable_gpu_driver_bug_workarounds,
gpu_preferences.log_gpu_control_list_decisions,
&gpu_info_, &gpu_feature_info_);
}
#else
void GpuInit::InitializeInProcess(base::CommandLine* command_line,
const GpuPreferences& gpu_preferences) {
gpu_preferences_ = gpu_preferences;
init_successful_ = true;
#if defined(USE_OZONE)
......@@ -331,34 +335,23 @@ void GpuInit::InitializeInProcess(base::CommandLine* command_line,
ui::OzonePlatform::InitializeForGPU(params);
ui::OzonePlatform::GetInstance()->AfterSandboxEntry();
#endif
if (gpu_info) {
gpu_info_ = *gpu_info;
} else {
#if !defined(OS_ANDROID)
if (!PopGPUInfoCache(&gpu_info_)) {
CollectBasicGraphicsInfo(command_line, &gpu_info_);
}
#endif
}
bool needs_more_info = false;
if (gpu_feature_info) {
gpu_feature_info_ = *gpu_feature_info;
} else {
#if !defined(OS_ANDROID)
if (!PopGpuFeatureInfoCache(&gpu_feature_info_)) {
gpu_feature_info_ = ComputeGpuFeatureInfo(
gpu_info_, gpu_preferences.ignore_gpu_blacklist,
gpu_preferences.disable_gpu_driver_bug_workarounds,
gpu_preferences.log_gpu_control_list_decisions, command_line,
&needs_more_info);
}
#endif
#if !defined(IS_CHROMECAST)
if (!PopGPUInfoCache(&gpu_info_)) {
CollectBasicGraphicsInfo(command_line, &gpu_info_);
}
if (!PopGpuFeatureInfoCache(&gpu_feature_info_)) {
gpu_feature_info_ = ComputeGpuFeatureInfo(
gpu_info_, gpu_preferences.ignore_gpu_blacklist,
gpu_preferences.disable_gpu_driver_bug_workarounds,
gpu_preferences.log_gpu_control_list_decisions, command_line,
&needs_more_info);
}
if (SwitchableGPUsSupported(gpu_info_, *command_line)) {
InitializeSwitchableGPUs(
gpu_feature_info_.enabled_gpu_driver_bug_workarounds);
}
#endif // !IS_CHROMECAST
bool use_swiftshader = ShouldEnableSwiftShader(command_line, needs_more_info);
if (!gl::init::InitializeGLNoExtensionsOneOff()) {
......@@ -393,6 +386,7 @@ void GpuInit::InitializeInProcess(base::CommandLine* command_line,
VLOG(1) << "gl::init::InitializeExtensionSettingsOneOffPlatform failed";
}
}
#endif // OS_ANDROID
bool GpuInit::ShouldEnableSwiftShader(base::CommandLine* command_line,
bool blacklist_needs_more_info) {
......
......@@ -41,17 +41,10 @@ class GPU_IPC_SERVICE_EXPORT GpuInit {
// TODO(zmo): Get rid of |command_line| in the following two functions.
// Pass all bits through GpuPreferences.
// Mostly we collect GPUInfo and compute GpuFeatureInfo inside this function,
// but on certain platforms (Chromecast, MacOSX) they might be computed
// somewhere else.
bool InitializeAndStartSandbox(base::CommandLine* command_line,
const GpuPreferences& gpu_preferences,
const GPUInfo* gpu_info,
const GpuFeatureInfo* gpu_feature_info);
const GpuPreferences& gpu_preferences);
void InitializeInProcess(base::CommandLine* command_line,
const GpuPreferences& gpu_preferences,
const GPUInfo* gpu_info = nullptr,
const GpuFeatureInfo* gpu_feature_info = nullptr);
const GpuPreferences& gpu_preferences);
const GPUInfo& gpu_info() const { return gpu_info_; }
const GpuFeatureInfo& gpu_feature_info() const { return gpu_feature_info_; }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment