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

Side by Side Diff: content/browser/browser_main_loop.cc

Issue 879703003: Make in-process gpu init thread safe (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: review3 Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/browser/browser_main_loop.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/browser_main_loop.h" 5 #include "content/browser/browser_main_loop.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 void BrowserMainLoop::EarlyInitialization() { 387 void BrowserMainLoop::EarlyInitialization() {
388 TRACE_EVENT0("startup", "BrowserMainLoop::EarlyInitialization"); 388 TRACE_EVENT0("startup", "BrowserMainLoop::EarlyInitialization");
389 389
390 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) 390 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
391 // No thread should be created before this call, as SetupSandbox() 391 // No thread should be created before this call, as SetupSandbox()
392 // will end-up using fork(). 392 // will end-up using fork().
393 SetupSandbox(parsed_command_line_); 393 SetupSandbox(parsed_command_line_);
394 #endif 394 #endif
395 395
396 #if defined(USE_X11) 396 #if defined(USE_X11)
397 if (parsed_command_line_.HasSwitch(switches::kSingleProcess) || 397 if (UsingInProcessGpu()) {
398 parsed_command_line_.HasSwitch(switches::kInProcessGPU)) {
399 if (!gfx::InitializeThreadedX11()) { 398 if (!gfx::InitializeThreadedX11()) {
400 LOG(ERROR) << "Failed to put Xlib into threaded mode."; 399 LOG(ERROR) << "Failed to put Xlib into threaded mode.";
401 } 400 }
402 } 401 }
403 #endif 402 #endif
404 403
405 // GLib's spawning of new processes is buggy, so it's important that at this 404 // GLib's spawning of new processes is buggy, so it's important that at this
406 // point GLib does not need to start DBUS. Chrome should always start with 405 // point GLib does not need to start DBUS. Chrome should always start with
407 // DBUS_SESSION_BUS_ADDRESS properly set. See crbug.com/309093. 406 // DBUS_SESSION_BUS_ADDRESS properly set. See crbug.com/309093.
408 #if defined(USE_GLIB) 407 #if defined(USE_GLIB)
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 PluginService::GetInstance()->Init(); 609 PluginService::GetInstance()->Init();
611 } 610 }
612 #endif 611 #endif
613 612
614 #if !defined(OS_IOS) && (!defined(GOOGLE_CHROME_BUILD) || defined(OS_ANDROID)) 613 #if !defined(OS_IOS) && (!defined(GOOGLE_CHROME_BUILD) || defined(OS_ANDROID))
615 // Single-process is an unsupported and not fully tested mode, so 614 // Single-process is an unsupported and not fully tested mode, so
616 // don't enable it for official Chrome builds (except on Android). 615 // don't enable it for official Chrome builds (except on Android).
617 if (parsed_command_line_.HasSwitch(switches::kSingleProcess)) 616 if (parsed_command_line_.HasSwitch(switches::kSingleProcess))
618 RenderProcessHost::SetRunRendererInProcess(true); 617 RenderProcessHost::SetRunRendererInProcess(true);
619 #endif 618 #endif
619
620 // Need to initialize in-process GpuDataManager before creating threads.
621 // It's unsafe to append the gpu command line switches to the global
622 // CommandLine::ForCurrentProcess object after threads are created.
623 if (UsingInProcessGpu()) {
624 bool initialize_gpu_data_manager = true;
625 #if defined(OS_ANDROID)
626 if (!gfx::GLSurface::InitializeOneOff()) {
627 // Single-process Android WebView supports no gpu.
628 LOG(ERROR) << "GLSurface::InitializeOneOff failed";
629 initialize_gpu_data_manager = false;
630 }
631 #endif
632
633 // Initialize the GpuDataManager before we set up the MessageLoops because
634 // otherwise we'll trigger the assertion about doing IO on the UI thread.
635 if (initialize_gpu_data_manager)
636 GpuDataManagerImpl::GetInstance()->Initialize();
637 }
638
620 return result_code_; 639 return result_code_;
621 } 640 }
622 641
623 void BrowserMainLoop::CreateStartupTasks() { 642 void BrowserMainLoop::CreateStartupTasks() {
624 TRACE_EVENT0("startup", "BrowserMainLoop::CreateStartupTasks"); 643 TRACE_EVENT0("startup", "BrowserMainLoop::CreateStartupTasks");
625 644
626 // First time through, we really want to create all the tasks 645 // First time through, we really want to create all the tasks
627 if (!startup_task_runner_.get()) { 646 if (!startup_task_runner_.get()) {
628 #if defined(OS_ANDROID) 647 #if defined(OS_ANDROID)
629 startup_task_runner_ = make_scoped_ptr(new StartupTaskRunner( 648 startup_task_runner_ = make_scoped_ptr(new StartupTaskRunner(
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
1005 } 1024 }
1006 1025
1007 int BrowserMainLoop::BrowserThreadsStarted() { 1026 int BrowserMainLoop::BrowserThreadsStarted() {
1008 TRACE_EVENT0("startup", "BrowserMainLoop::BrowserThreadsStarted"); 1027 TRACE_EVENT0("startup", "BrowserMainLoop::BrowserThreadsStarted");
1009 1028
1010 #if !defined(OS_IOS) 1029 #if !defined(OS_IOS)
1011 indexed_db_thread_.reset(new base::Thread("IndexedDB")); 1030 indexed_db_thread_.reset(new base::Thread("IndexedDB"));
1012 indexed_db_thread_->Start(); 1031 indexed_db_thread_->Start();
1013 #endif 1032 #endif
1014 1033
1034 #if !defined(OS_IOS)
1035 HistogramSynchronizer::GetInstance();
1036
1037
1038 // GpuDataManager for in-process initialized in PreCreateThreads.
1039 bool initialize_gpu_data_manager = !UsingInProcessGpu();
1015 #if defined(OS_ANDROID) 1040 #if defined(OS_ANDROID)
1016 // Up the priority of anything that touches with display tasks 1041 // Up the priority of anything that touches with display tasks
1017 // (this thread is UI thread, and io_thread_ is for IPCs). 1042 // (this thread is UI thread, and io_thread_ is for IPCs).
1018 io_thread_->SetPriority(base::kThreadPriority_Display); 1043 io_thread_->SetPriority(base::kThreadPriority_Display);
1019 base::PlatformThread::SetThreadPriority( 1044 base::PlatformThread::SetThreadPriority(
1020 base::PlatformThread::CurrentHandle(), 1045 base::PlatformThread::CurrentHandle(),
1021 base::kThreadPriority_Display); 1046 base::kThreadPriority_Display);
1022 #endif
1023 1047
1024 #if !defined(OS_IOS) 1048 // On Android, GLSurface::InitializeOneOff() must be called before
1025 HistogramSynchronizer::GetInstance(); 1049 // initalizing the GpuDataManagerImpl as it uses the GL bindings.
1026 1050 // TODO(sievers): Shouldn't need to init full bindings to determine GL
1027 bool initialize_gpu_data_manager = true; 1051 // version/vendor strings. crbug.com/326295
1028 #if defined(OS_ANDROID) 1052 if (initialize_gpu_data_manager) {
1029 // On Android, GLSurface::InitializeOneOff() must be called before initalizing 1053 // Note InitializeOneOff is not safe either for in-process gpu after
1030 // the GpuDataManagerImpl as it uses the GL bindings. crbug.com/326295 1054 // creating threads, since it may race with the gpu thread.
1031 if (!gfx::GLSurface::InitializeOneOff()) { 1055 if (!gfx::GLSurface::InitializeOneOff()) {
1032 LOG(ERROR) << "GLSurface::InitializeOneOff failed"; 1056 LOG(FATAL) << "GLSurface::InitializeOneOff failed";
1033 initialize_gpu_data_manager = false; 1057 }
1034 } 1058 }
1035 #endif 1059 #endif
1036 1060
1037 // Initialize the GpuDataManager before we set up the MessageLoops because
1038 // otherwise we'll trigger the assertion about doing IO on the UI thread.
1039 if (initialize_gpu_data_manager) 1061 if (initialize_gpu_data_manager)
1040 GpuDataManagerImpl::GetInstance()->Initialize(); 1062 GpuDataManagerImpl::GetInstance()->Initialize();
1041 1063
1042 bool always_uses_gpu = true; 1064 bool always_uses_gpu = true;
1043 bool established_gpu_channel = false; 1065 bool established_gpu_channel = false;
1044 #if defined(USE_AURA) || defined(OS_MACOSX) 1066 #if defined(USE_AURA) || defined(OS_MACOSX)
1045 established_gpu_channel = true; 1067 established_gpu_channel = true;
1046 if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor()) { 1068 if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor()) {
1047 established_gpu_channel = always_uses_gpu = false; 1069 established_gpu_channel = always_uses_gpu = false;
1048 } 1070 }
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 allowed_clipboard_threads.push_back(io_thread_->thread_id()); 1133 allowed_clipboard_threads.push_back(io_thread_->thread_id());
1112 #endif 1134 #endif
1113 ui::Clipboard::SetAllowedThreads(allowed_clipboard_threads); 1135 ui::Clipboard::SetAllowedThreads(allowed_clipboard_threads);
1114 1136
1115 // When running the GPU thread in-process, avoid optimistically starting it 1137 // When running the GPU thread in-process, avoid optimistically starting it
1116 // since creating the GPU thread races against creation of the one-and-only 1138 // since creating the GPU thread races against creation of the one-and-only
1117 // ChildProcess instance which is created by the renderer thread. 1139 // ChildProcess instance which is created by the renderer thread.
1118 if (GpuDataManagerImpl::GetInstance()->GpuAccessAllowed(NULL) && 1140 if (GpuDataManagerImpl::GetInstance()->GpuAccessAllowed(NULL) &&
1119 !established_gpu_channel && 1141 !established_gpu_channel &&
1120 always_uses_gpu && 1142 always_uses_gpu &&
1121 !parsed_command_line_.HasSwitch(switches::kSingleProcess) && 1143 !UsingInProcessGpu()) {
1122 !parsed_command_line_.HasSwitch(switches::kInProcessGPU)) {
1123 TRACE_EVENT_INSTANT0("gpu", "Post task to launch GPU process", 1144 TRACE_EVENT_INSTANT0("gpu", "Post task to launch GPU process",
1124 TRACE_EVENT_SCOPE_THREAD); 1145 TRACE_EVENT_SCOPE_THREAD);
1125 BrowserThread::PostTask( 1146 BrowserThread::PostTask(
1126 BrowserThread::IO, FROM_HERE, base::Bind( 1147 BrowserThread::IO, FROM_HERE, base::Bind(
1127 base::IgnoreResult(&GpuProcessHost::Get), 1148 base::IgnoreResult(&GpuProcessHost::Get),
1128 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, 1149 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
1129 CAUSE_FOR_GPU_LAUNCH_BROWSER_STARTUP)); 1150 CAUSE_FOR_GPU_LAUNCH_BROWSER_STARTUP));
1130 } 1151 }
1131 1152
1132 #if defined(OS_MACOSX) 1153 #if defined(OS_MACOSX)
1133 ThemeHelperMac::GetInstance(); 1154 ThemeHelperMac::GetInstance();
1134 SystemHotkeyHelperMac::GetInstance()->DeferredLoadSystemHotkeys(); 1155 SystemHotkeyHelperMac::GetInstance()->DeferredLoadSystemHotkeys();
1135 if (ShouldEnableBootstrapSandbox()) { 1156 if (ShouldEnableBootstrapSandbox()) {
1136 TRACE_EVENT0("startup", 1157 TRACE_EVENT0("startup",
1137 "BrowserMainLoop::BrowserThreadsStarted:BootstrapSandbox"); 1158 "BrowserMainLoop::BrowserThreadsStarted:BootstrapSandbox");
1138 CHECK(GetBootstrapSandbox()); 1159 CHECK(GetBootstrapSandbox());
1139 } 1160 }
1140 #endif // defined(OS_MACOSX) 1161 #endif // defined(OS_MACOSX)
1141 1162
1142 #endif // !defined(OS_IOS) 1163 #endif // !defined(OS_IOS)
1143 1164
1144 return result_code_; 1165 return result_code_;
1145 } 1166 }
1146 1167
1168 bool BrowserMainLoop::UsingInProcessGpu() const {
1169 return parsed_command_line_.HasSwitch(switches::kSingleProcess) ||
1170 parsed_command_line_.HasSwitch(switches::kInProcessGPU);
1171 }
1172
1147 bool BrowserMainLoop::InitializeToolkit() { 1173 bool BrowserMainLoop::InitializeToolkit() {
1148 TRACE_EVENT0("startup", "BrowserMainLoop::InitializeToolkit"); 1174 TRACE_EVENT0("startup", "BrowserMainLoop::InitializeToolkit");
1149 // TODO(evan): this function is rather subtle, due to the variety 1175 // TODO(evan): this function is rather subtle, due to the variety
1150 // of intersecting ifdefs we have. To keep it easy to follow, there 1176 // of intersecting ifdefs we have. To keep it easy to follow, there
1151 // are no #else branches on any #ifs. 1177 // are no #else branches on any #ifs.
1152 // TODO(stevenjb): Move platform specific code into platform specific Parts 1178 // TODO(stevenjb): Move platform specific code into platform specific Parts
1153 // (Need to add InitializeToolkit stage to BrowserParts). 1179 // (Need to add InitializeToolkit stage to BrowserParts).
1154 // See also GTK setup in EarlyInitialization, above, and associated comments. 1180 // See also GTK setup in EarlyInitialization, above, and associated comments.
1155 1181
1156 #if defined(OS_WIN) 1182 #if defined(OS_WIN)
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1240 1266
1241 void BrowserMainLoop::EndStartupTracing() { 1267 void BrowserMainLoop::EndStartupTracing() {
1242 is_tracing_startup_ = false; 1268 is_tracing_startup_ = false;
1243 TracingController::GetInstance()->DisableRecording( 1269 TracingController::GetInstance()->DisableRecording(
1244 TracingController::CreateFileSink( 1270 TracingController::CreateFileSink(
1245 startup_trace_file_, 1271 startup_trace_file_,
1246 base::Bind(OnStoppedStartupTracing, startup_trace_file_))); 1272 base::Bind(OnStoppedStartupTracing, startup_trace_file_)));
1247 } 1273 }
1248 1274
1249 } // namespace content 1275 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/browser_main_loop.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698