| 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 |