Commit 7439d046 authored by boliu's avatar boliu Committed by Commit bot

Make in-process gpu init thread safe

Initialize in-process gpu before threads are created.
In-process gpu init appends command line switches to the
global current process command line, which is only safe to
do before any background threads start and read the command
line.

BUG=450396

Review URL: https://codereview.chromium.org/879703003

Cr-Commit-Position: refs/heads/master@{#313387}
parent 103ae3cf
...@@ -394,8 +394,7 @@ void BrowserMainLoop::EarlyInitialization() { ...@@ -394,8 +394,7 @@ void BrowserMainLoop::EarlyInitialization() {
#endif #endif
#if defined(USE_X11) #if defined(USE_X11)
if (parsed_command_line_.HasSwitch(switches::kSingleProcess) || if (UsingInProcessGpu()) {
parsed_command_line_.HasSwitch(switches::kInProcessGPU)) {
if (!gfx::InitializeThreadedX11()) { if (!gfx::InitializeThreadedX11()) {
LOG(ERROR) << "Failed to put Xlib into threaded mode."; LOG(ERROR) << "Failed to put Xlib into threaded mode.";
} }
...@@ -617,6 +616,26 @@ int BrowserMainLoop::PreCreateThreads() { ...@@ -617,6 +616,26 @@ int BrowserMainLoop::PreCreateThreads() {
if (parsed_command_line_.HasSwitch(switches::kSingleProcess)) if (parsed_command_line_.HasSwitch(switches::kSingleProcess))
RenderProcessHost::SetRunRendererInProcess(true); RenderProcessHost::SetRunRendererInProcess(true);
#endif #endif
// Need to initialize in-process GpuDataManager before creating threads.
// It's unsafe to append the gpu command line switches to the global
// CommandLine::ForCurrentProcess object after threads are created.
if (UsingInProcessGpu()) {
bool initialize_gpu_data_manager = true;
#if defined(OS_ANDROID)
if (!gfx::GLSurface::InitializeOneOff()) {
// Single-process Android WebView supports no gpu.
LOG(ERROR) << "GLSurface::InitializeOneOff failed";
initialize_gpu_data_manager = false;
}
#endif
// Initialize the GpuDataManager before we set up the MessageLoops because
// otherwise we'll trigger the assertion about doing IO on the UI thread.
if (initialize_gpu_data_manager)
GpuDataManagerImpl::GetInstance()->Initialize();
}
return result_code_; return result_code_;
} }
...@@ -1012,6 +1031,12 @@ int BrowserMainLoop::BrowserThreadsStarted() { ...@@ -1012,6 +1031,12 @@ int BrowserMainLoop::BrowserThreadsStarted() {
indexed_db_thread_->Start(); indexed_db_thread_->Start();
#endif #endif
#if !defined(OS_IOS)
HistogramSynchronizer::GetInstance();
// GpuDataManager for in-process initialized in PreCreateThreads.
bool initialize_gpu_data_manager = !UsingInProcessGpu();
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
// Up the priority of anything that touches with display tasks // Up the priority of anything that touches with display tasks
// (this thread is UI thread, and io_thread_ is for IPCs). // (this thread is UI thread, and io_thread_ is for IPCs).
...@@ -1019,23 +1044,20 @@ int BrowserMainLoop::BrowserThreadsStarted() { ...@@ -1019,23 +1044,20 @@ int BrowserMainLoop::BrowserThreadsStarted() {
base::PlatformThread::SetThreadPriority( base::PlatformThread::SetThreadPriority(
base::PlatformThread::CurrentHandle(), base::PlatformThread::CurrentHandle(),
base::kThreadPriority_Display); base::kThreadPriority_Display);
#endif
#if !defined(OS_IOS) // On Android, GLSurface::InitializeOneOff() must be called before
HistogramSynchronizer::GetInstance(); // initalizing the GpuDataManagerImpl as it uses the GL bindings.
// TODO(sievers): Shouldn't need to init full bindings to determine GL
bool initialize_gpu_data_manager = true; // version/vendor strings. crbug.com/326295
#if defined(OS_ANDROID) if (initialize_gpu_data_manager) {
// On Android, GLSurface::InitializeOneOff() must be called before initalizing // Note InitializeOneOff is not safe either for in-process gpu after
// the GpuDataManagerImpl as it uses the GL bindings. crbug.com/326295 // creating threads, since it may race with the gpu thread.
if (!gfx::GLSurface::InitializeOneOff()) { if (!gfx::GLSurface::InitializeOneOff()) {
LOG(ERROR) << "GLSurface::InitializeOneOff failed"; LOG(FATAL) << "GLSurface::InitializeOneOff failed";
initialize_gpu_data_manager = false; }
} }
#endif #endif
// Initialize the GpuDataManager before we set up the MessageLoops because
// otherwise we'll trigger the assertion about doing IO on the UI thread.
if (initialize_gpu_data_manager) if (initialize_gpu_data_manager)
GpuDataManagerImpl::GetInstance()->Initialize(); GpuDataManagerImpl::GetInstance()->Initialize();
...@@ -1118,8 +1140,7 @@ int BrowserMainLoop::BrowserThreadsStarted() { ...@@ -1118,8 +1140,7 @@ int BrowserMainLoop::BrowserThreadsStarted() {
if (GpuDataManagerImpl::GetInstance()->GpuAccessAllowed(NULL) && if (GpuDataManagerImpl::GetInstance()->GpuAccessAllowed(NULL) &&
!established_gpu_channel && !established_gpu_channel &&
always_uses_gpu && always_uses_gpu &&
!parsed_command_line_.HasSwitch(switches::kSingleProcess) && !UsingInProcessGpu()) {
!parsed_command_line_.HasSwitch(switches::kInProcessGPU)) {
TRACE_EVENT_INSTANT0("gpu", "Post task to launch GPU process", TRACE_EVENT_INSTANT0("gpu", "Post task to launch GPU process",
TRACE_EVENT_SCOPE_THREAD); TRACE_EVENT_SCOPE_THREAD);
BrowserThread::PostTask( BrowserThread::PostTask(
...@@ -1144,6 +1165,11 @@ int BrowserMainLoop::BrowserThreadsStarted() { ...@@ -1144,6 +1165,11 @@ int BrowserMainLoop::BrowserThreadsStarted() {
return result_code_; return result_code_;
} }
bool BrowserMainLoop::UsingInProcessGpu() const {
return parsed_command_line_.HasSwitch(switches::kSingleProcess) ||
parsed_command_line_.HasSwitch(switches::kInProcessGPU);
}
bool BrowserMainLoop::InitializeToolkit() { bool BrowserMainLoop::InitializeToolkit() {
TRACE_EVENT0("startup", "BrowserMainLoop::InitializeToolkit"); TRACE_EVENT0("startup", "BrowserMainLoop::InitializeToolkit");
// TODO(evan): this function is rather subtle, due to the variety // TODO(evan): this function is rather subtle, due to the variety
......
...@@ -150,6 +150,9 @@ class CONTENT_EXPORT BrowserMainLoop { ...@@ -150,6 +150,9 @@ class CONTENT_EXPORT BrowserMainLoop {
void InitStartupTracing(const base::CommandLine& command_line); void InitStartupTracing(const base::CommandLine& command_line);
void EndStartupTracing(); void EndStartupTracing();
bool UsingInProcessGpu() const;
void InitializeGpuDataManager();
// Members initialized on construction --------------------------------------- // Members initialized on construction ---------------------------------------
const MainFunctionParams& parameters_; const MainFunctionParams& parameters_;
const base::CommandLine& parsed_command_line_; const base::CommandLine& parsed_command_line_;
......
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