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

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

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

Powered by Google App Engine
This is Rietveld 408576698