OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 <stdlib.h> | 5 #include <stdlib.h> |
6 | 6 |
7 #include "app/app_switches.h" | 7 #include "app/app_switches.h" |
8 #include "app/gfx/gl/gl_context.h" | 8 #include "app/gfx/gl/gl_context.h" |
9 #include "app/gfx/gl/gl_implementation.h" | 9 #include "app/gfx/gl/gl_implementation.h" |
10 #include "base/environment.h" | 10 #include "base/environment.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include "chrome/app/breakpad_linux.h" | 25 #include "chrome/app/breakpad_linux.h" |
26 #endif | 26 #endif |
27 | 27 |
28 #if defined(OS_WIN) | 28 #if defined(OS_WIN) |
29 #include "app/win_util.h" | 29 #include "app/win_util.h" |
30 #endif | 30 #endif |
31 | 31 |
32 #if defined(USE_X11) | 32 #if defined(USE_X11) |
33 #include "app/x11_util.h" | 33 #include "app/x11_util.h" |
34 #include "app/x11_util_internal.h" | 34 #include "app/x11_util_internal.h" |
| 35 #include "gfx/gtk_util.h" |
35 #endif | 36 #endif |
36 | 37 |
37 | |
38 namespace { | 38 namespace { |
39 | 39 |
40 // 1% per watchdog trial group. | 40 // 1% per watchdog trial group. |
41 const int kFieldTrialSize = 1; | 41 const int kFieldTrialSize = 1; |
42 | 42 |
43 // 5 - 20 seconds timeout. | 43 // 5 - 20 seconds timeout. |
44 const int kMinGpuTimeout = 5; | 44 const int kMinGpuTimeout = 5; |
45 const int kMaxGpuTimeout = 20; | 45 const int kMaxGpuTimeout = 20; |
46 | 46 |
47 #if defined(USE_X11) | 47 #if defined(USE_X11) |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 } | 80 } |
81 | 81 |
82 MessageLoop main_message_loop(MessageLoop::TYPE_UI); | 82 MessageLoop main_message_loop(MessageLoop::TYPE_UI); |
83 PlatformThread::SetName("CrGpuMain"); | 83 PlatformThread::SetName("CrGpuMain"); |
84 | 84 |
85 #if defined(OS_WIN) | 85 #if defined(OS_WIN) |
86 win_util::ScopedCOMInitializer com_initializer; | 86 win_util::ScopedCOMInitializer com_initializer; |
87 #endif | 87 #endif |
88 | 88 |
89 #if defined(USE_X11) | 89 #if defined(USE_X11) |
| 90 // The X11 port of the command buffer code assumes it can access the X |
| 91 // display via the macro GDK_DISPLAY(), which implies that Gtk has been |
| 92 // initialized. This code was taken from PluginThread. TODO(kbr): |
| 93 // rethink whether initializing Gtk is really necessary or whether we |
| 94 // should just send a raw display connection down to the GPUProcessor. |
| 95 g_thread_init(NULL); |
| 96 gfx::GtkInitFromCommandLine(command_line); |
90 SetGpuX11ErrorHandlers(); | 97 SetGpuX11ErrorHandlers(); |
91 #endif | 98 #endif |
92 | 99 |
93 // On Linux the GpuThread constructor performs certain | 100 // Load the GL implementation and locate the bindings before starting the GPU |
94 // initialization that is required before accessing the default X | 101 // watchdog because this can take a lot of time and the GPU watchdog might |
95 // display. | 102 // terminate the GPU process. |
| 103 if (!gfx::GLContext::InitializeOneOff()) |
| 104 return EXIT_FAILURE; |
| 105 |
| 106 // Do this soon before running the message loop so accurate |
| 107 // initialization time is recorded in the GPU info. Don't do it before |
| 108 // starting the watchdog thread since it can take a significant amount of |
| 109 // time to collect GPU information in GpuThread::Init. |
96 GpuProcess gpu_process; | 110 GpuProcess gpu_process; |
97 GpuThread* gpu_thread = new GpuThread; | 111 GpuThread* gpu_thread = new GpuThread; |
| 112 gpu_thread->Init(start_time); |
98 gpu_process.set_main_thread(gpu_thread); | 113 gpu_process.set_main_thread(gpu_thread); |
99 | 114 |
100 // Load the GL implementation and locate the bindings before starting as | |
101 // this can take a lot of time and the GPU watchdog might terminate the GPU | |
102 // process. | |
103 if (!gfx::GLContext::InitializeOneOff()) | |
104 return EXIT_FAILURE; | |
105 | |
106 // Only enable this experimental feaure for a subset of users. | 115 // Only enable this experimental feaure for a subset of users. |
107 scoped_refptr<base::FieldTrial> watchdog_trial( | 116 scoped_refptr<base::FieldTrial> watchdog_trial( |
108 new base::FieldTrial("GpuWatchdogTrial", 100)); | 117 new base::FieldTrial("GpuWatchdogTrial", 100)); |
109 int watchdog_timeout = 0; | 118 int watchdog_timeout = 0; |
110 for (int i = kMinGpuTimeout; i <= kMaxGpuTimeout; ++i) { | 119 for (int i = kMinGpuTimeout; i <= kMaxGpuTimeout; ++i) { |
111 int group = watchdog_trial->AppendGroup(StringPrintf("%dsecs", i), | 120 int group = watchdog_trial->AppendGroup(StringPrintf("%dsecs", i), |
112 kFieldTrialSize); | 121 kFieldTrialSize); |
113 if (group == watchdog_trial->group()) { | 122 if (group == watchdog_trial->group()) { |
114 watchdog_timeout = i; | 123 watchdog_timeout = i; |
115 break; | 124 break; |
116 } | 125 } |
117 } | 126 } |
118 | 127 |
119 scoped_ptr<base::Environment> env(base::Environment::Create()); | |
120 | |
121 // In addition to disabling the watchdog if the command line switch is | 128 // In addition to disabling the watchdog if the command line switch is |
122 // present, disable it in two other cases. OSMesa is expected to run very | 129 // present, disable it in two other cases. OSMesa is expected to run very |
123 // slowly. Also disable the watchdog on valgrind because the code is expected | 130 // slowly. Also disable the watchdog on valgrind because the code is expected |
124 // to run slowly in that case. | 131 // to run slowly in that case. |
125 bool enable_watchdog = | 132 bool enable_watchdog = |
126 watchdog_timeout != 0 && | 133 watchdog_timeout != 0 && |
127 !command_line.HasSwitch(switches::kDisableGpuWatchdog) && | 134 !command_line.HasSwitch(switches::kDisableGpuWatchdog) && |
128 gfx::GetGLImplementation() != gfx::kGLImplementationOSMesaGL && | 135 gfx::GetGLImplementation() != gfx::kGLImplementationOSMesaGL && |
129 !RunningOnValgrind(); | 136 !RunningOnValgrind(); |
130 | 137 |
131 // Disable the watchdog in debug builds because they tend to only be run by | 138 // Disable the watchdog in debug builds because they tend to only be run by |
132 // developers who will not appreciate the watchdog killing the GPU process. | 139 // developers who will not appreciate the watchdog killing the GPU process. |
133 #ifndef NDEBUG | 140 #ifndef NDEBUG |
134 enable_watchdog = false; | 141 enable_watchdog = false; |
135 #endif | 142 #endif |
136 | 143 |
| 144 // Start the GPU watchdog only after anything that is expected to be time |
| 145 // consuming has completed, otherwise the process is liable to be aborted. |
137 scoped_refptr<GpuWatchdogThread> watchdog_thread; | 146 scoped_refptr<GpuWatchdogThread> watchdog_thread; |
138 if (enable_watchdog) { | 147 if (enable_watchdog) { |
139 watchdog_thread = new GpuWatchdogThread(MessageLoop::current(), | 148 watchdog_thread = new GpuWatchdogThread(MessageLoop::current(), |
140 watchdog_timeout * 1000); | 149 watchdog_timeout * 1000); |
141 watchdog_thread->Start(); | 150 watchdog_thread->Start(); |
142 } | 151 } |
143 | 152 |
144 // Do this immediately before running the message loop so the correct | |
145 // initialization time is recorded in the GPU info. | |
146 gpu_thread->Init(start_time); | |
147 | |
148 main_message_loop.Run(); | 153 main_message_loop.Run(); |
149 | 154 |
150 if (enable_watchdog) | 155 if (enable_watchdog) |
151 watchdog_thread->Stop(); | 156 watchdog_thread->Stop(); |
152 | 157 |
153 return 0; | 158 return 0; |
154 } | 159 } |
OLD | NEW |