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

Side by Side Diff: content/browser/gpu/gpu_data_manager_impl.cc

Issue 14981007: Refactor GpuDataManagerImpl to make it thread-safe. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 7 years, 7 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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/gpu/gpu_data_manager_impl.h" 5 #include "content/browser/gpu/gpu_data_manager_impl.h"
6 6
7 #if defined(OS_MACOSX) 7 #include "content/browser/gpu/gpu_data_manager_impl_private.h"
8 #include <ApplicationServices/ApplicationServices.h>
9 #endif // OS_MACOSX
10
11 #include "base/bind.h"
12 #include "base/bind_helpers.h"
13 #include "base/command_line.h"
14 #include "base/debug/trace_event.h"
15 #include "base/metrics/field_trial.h"
16 #include "base/metrics/histogram.h"
17 #include "base/stringprintf.h"
18 #include "base/strings/string_number_conversions.h"
19 #include "base/strings/string_piece.h"
20 #include "base/sys_info.h"
21 #include "base/values.h"
22 #include "base/version.h"
23 #include "content/browser/gpu/gpu_process_host.h"
24 #include "content/browser/gpu/gpu_util.h"
25 #include "content/common/gpu/gpu_messages.h"
26 #include "content/gpu/gpu_info_collector.h"
27 #include "content/public/browser/browser_thread.h"
28 #include "content/public/browser/gpu_data_manager_observer.h"
29 #include "content/public/common/content_client.h"
30 #include "content/public/common/content_constants.h"
31 #include "content/public/common/content_switches.h"
32 #include "content/public/common/gpu_feature_type.h"
33 #include "gpu/command_buffer/service/gpu_switches.h"
34 #include "grit/content_resources.h"
35 #include "ui/base/ui_base_switches.h"
36 #include "ui/gl/gl_implementation.h"
37 #include "ui/gl/gl_switches.h"
38 #include "ui/gl/gpu_switching_manager.h"
39 #include "webkit/glue/webpreferences.h"
40 #include "webkit/plugins/plugin_switches.h"
41
42 #if defined(OS_WIN)
43 #include "base/win/windows_version.h"
44 #endif
45 8
46 namespace content { 9 namespace content {
47 namespace {
48
49 // Strip out the non-digital info; if after that, we get an empty string,
50 // return "0".
51 std::string ProcessVersionString(const std::string& raw_string) {
52 const std::string valid_set = "0123456789.";
53 size_t start_pos = raw_string.find_first_of(valid_set);
54 if (start_pos == std::string::npos)
55 return "0";
56 size_t end_pos = raw_string.find_first_not_of(raw_string, start_pos);
57 std::string version_string = raw_string.substr(
58 start_pos, end_pos - start_pos);
59 if (version_string.empty())
60 return "0";
61 return version_string;
62 }
63
64 // Combine the integers into a string, seperated by ','.
65 std::string IntSetToString(const std::set<int>& list) {
66 std::string rt;
67 for (std::set<int>::const_iterator it = list.begin();
68 it != list.end(); ++it) {
69 if (!rt.empty())
70 rt += ",";
71 rt += base::IntToString(*it);
72 }
73 return rt;
74 }
75
76 #if defined(OS_MACOSX)
77 void DisplayReconfigCallback(CGDirectDisplayID display,
78 CGDisplayChangeSummaryFlags flags,
79 void* gpu_data_manager) {
80 if (flags & kCGDisplayAddFlag) {
81 GpuDataManagerImpl* manager =
82 reinterpret_cast<GpuDataManagerImpl*>(gpu_data_manager);
83 DCHECK(manager);
84 manager->HandleGpuSwitch();
85 }
86 }
87 #endif // OS_MACOSX
88
89 // Block all domains' use of 3D APIs for this many milliseconds if
90 // approaching a threshold where system stability might be compromised.
91 const int64 kBlockAllDomainsMs = 10000;
92 const int kNumResetsWithinDuration = 1;
93
94 // Enums for UMA histograms.
95 enum BlockStatusHistogram {
96 BLOCK_STATUS_NOT_BLOCKED,
97 BLOCK_STATUS_SPECIFIC_DOMAIN_BLOCKED,
98 BLOCK_STATUS_ALL_DOMAINS_BLOCKED,
99 BLOCK_STATUS_MAX
100 };
101
102 } // namespace anonymous
103 10
104 // static 11 // static
105 GpuDataManager* GpuDataManager::GetInstance() { 12 GpuDataManager* GpuDataManager::GetInstance() {
106 return GpuDataManagerImpl::GetInstance(); 13 return GpuDataManagerImpl::GetInstance();
107 } 14 }
108 15
109 // static 16 // static
110 GpuDataManagerImpl* GpuDataManagerImpl::GetInstance() { 17 GpuDataManagerImpl* GpuDataManagerImpl::GetInstance() {
111 return Singleton<GpuDataManagerImpl>::get(); 18 return Singleton<GpuDataManagerImpl>::get();
112 } 19 }
113 20
114 void GpuDataManagerImpl::InitializeForTesting( 21 void GpuDataManagerImpl::InitializeForTesting(
115 const std::string& gpu_blacklist_json, 22 const std::string& gpu_blacklist_json, const GPUInfo& gpu_info) {
116 const GPUInfo& gpu_info) { 23 base::AutoLock auto_lock(lock_);
117 // This function is for testing only, so disable histograms. 24 private_->InitializeForTesting(gpu_blacklist_json, gpu_info);
118 update_histograms_ = false;
119
120 InitializeImpl(gpu_blacklist_json, std::string(), std::string(), gpu_info);
121 } 25 }
122 26
123 bool GpuDataManagerImpl::IsFeatureBlacklisted(int feature) const { 27 bool GpuDataManagerImpl::IsFeatureBlacklisted(int feature) const {
124 if (use_swiftshader_) { 28 base::AutoLock auto_lock(lock_);
125 // Skia's software rendering is probably more efficient than going through 29 return private_->IsFeatureBlacklisted(feature);
126 // software emulation of the GPU, so use that.
127 if (feature == GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS)
128 return true;
129 return false;
130 }
131
132 return (blacklisted_features_.count(feature) == 1);
133 }
134
135 size_t GpuDataManagerImpl::GetBlacklistedFeatureCount() const {
136 if (use_swiftshader_)
137 return 1;
138 return blacklisted_features_.size();
139 }
140
141 void GpuDataManagerImpl::AddGpuSwitchCallback(
142 const GpuSwitchCallback& callback) {
143 gpu_switch_callbacks_.push_back(callback);
144 }
145
146 void GpuDataManagerImpl::RemoveGpuSwitchCallback(
147 const GpuSwitchCallback& callback) {
148 for (size_t i = 0; i < gpu_switch_callbacks_.size(); i++) {
149 if (gpu_switch_callbacks_[i].Equals(callback)) {
150 gpu_switch_callbacks_.erase(gpu_switch_callbacks_.begin() + i);
151 return;
152 }
153 }
154 } 30 }
155 31
156 GPUInfo GpuDataManagerImpl::GetGPUInfo() const { 32 GPUInfo GpuDataManagerImpl::GetGPUInfo() const {
157 GPUInfo gpu_info; 33 base::AutoLock auto_lock(lock_);
158 { 34 return private_->GetGPUInfo();
159 base::AutoLock auto_lock(gpu_info_lock_);
160 gpu_info = gpu_info_;
161 }
162 return gpu_info;
163 } 35 }
164 36
165 void GpuDataManagerImpl::GetGpuProcessHandles( 37 void GpuDataManagerImpl::GetGpuProcessHandles(
166 const GetGpuProcessHandlesCallback& callback) const { 38 const GetGpuProcessHandlesCallback& callback) const {
167 GpuProcessHost::GetProcessHandles(callback); 39 base::AutoLock auto_lock(lock_);
40 private_->GetGpuProcessHandles(callback);
168 } 41 }
169 42
170 bool GpuDataManagerImpl::GpuAccessAllowed(std::string* reason) const { 43 bool GpuDataManagerImpl::GpuAccessAllowed(std::string* reason) const {
171 if (use_swiftshader_) 44 base::AutoLock auto_lock(lock_);
172 return true; 45 return private_->GpuAccessAllowed(reason);
173
174 if (!gpu_info_.gpu_accessible) {
175 if (reason) {
176 *reason = "GPU process launch failed.";
177 }
178 return false;
179 }
180
181 if (card_blacklisted_) {
182 if (reason) {
183 *reason = "GPU access is disabled ";
184 CommandLine* command_line = CommandLine::ForCurrentProcess();
185 if (command_line->HasSwitch(switches::kDisableGpu))
186 *reason += "through commandline switch --disable-gpu.";
187 else
188 *reason += "in chrome://settings.";
189 }
190 return false;
191 }
192
193 // We only need to block GPU process if more features are disallowed other
194 // than those in the preliminary gpu feature flags because the latter work
195 // through renderer commandline switches.
196 std::set<int> features = preliminary_blacklisted_features_;
197 MergeFeatureSets(&features, blacklisted_features_);
198 if (features.size() > preliminary_blacklisted_features_.size()) {
199 if (reason) {
200 *reason = "Features are disabled upon full but not preliminary GPU info.";
201 }
202 return false;
203 }
204
205 if (blacklisted_features_.size() == NUMBER_OF_GPU_FEATURE_TYPES) {
206 // On Linux, we use cached GL strings to make blacklist decsions at browser
207 // startup time. We need to launch the GPU process to validate these
208 // strings even if all features are blacklisted. If all GPU features are
209 // disabled, the GPU process will only initialize GL bindings, create a GL
210 // context, and collect full GPU info.
211 #if !defined(OS_LINUX)
212 if (reason) {
213 *reason = "All GPU features are blacklisted.";
214 }
215 return false;
216 #endif
217 }
218
219 return true;
220 } 46 }
221 47
222 void GpuDataManagerImpl::RequestCompleteGpuInfoIfNeeded() { 48 void GpuDataManagerImpl::RequestCompleteGpuInfoIfNeeded() {
223 if (complete_gpu_info_already_requested_ || gpu_info_.finalized) 49 base::AutoLock auto_lock(lock_);
224 return; 50 private_->RequestCompleteGpuInfoIfNeeded();
225 complete_gpu_info_already_requested_ = true;
226
227 GpuProcessHost::SendOnIO(
228 #if defined(OS_WIN)
229 GpuProcessHost::GPU_PROCESS_KIND_UNSANDBOXED,
230 #else
231 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
232 #endif
233 CAUSE_FOR_GPU_LAUNCH_GPUDATAMANAGER_REQUESTCOMPLETEGPUINFOIFNEEDED,
234 new GpuMsg_CollectGraphicsInfo());
235 } 51 }
236 52
237 bool GpuDataManagerImpl::IsCompleteGpuInfoAvailable() const { 53 bool GpuDataManagerImpl::IsCompleteGpuInfoAvailable() const {
238 return gpu_info_.finalized; 54 base::AutoLock auto_lock(lock_);
55 return private_->IsCompleteGpuInfoAvailable();
239 } 56 }
240 57
241 void GpuDataManagerImpl::RequestVideoMemoryUsageStatsUpdate() const { 58 void GpuDataManagerImpl::RequestVideoMemoryUsageStatsUpdate() const {
242 GpuProcessHost::SendOnIO( 59 base::AutoLock auto_lock(lock_);
243 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, 60 private_->RequestVideoMemoryUsageStatsUpdate();
244 CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH,
245 new GpuMsg_GetVideoMemoryUsageStats());
246 } 61 }
247 62
248 bool GpuDataManagerImpl::ShouldUseSwiftShader() const { 63 bool GpuDataManagerImpl::ShouldUseSwiftShader() const {
249 return use_swiftshader_; 64 base::AutoLock auto_lock(lock_);
250 } 65 return private_->ShouldUseSwiftShader();
251 66 }
252 void GpuDataManagerImpl::RegisterSwiftShaderPath(const base::FilePath& path) { 67
253 swiftshader_path_ = path; 68 void GpuDataManagerImpl::RegisterSwiftShaderPath(
254 EnableSwiftShaderIfNecessary(); 69 const base::FilePath& path) {
255 } 70 base::AutoLock auto_lock(lock_);
256 71 private_->RegisterSwiftShaderPath(path);
257 void GpuDataManagerImpl::AddObserver(GpuDataManagerObserver* observer) { 72 }
258 observer_list_->AddObserver(observer); 73
259 } 74 void GpuDataManagerImpl::AddObserver(
260 75 GpuDataManagerObserver* observer) {
261 void GpuDataManagerImpl::RemoveObserver(GpuDataManagerObserver* observer) { 76 base::AutoLock auto_lock(lock_);
262 observer_list_->RemoveObserver(observer); 77 private_->AddObserver(observer);
78 }
79
80 void GpuDataManagerImpl::RemoveObserver(
81 GpuDataManagerObserver* observer) {
82 base::AutoLock auto_lock(lock_);
83 private_->RemoveObserver(observer);
263 } 84 }
264 85
265 void GpuDataManagerImpl::UnblockDomainFrom3DAPIs(const GURL& url) { 86 void GpuDataManagerImpl::UnblockDomainFrom3DAPIs(const GURL& url) {
266 // This method must do two things: 87 base::AutoLock auto_lock(lock_);
267 // 88 private_->UnblockDomainFrom3DAPIs(url);
268 // 1. If the specific domain is blocked, then unblock it.
269 //
270 // 2. Reset our notion of how many GPU resets have occurred recently.
271 // This is necessary even if the specific domain was blocked.
272 // Otherwise, if we call Are3DAPIsBlocked with the same domain right
273 // after unblocking it, it will probably still be blocked because of
274 // the recent GPU reset caused by that domain.
275 //
276 // These policies could be refined, but at a certain point the behavior
277 // will become difficult to explain.
278 std::string domain = GetDomainFromURL(url);
279
280 base::AutoLock auto_lock(gpu_info_lock_);
281 blocked_domains_.erase(domain);
282 timestamps_of_gpu_resets_.clear();
283 } 89 }
284 90
285 void GpuDataManagerImpl::DisableGpuWatchdog() { 91 void GpuDataManagerImpl::DisableGpuWatchdog() {
286 GpuProcessHost::SendOnIO( 92 base::AutoLock auto_lock(lock_);
287 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, 93 private_->DisableGpuWatchdog();
288 CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH,
289 new GpuMsg_DisableWatchdog);
290 } 94 }
291 95
292 void GpuDataManagerImpl::SetGLStrings(const std::string& gl_vendor, 96 void GpuDataManagerImpl::SetGLStrings(const std::string& gl_vendor,
293 const std::string& gl_renderer, 97 const std::string& gl_renderer,
294 const std::string& gl_version) { 98 const std::string& gl_version) {
295 if (gl_vendor.empty() && gl_renderer.empty() && gl_version.empty()) 99 base::AutoLock auto_lock(lock_);
296 return; 100 private_->SetGLStrings(gl_vendor, gl_renderer, gl_version);
297
298 GPUInfo gpu_info;
299 {
300 base::AutoLock auto_lock(gpu_info_lock_);
301 // If GPUInfo already got GL strings, do nothing. This is for the rare
302 // situation where GPU process collected GL strings before this call.
303 if (!gpu_info_.gl_vendor.empty() ||
304 !gpu_info_.gl_renderer.empty() ||
305 !gpu_info_.gl_version_string.empty())
306 return;
307 gpu_info = gpu_info_;
308 }
309
310 gpu_info.gl_vendor = gl_vendor;
311 gpu_info.gl_renderer = gl_renderer;
312 gpu_info.gl_version_string = gl_version;
313
314 gpu_info_collector::CollectDriverInfoGL(&gpu_info);
315
316 UpdateGpuInfo(gpu_info);
317 UpdateGpuSwitchingManager(gpu_info);
318 UpdatePreliminaryBlacklistedFeatures();
319 } 101 }
320 102
321 void GpuDataManagerImpl::GetGLStrings(std::string* gl_vendor, 103 void GpuDataManagerImpl::GetGLStrings(std::string* gl_vendor,
322 std::string* gl_renderer, 104 std::string* gl_renderer,
323 std::string* gl_version) { 105 std::string* gl_version) {
324 DCHECK(gl_vendor && gl_renderer && gl_version); 106 base::AutoLock auto_lock(lock_);
325 107 private_->GetGLStrings(gl_vendor, gl_renderer, gl_version);
326 base::AutoLock auto_lock(gpu_info_lock_); 108 }
327 *gl_vendor = gpu_info_.gl_vendor; 109
328 *gl_renderer = gpu_info_.gl_renderer; 110 void GpuDataManagerImpl::DisableHardwareAcceleration() {
329 *gl_version = gpu_info_.gl_version_string; 111 base::AutoLock auto_lock(lock_);
330 } 112 private_->DisableHardwareAcceleration();
331 113 }
332 114
333 void GpuDataManagerImpl::Initialize() { 115 void GpuDataManagerImpl::Initialize() {
334 TRACE_EVENT0("startup", "GpuDataManagerImpl::Initialize"); 116 base::AutoLock auto_lock(lock_);
335 CommandLine* command_line = CommandLine::ForCurrentProcess(); 117 private_->Initialize();
336 if (command_line->HasSwitch(switches::kSkipGpuDataLoading))
337 return;
338
339 GPUInfo gpu_info;
340 {
341 TRACE_EVENT0("startup",
342 "GpuDataManagerImpl::Initialize:CollectBasicGraphicsInfo");
343 gpu_info_collector::CollectBasicGraphicsInfo(&gpu_info);
344 }
345 #if defined(ARCH_CPU_X86_FAMILY)
346 if (!gpu_info.gpu.vendor_id || !gpu_info.gpu.device_id)
347 gpu_info.finalized = true;
348 #endif
349
350 std::string gpu_blacklist_string;
351 std::string gpu_switching_list_string;
352 std::string gpu_driver_bug_list_string;
353 if (!command_line->HasSwitch(switches::kIgnoreGpuBlacklist)) {
354 const base::StringPiece gpu_blacklist_json =
355 GetContentClient()->GetDataResource(
356 IDR_GPU_BLACKLIST, ui::SCALE_FACTOR_NONE);
357 gpu_blacklist_string = gpu_blacklist_json.as_string();
358 const base::StringPiece gpu_switching_list_json =
359 GetContentClient()->GetDataResource(
360 IDR_GPU_SWITCHING_LIST, ui::SCALE_FACTOR_NONE);
361 gpu_switching_list_string = gpu_switching_list_json.as_string();
362 }
363 if (!command_line->HasSwitch(switches::kDisableGpuDriverBugWorkarounds)) {
364 const base::StringPiece gpu_driver_bug_list_json =
365 GetContentClient()->GetDataResource(
366 IDR_GPU_DRIVER_BUG_LIST, ui::SCALE_FACTOR_NONE);
367 gpu_driver_bug_list_string = gpu_driver_bug_list_json.as_string();
368 }
369 InitializeImpl(gpu_blacklist_string,
370 gpu_switching_list_string,
371 gpu_driver_bug_list_string,
372 gpu_info);
373 // We pass down the list to GPU command buffer through commandline
374 // switches at GPU process launch. However, in situations where we don't
375 // have a GPU process, we append the browser process commandline.
376 if (command_line->HasSwitch(switches::kSingleProcess) ||
377 command_line->HasSwitch(switches::kInProcessGPU)) {
378 if (!gpu_driver_bugs_.empty()) {
379 command_line->AppendSwitchASCII(switches::kGpuDriverBugWorkarounds,
380 IntSetToString(gpu_driver_bugs_));
381 }
382 }
383 } 118 }
384 119
385 void GpuDataManagerImpl::UpdateGpuInfo(const GPUInfo& gpu_info) { 120 void GpuDataManagerImpl::UpdateGpuInfo(const GPUInfo& gpu_info) {
386 // No further update of gpu_info if falling back to SwiftShader. 121 base::AutoLock auto_lock(lock_);
387 if (use_swiftshader_) 122 private_->UpdateGpuInfo(gpu_info);
388 return;
389
390 GPUInfo my_gpu_info;
391 {
392 base::AutoLock auto_lock(gpu_info_lock_);
393 gpu_info_collector::MergeGPUInfo(&gpu_info_, gpu_info);
394 complete_gpu_info_already_requested_ =
395 complete_gpu_info_already_requested_ || gpu_info_.finalized;
396 my_gpu_info = gpu_info_;
397 }
398
399 GetContentClient()->SetGpuInfo(my_gpu_info);
400
401 if (gpu_blacklist_) {
402 std::set<int> features = gpu_blacklist_->MakeDecision(
403 GpuControlList::kOsAny, std::string(), my_gpu_info);
404 if (update_histograms_)
405 UpdateStats(gpu_blacklist_.get(), features);
406
407 UpdateBlacklistedFeatures(features);
408 }
409 if (gpu_switching_list_) {
410 std::set<int> option = gpu_switching_list_->MakeDecision(
411 GpuControlList::kOsAny, std::string(), my_gpu_info);
412 if (option.size() == 1) {
413 // Blacklist decision should not overwrite commandline switch from users.
414 CommandLine* command_line = CommandLine::ForCurrentProcess();
415 if (!command_line->HasSwitch(switches::kGpuSwitching))
416 gpu_switching_ = static_cast<GpuSwitchingOption>(*(option.begin()));
417 }
418 }
419 if (gpu_driver_bug_list_)
420 gpu_driver_bugs_ = gpu_driver_bug_list_->MakeDecision(
421 GpuControlList::kOsAny, std::string(), my_gpu_info);
422
423 // We have to update GpuFeatureType before notify all the observers.
424 NotifyGpuInfoUpdate();
425 } 123 }
426 124
427 void GpuDataManagerImpl::UpdateVideoMemoryUsageStats( 125 void GpuDataManagerImpl::UpdateVideoMemoryUsageStats(
428 const GPUVideoMemoryUsageStats& video_memory_usage_stats) { 126 const GPUVideoMemoryUsageStats& video_memory_usage_stats) {
429 observer_list_->Notify(&GpuDataManagerObserver::OnVideoMemoryUsageStatsUpdate, 127 base::AutoLock auto_lock(lock_);
430 video_memory_usage_stats); 128 private_->UpdateVideoMemoryUsageStats(video_memory_usage_stats);
431 } 129 }
432 130
433 void GpuDataManagerImpl::AppendRendererCommandLine( 131 void GpuDataManagerImpl::AppendRendererCommandLine(
434 CommandLine* command_line) const { 132 CommandLine* command_line) const {
435 DCHECK(command_line); 133 base::AutoLock auto_lock(lock_);
436 134 private_->AppendRendererCommandLine(command_line);
437 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_WEBGL)) {
438 #if !defined(OS_ANDROID)
439 if (!command_line->HasSwitch(switches::kDisableExperimentalWebGL))
440 command_line->AppendSwitch(switches::kDisableExperimentalWebGL);
441 #endif
442 if (!command_line->HasSwitch(switches::kDisablePepper3d))
443 command_line->AppendSwitch(switches::kDisablePepper3d);
444 }
445 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_MULTISAMPLING) &&
446 !command_line->HasSwitch(switches::kDisableGLMultisampling))
447 command_line->AppendSwitch(switches::kDisableGLMultisampling);
448 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) &&
449 !command_line->HasSwitch(switches::kDisableAcceleratedCompositing))
450 command_line->AppendSwitch(switches::kDisableAcceleratedCompositing);
451 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS) &&
452 !command_line->HasSwitch(switches::kDisableAccelerated2dCanvas))
453 command_line->AppendSwitch(switches::kDisableAccelerated2dCanvas);
454 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE) &&
455 !command_line->HasSwitch(switches::kDisableAcceleratedVideoDecode))
456 command_line->AppendSwitch(switches::kDisableAcceleratedVideoDecode);
457 if (ShouldUseSwiftShader())
458 command_line->AppendSwitch(switches::kDisableFlashFullscreen3d);
459 } 135 }
460 136
461 void GpuDataManagerImpl::AppendGpuCommandLine( 137 void GpuDataManagerImpl::AppendGpuCommandLine(
462 CommandLine* command_line) const { 138 CommandLine* command_line) const {
463 DCHECK(command_line); 139 base::AutoLock auto_lock(lock_);
464 140 private_->AppendGpuCommandLine(command_line);
465 std::string use_gl =
466 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switches::kUseGL);
467 base::FilePath swiftshader_path =
468 CommandLine::ForCurrentProcess()->GetSwitchValuePath(
469 switches::kSwiftShaderPath);
470 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_MULTISAMPLING) &&
471 !command_line->HasSwitch(switches::kDisableGLMultisampling))
472 command_line->AppendSwitch(switches::kDisableGLMultisampling);
473 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_TEXTURE_SHARING))
474 command_line->AppendSwitch(switches::kDisableImageTransportSurface);
475
476 if (use_swiftshader_) {
477 command_line->AppendSwitchASCII(switches::kUseGL, "swiftshader");
478 if (swiftshader_path.empty())
479 swiftshader_path = swiftshader_path_;
480 } else if ((IsFeatureBlacklisted(GPU_FEATURE_TYPE_WEBGL) ||
481 IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) ||
482 IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS)) &&
483 (use_gl == "any")) {
484 command_line->AppendSwitchASCII(
485 switches::kUseGL, gfx::kGLImplementationOSMesaName);
486 } else if (!use_gl.empty()) {
487 command_line->AppendSwitchASCII(switches::kUseGL, use_gl);
488 }
489 if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus()) {
490 command_line->AppendSwitchASCII(switches::kSupportsDualGpus, "true");
491 switch (gpu_switching_) {
492 case GPU_SWITCHING_OPTION_FORCE_DISCRETE:
493 command_line->AppendSwitchASCII(switches::kGpuSwitching,
494 switches::kGpuSwitchingOptionNameForceDiscrete);
495 break;
496 case GPU_SWITCHING_OPTION_FORCE_INTEGRATED:
497 command_line->AppendSwitchASCII(switches::kGpuSwitching,
498 switches::kGpuSwitchingOptionNameForceIntegrated);
499 break;
500 case GPU_SWITCHING_OPTION_AUTOMATIC:
501 case GPU_SWITCHING_OPTION_UNKNOWN:
502 break;
503 }
504 } else {
505 command_line->AppendSwitchASCII(switches::kSupportsDualGpus, "false");
506 }
507
508 if (!swiftshader_path.empty())
509 command_line->AppendSwitchPath(switches::kSwiftShaderPath,
510 swiftshader_path);
511
512 if (!gpu_driver_bugs_.empty()) {
513 command_line->AppendSwitchASCII(switches::kGpuDriverBugWorkarounds,
514 IntSetToString(gpu_driver_bugs_));
515 }
516
517 #if defined(OS_WIN)
518 // DisplayLink 7.1 and earlier can cause the GPU process to crash on startup.
519 // http://crbug.com/177611
520 // Thinkpad USB Port Replicator driver causes GPU process to crash when the
521 // sandbox is enabled. http://crbug.com/181665.
522 if ((gpu_info_.display_link_version.IsValid()
523 && gpu_info_.display_link_version.IsOlderThan("7.2")) ||
524 gpu_info_.lenovo_dcute) {
525 command_line->AppendSwitch(switches::kReduceGpuSandbox);
526 }
527 #endif
528
529 {
530 base::AutoLock auto_lock(gpu_info_lock_);
531 if (gpu_info_.optimus)
532 command_line->AppendSwitch(switches::kReduceGpuSandbox);
533 if (gpu_info_.amd_switchable) {
534 // The image transport surface currently doesn't work with AMD Dynamic
535 // Switchable graphics.
536 command_line->AppendSwitch(switches::kReduceGpuSandbox);
537 command_line->AppendSwitch(switches::kDisableImageTransportSurface);
538 }
539 // Pass GPU and driver information to GPU process. We try to avoid full GPU
540 // info collection at GPU process startup, but we need gpu vendor_id,
541 // device_id, driver_vendor, driver_version for deciding whether we need to
542 // collect full info (on Linux) and for crash reporting purpose.
543 command_line->AppendSwitchASCII(switches::kGpuVendorID,
544 base::StringPrintf("0x%04x", gpu_info_.gpu.vendor_id));
545 command_line->AppendSwitchASCII(switches::kGpuDeviceID,
546 base::StringPrintf("0x%04x", gpu_info_.gpu.device_id));
547 command_line->AppendSwitchASCII(switches::kGpuDriverVendor,
548 gpu_info_.driver_vendor);
549 command_line->AppendSwitchASCII(switches::kGpuDriverVersion,
550 gpu_info_.driver_version);
551 }
552 } 141 }
553 142
554 void GpuDataManagerImpl::AppendPluginCommandLine( 143 void GpuDataManagerImpl::AppendPluginCommandLine(
555 CommandLine* command_line) const { 144 CommandLine* command_line) const {
556 DCHECK(command_line); 145 base::AutoLock auto_lock(lock_);
557 146 private_->AppendPluginCommandLine(command_line);
558 #if defined(OS_MACOSX) 147 }
559 // TODO(jbauman): Add proper blacklist support for core animation plugins so 148
560 // special-casing this video card won't be necessary. See 149 void GpuDataManagerImpl::UpdateRendererWebPrefs(
561 // http://crbug.com/134015 150 WebPreferences* prefs) const {
562 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) || 151 base::AutoLock auto_lock(lock_);
563 CommandLine::ForCurrentProcess()->HasSwitch( 152 private_->UpdateRendererWebPrefs(prefs);
564 switches::kDisableAcceleratedCompositing)) {
565 if (!command_line->HasSwitch(
566 switches::kDisableCoreAnimationPlugins))
567 command_line->AppendSwitch(
568 switches::kDisableCoreAnimationPlugins);
569 }
570 #endif
571 }
572
573 void GpuDataManagerImpl::UpdateRendererWebPrefs(WebPreferences* prefs) const {
574 DCHECK(prefs);
575
576 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING))
577 prefs->accelerated_compositing_enabled = false;
578 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_WEBGL))
579 prefs->experimental_webgl_enabled = false;
580 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_FLASH3D))
581 prefs->flash_3d_enabled = false;
582 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_FLASH_STAGE3D)) {
583 prefs->flash_stage3d_enabled = false;
584 prefs->flash_stage3d_baseline_enabled = false;
585 }
586 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE))
587 prefs->flash_stage3d_baseline_enabled = false;
588 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS))
589 prefs->accelerated_2d_canvas_enabled = false;
590 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_MULTISAMPLING))
591 prefs->gl_multisampling_enabled = false;
592 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_3D_CSS)) {
593 prefs->accelerated_compositing_for_3d_transforms_enabled = false;
594 prefs->accelerated_compositing_for_animation_enabled = false;
595 }
596 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_VIDEO))
597 prefs->accelerated_compositing_for_video_enabled = false;
598
599 // Accelerated video and animation are slower than regular when using
600 // SwiftShader. 3D CSS may also be too slow to be worthwhile.
601 if (ShouldUseSwiftShader()) {
602 prefs->accelerated_compositing_for_video_enabled = false;
603 prefs->accelerated_compositing_for_animation_enabled = false;
604 prefs->accelerated_compositing_for_3d_transforms_enabled = false;
605 prefs->accelerated_compositing_for_plugins_enabled = false;
606 }
607 } 153 }
608 154
609 GpuSwitchingOption GpuDataManagerImpl::GetGpuSwitchingOption() const { 155 GpuSwitchingOption GpuDataManagerImpl::GetGpuSwitchingOption() const {
610 if (!ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus()) 156 base::AutoLock auto_lock(lock_);
611 return GPU_SWITCHING_OPTION_UNKNOWN; 157 return private_->GetGpuSwitchingOption();
612 return gpu_switching_;
613 }
614
615 void GpuDataManagerImpl::DisableHardwareAcceleration() {
616 card_blacklisted_ = true;
617
618 for (int i = 0; i < NUMBER_OF_GPU_FEATURE_TYPES; ++i)
619 blacklisted_features_.insert(i);
620
621 EnableSwiftShaderIfNecessary();
622 NotifyGpuInfoUpdate();
623 } 158 }
624 159
625 std::string GpuDataManagerImpl::GetBlacklistVersion() const { 160 std::string GpuDataManagerImpl::GetBlacklistVersion() const {
626 if (gpu_blacklist_) 161 base::AutoLock auto_lock(lock_);
627 return gpu_blacklist_->version(); 162 return private_->GetBlacklistVersion();
628 return "0";
629 } 163 }
630 164
631 base::ListValue* GpuDataManagerImpl::GetBlacklistReasons() const { 165 base::ListValue* GpuDataManagerImpl::GetBlacklistReasons() const {
632 ListValue* reasons = new ListValue(); 166 base::AutoLock auto_lock(lock_);
633 if (gpu_blacklist_) 167 return private_->GetBlacklistReasons();
634 gpu_blacklist_->GetReasons(reasons); 168 }
635 return reasons; 169
636 } 170 void GpuDataManagerImpl::AddLogMessage(int level,
637 171 const std::string& header,
638 void GpuDataManagerImpl::AddLogMessage( 172 const std::string& message) {
639 int level, const std::string& header, const std::string& message) { 173 base::AutoLock auto_lock(lock_);
640 base::AutoLock auto_lock(log_messages_lock_); 174 private_->AddLogMessage(level, header, message);
641 DictionaryValue* dict = new DictionaryValue(); 175 }
642 dict->SetInteger("level", level); 176
643 dict->SetString("header", header); 177 void GpuDataManagerImpl::ProcessCrashed(
644 dict->SetString("message", message); 178 base::TerminationStatus exit_code) {
645 log_messages_.Append(dict); 179 base::AutoLock auto_lock(lock_);
646 } 180 private_->ProcessCrashed(exit_code);
647
648 void GpuDataManagerImpl::ProcessCrashed(base::TerminationStatus exit_code) {
649 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
650 BrowserThread::PostTask(BrowserThread::UI,
651 FROM_HERE,
652 base::Bind(&GpuDataManagerImpl::ProcessCrashed,
653 base::Unretained(this),
654 exit_code));
655 return;
656 }
657 observer_list_->Notify(&GpuDataManagerObserver::OnGpuProcessCrashed,
658 exit_code);
659 } 181 }
660 182
661 base::ListValue* GpuDataManagerImpl::GetLogMessages() const { 183 base::ListValue* GpuDataManagerImpl::GetLogMessages() const {
662 base::ListValue* value; 184 base::AutoLock auto_lock(lock_);
663 { 185 return private_->GetLogMessages();
664 base::AutoLock auto_lock(log_messages_lock_);
665 value = log_messages_.DeepCopy();
666 }
667 return value;
668 } 186 }
669 187
670 void GpuDataManagerImpl::HandleGpuSwitch() { 188 void GpuDataManagerImpl::HandleGpuSwitch() {
671 complete_gpu_info_already_requested_ = false; 189 base::AutoLock auto_lock(lock_);
672 gpu_info_.finalized = false; 190 private_->HandleGpuSwitch();
673 for (size_t i = 0; i < gpu_switch_callbacks_.size(); ++i)
674 gpu_switch_callbacks_[i].Run();
675 } 191 }
676 192
677 #if defined(OS_WIN) 193 #if defined(OS_WIN)
678 bool GpuDataManagerImpl::IsUsingAcceleratedSurface() const { 194 bool GpuDataManagerImpl::IsUsingAcceleratedSurface() const {
679 if (base::win::GetVersion() < base::win::VERSION_VISTA) 195 base::AutoLock auto_lock(lock_);
680 return false; 196 return private_->IsUsingAcceleratedSurface();
681
682 if (gpu_info_.amd_switchable)
683 return false;
684 if (use_swiftshader_)
685 return false;
686 CommandLine* command_line = CommandLine::ForCurrentProcess();
687 if (command_line->HasSwitch(switches::kDisableImageTransportSurface))
688 return false;
689 return !IsFeatureBlacklisted(GPU_FEATURE_TYPE_TEXTURE_SHARING);
690 } 197 }
691 #endif 198 #endif
692 199
693 void GpuDataManagerImpl::BlockDomainFrom3DAPIs( 200 void GpuDataManagerImpl::BlockDomainFrom3DAPIs(
694 const GURL& url, DomainGuilt guilt) { 201 const GURL& url, DomainGuilt guilt) {
695 BlockDomainFrom3DAPIsAtTime(url, guilt, base::Time::Now()); 202 base::AutoLock auto_lock(lock_);
203 private_->BlockDomainFrom3DAPIs(url, guilt);
696 } 204 }
697 205
698 bool GpuDataManagerImpl::Are3DAPIsBlocked(const GURL& url, 206 bool GpuDataManagerImpl::Are3DAPIsBlocked(const GURL& url,
699 int render_process_id, 207 int render_process_id,
700 int render_view_id, 208 int render_view_id,
701 ThreeDAPIType requester) { 209 ThreeDAPIType requester) {
702 bool blocked = Are3DAPIsBlockedAtTime(url, base::Time::Now()) != 210 base::AutoLock auto_lock(lock_);
703 GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED; 211 return private_->Are3DAPIsBlocked(
704 if (blocked) { 212 url, render_process_id, render_view_id, requester);
705 BrowserThread::PostTask(
706 BrowserThread::UI, FROM_HERE,
707 base::Bind(&GpuDataManagerImpl::Notify3DAPIBlocked,
708 base::Unretained(this), url, render_process_id,
709 render_view_id, requester));
710 }
711
712 return blocked;
713 } 213 }
714 214
715 void GpuDataManagerImpl::DisableDomainBlockingFor3DAPIsForTesting() { 215 void GpuDataManagerImpl::DisableDomainBlockingFor3DAPIsForTesting() {
716 domain_blocking_enabled_ = false; 216 base::AutoLock auto_lock(lock_);
717 } 217 private_->DisableDomainBlockingFor3DAPIsForTesting();
718 218 }
719 GpuDataManagerImpl::GpuDataManagerImpl() 219
720 : complete_gpu_info_already_requested_(false), 220 size_t GpuDataManagerImpl::GetBlacklistedFeatureCount() const {
721 gpu_switching_(GPU_SWITCHING_OPTION_AUTOMATIC), 221 base::AutoLock auto_lock(lock_);
722 observer_list_(new GpuDataManagerObserverList), 222 return private_->GetBlacklistedFeatureCount();
723 use_swiftshader_(false),
724 card_blacklisted_(false),
725 update_histograms_(true),
726 window_count_(0),
727 domain_blocking_enabled_(true) {
728 CommandLine* command_line = CommandLine::ForCurrentProcess();
729 if (command_line->HasSwitch(switches::kDisableAcceleratedCompositing)) {
730 command_line->AppendSwitch(switches::kDisableAccelerated2dCanvas);
731 command_line->AppendSwitch(switches::kDisableAcceleratedLayers);
732 }
733 if (command_line->HasSwitch(switches::kDisableGpu))
734 DisableHardwareAcceleration();
735 if (command_line->HasSwitch(switches::kGpuSwitching)) {
736 std::string option_string = command_line->GetSwitchValueASCII(
737 switches::kGpuSwitching);
738 GpuSwitchingOption option = StringToGpuSwitchingOption(option_string);
739 if (option != GPU_SWITCHING_OPTION_UNKNOWN)
740 gpu_switching_ = option;
741 }
742
743 #if defined(OS_MACOSX)
744 CGDisplayRegisterReconfigurationCallback(DisplayReconfigCallback, this);
745 #endif // OS_MACOSX
746 }
747
748 GpuDataManagerImpl::~GpuDataManagerImpl() {
749 #if defined(OS_MACOSX)
750 CGDisplayRemoveReconfigurationCallback(DisplayReconfigCallback, this);
751 #endif
752 }
753
754 void GpuDataManagerImpl::InitializeImpl(
755 const std::string& gpu_blacklist_json,
756 const std::string& gpu_switching_list_json,
757 const std::string& gpu_driver_bug_list_json,
758 const GPUInfo& gpu_info) {
759 std::string browser_version_string = ProcessVersionString(
760 GetContentClient()->GetProduct());
761 CHECK(!browser_version_string.empty());
762
763 if (!gpu_blacklist_json.empty()) {
764 gpu_blacklist_.reset(GpuBlacklist::Create());
765 gpu_blacklist_->LoadList(
766 browser_version_string, gpu_blacklist_json,
767 GpuControlList::kCurrentOsOnly);
768 }
769 if (!gpu_switching_list_json.empty()) {
770 gpu_switching_list_.reset(GpuSwitchingList::Create());
771 gpu_switching_list_->LoadList(
772 browser_version_string, gpu_switching_list_json,
773 GpuControlList::kCurrentOsOnly);
774 }
775 if (!gpu_driver_bug_list_json.empty()) {
776 gpu_driver_bug_list_.reset(GpuDriverBugList::Create());
777 gpu_driver_bug_list_->LoadList(
778 browser_version_string, gpu_driver_bug_list_json,
779 GpuControlList::kCurrentOsOnly);
780 }
781
782 {
783 base::AutoLock auto_lock(gpu_info_lock_);
784 gpu_info_ = gpu_info;
785 }
786 UpdateGpuInfo(gpu_info);
787 UpdateGpuSwitchingManager(gpu_info);
788 UpdatePreliminaryBlacklistedFeatures();
789 }
790
791 void GpuDataManagerImpl::UpdateBlacklistedFeatures(
792 const std::set<int>& features) {
793 CommandLine* command_line = CommandLine::ForCurrentProcess();
794 blacklisted_features_ = features;
795
796 // Force disable using the GPU for these features, even if they would
797 // otherwise be allowed.
798 if (card_blacklisted_ ||
799 command_line->HasSwitch(switches::kBlacklistAcceleratedCompositing)) {
800 blacklisted_features_.insert(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING);
801 }
802 if (card_blacklisted_ ||
803 command_line->HasSwitch(switches::kBlacklistWebGL)) {
804 blacklisted_features_.insert(GPU_FEATURE_TYPE_WEBGL);
805 }
806
807 EnableSwiftShaderIfNecessary();
808 }
809
810 void GpuDataManagerImpl::UpdatePreliminaryBlacklistedFeatures() {
811 preliminary_blacklisted_features_ = blacklisted_features_;
812 }
813
814 void GpuDataManagerImpl::UpdateGpuSwitchingManager(const GPUInfo& gpu_info) {
815 ui::GpuSwitchingManager::GetInstance()->SetGpuCount(
816 gpu_info.secondary_gpus.size() + 1);
817
818 if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus()) {
819 switch (gpu_switching_) {
820 case GPU_SWITCHING_OPTION_FORCE_DISCRETE:
821 ui::GpuSwitchingManager::GetInstance()->ForceUseOfDiscreteGpu();
822 break;
823 case GPU_SWITCHING_OPTION_FORCE_INTEGRATED:
824 ui::GpuSwitchingManager::GetInstance()->ForceUseOfIntegratedGpu();
825 break;
826 case GPU_SWITCHING_OPTION_AUTOMATIC:
827 case GPU_SWITCHING_OPTION_UNKNOWN:
828 break;
829 }
830 }
831 }
832
833 void GpuDataManagerImpl::NotifyGpuInfoUpdate() {
834 observer_list_->Notify(&GpuDataManagerObserver::OnGpuInfoUpdate);
835 }
836
837 void GpuDataManagerImpl::EnableSwiftShaderIfNecessary() {
838 if (!GpuAccessAllowed(NULL) ||
839 blacklisted_features_.count(GPU_FEATURE_TYPE_WEBGL)) {
840 if (!swiftshader_path_.empty() &&
841 !CommandLine::ForCurrentProcess()->HasSwitch(
842 switches::kDisableSoftwareRasterizer))
843 use_swiftshader_ = true;
844 }
845 }
846
847 std::string GpuDataManagerImpl::GetDomainFromURL(const GURL& url) const {
848 // For the moment, we just use the host, or its IP address, as the
849 // entry in the set, rather than trying to figure out the top-level
850 // domain. This does mean that a.foo.com and b.foo.com will be
851 // treated independently in the blocking of a given domain, but it
852 // would require a third-party library to reliably figure out the
853 // top-level domain from a URL.
854 if (!url.has_host()) {
855 return std::string();
856 }
857
858 return url.host();
859 }
860
861 void GpuDataManagerImpl::BlockDomainFrom3DAPIsAtTime(
862 const GURL& url, DomainGuilt guilt, base::Time at_time) {
863 if (!domain_blocking_enabled_)
864 return;
865
866 std::string domain = GetDomainFromURL(url);
867
868 base::AutoLock auto_lock(gpu_info_lock_);
869 DomainBlockEntry& entry = blocked_domains_[domain];
870 entry.last_guilt = guilt;
871 timestamps_of_gpu_resets_.push_back(at_time);
872 }
873
874 GpuDataManagerImpl::DomainBlockStatus
875 GpuDataManagerImpl::Are3DAPIsBlockedAtTime(
876 const GURL& url, base::Time at_time) const {
877 if (!domain_blocking_enabled_)
878 return DOMAIN_BLOCK_STATUS_NOT_BLOCKED;
879
880 // Note: adjusting the policies in this code will almost certainly
881 // require adjusting the associated unit tests.
882 std::string domain = GetDomainFromURL(url);
883
884 base::AutoLock auto_lock(gpu_info_lock_);
885 {
886 DomainBlockMap::const_iterator iter = blocked_domains_.find(domain);
887 if (iter != blocked_domains_.end()) {
888 // Err on the side of caution, and assume that if a particular
889 // domain shows up in the block map, it's there for a good
890 // reason and don't let its presence there automatically expire.
891
892 UMA_HISTOGRAM_ENUMERATION("GPU.BlockStatusForClient3DAPIs",
893 BLOCK_STATUS_SPECIFIC_DOMAIN_BLOCKED,
894 BLOCK_STATUS_MAX);
895
896 return DOMAIN_BLOCK_STATUS_BLOCKED;
897 }
898 }
899
900 // Look at the timestamps of the recent GPU resets to see if there are
901 // enough within the threshold which would cause us to blacklist all
902 // domains. This doesn't need to be overly precise -- if time goes
903 // backward due to a system clock adjustment, that's fine.
904 //
905 // TODO(kbr): make this pay attention to the TDR thresholds in the
906 // Windows registry, but make sure it continues to be testable.
907 std::list<base::Time>::iterator iter = timestamps_of_gpu_resets_.begin();
908 int num_resets_within_timeframe = 0;
909 while (iter != timestamps_of_gpu_resets_.end()) {
910 base::Time time = *iter;
911 base::TimeDelta delta_t = at_time - time;
912
913 // If this entry has "expired", just remove it.
914 if (delta_t.InMilliseconds() > kBlockAllDomainsMs) {
915 iter = timestamps_of_gpu_resets_.erase(iter);
916 continue;
917 }
918
919 ++num_resets_within_timeframe;
920 ++iter;
921 }
922
923 if (num_resets_within_timeframe >= kNumResetsWithinDuration) {
924 UMA_HISTOGRAM_ENUMERATION("GPU.BlockStatusForClient3DAPIs",
925 BLOCK_STATUS_ALL_DOMAINS_BLOCKED,
926 BLOCK_STATUS_MAX);
927
928 return DOMAIN_BLOCK_STATUS_ALL_DOMAINS_BLOCKED;
929 }
930
931 UMA_HISTOGRAM_ENUMERATION("GPU.BlockStatusForClient3DAPIs",
932 BLOCK_STATUS_NOT_BLOCKED,
933 BLOCK_STATUS_MAX);
934
935 return DOMAIN_BLOCK_STATUS_NOT_BLOCKED;
936 }
937
938 int64 GpuDataManagerImpl::GetBlockAllDomainsDurationInMs() const {
939 return kBlockAllDomainsMs;
940 } 223 }
941 224
942 void GpuDataManagerImpl::Notify3DAPIBlocked(const GURL& url, 225 void GpuDataManagerImpl::Notify3DAPIBlocked(const GURL& url,
943 int render_process_id, 226 int render_process_id,
944 int render_view_id, 227 int render_view_id,
945 ThreeDAPIType requester) { 228 ThreeDAPIType requester) {
946 observer_list_->Notify(&GpuDataManagerObserver::DidBlock3DAPIs, 229 base::AutoLock auto_lock(lock_);
947 url, render_process_id, render_view_id, requester); 230 private_->Notify3DAPIBlocked(
231 url, render_process_id, render_view_id, requester);
232 }
233
234 GpuDataManagerImpl::GpuDataManagerImpl()
235 : private_(GpuDataManagerImplPrivate::Create(this)) {
236 }
237
238 GpuDataManagerImpl::~GpuDataManagerImpl() {
948 } 239 }
949 240
950 } // namespace content 241 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/gpu/gpu_data_manager_impl.h ('k') | content/browser/gpu/gpu_data_manager_impl_private.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698