Add ICU message format support
[chromium-blink-merge.git] / content / browser / gpu / gpu_data_manager_impl_private.cc
blob6fa3568da44e2af3d781dd10358d74d5e7f83fc7
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
3 // found in the LICENSE file.
5 #include "content/browser/gpu/gpu_data_manager_impl_private.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/command_line.h"
10 #include "base/metrics/field_trial.h"
11 #include "base/metrics/histogram.h"
12 #include "base/metrics/sparse_histogram.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/sys_info.h"
16 #include "base/trace_event/trace_event.h"
17 #include "base/version.h"
18 #include "cc/base/switches.h"
19 #include "content/browser/gpu/gpu_process_host.h"
20 #include "content/common/gpu/gpu_messages.h"
21 #include "content/public/browser/browser_thread.h"
22 #include "content/public/browser/gpu_data_manager_observer.h"
23 #include "content/public/common/content_client.h"
24 #include "content/public/common/content_constants.h"
25 #include "content/public/common/content_switches.h"
26 #include "content/public/common/web_preferences.h"
27 #include "gpu/command_buffer/service/gpu_switches.h"
28 #include "gpu/config/gpu_control_list_jsons.h"
29 #include "gpu/config/gpu_driver_bug_workaround_type.h"
30 #include "gpu/config/gpu_feature_type.h"
31 #include "gpu/config/gpu_info_collector.h"
32 #include "gpu/config/gpu_switches.h"
33 #include "gpu/config/gpu_util.h"
34 #include "ui/base/ui_base_switches.h"
35 #include "ui/gl/gl_implementation.h"
36 #include "ui/gl/gl_switches.h"
37 #include "ui/gl/gpu_switching_manager.h"
39 #if defined(OS_MACOSX)
40 #include <ApplicationServices/ApplicationServices.h>
41 #endif // OS_MACOSX
42 #if defined(OS_WIN)
43 #include "base/win/windows_version.h"
44 #endif // OS_WIN
45 #if defined(OS_ANDROID)
46 #include "ui/gfx/android/device_display_info.h"
47 #endif // OS_ANDROID
49 namespace content {
51 namespace {
53 enum GpuFeatureStatus {
54 kGpuFeatureEnabled = 0,
55 kGpuFeatureBlacklisted = 1,
56 kGpuFeatureDisabled = 2, // disabled by user but not blacklisted
57 kGpuFeatureNumStatus
60 #if defined(OS_WIN)
62 enum WinSubVersion {
63 kWinOthers = 0,
64 kWinXP,
65 kWinVista,
66 kWin7,
67 kWin8,
68 kNumWinSubVersions
71 int GetGpuBlacklistHistogramValueWin(GpuFeatureStatus status) {
72 static WinSubVersion sub_version = kNumWinSubVersions;
73 if (sub_version == kNumWinSubVersions) {
74 sub_version = kWinOthers;
75 std::string version_str = base::SysInfo::OperatingSystemVersion();
76 size_t pos = version_str.find_first_not_of("0123456789.");
77 if (pos != std::string::npos)
78 version_str = version_str.substr(0, pos);
79 Version os_version(version_str);
80 if (os_version.IsValid() && os_version.components().size() >= 2) {
81 const std::vector<uint32_t>& version_numbers = os_version.components();
82 if (version_numbers[0] == 5)
83 sub_version = kWinXP;
84 else if (version_numbers[0] == 6 && version_numbers[1] == 0)
85 sub_version = kWinVista;
86 else if (version_numbers[0] == 6 && version_numbers[1] == 1)
87 sub_version = kWin7;
88 else if (version_numbers[0] == 6 && version_numbers[1] == 2)
89 sub_version = kWin8;
92 int entry_index = static_cast<int>(sub_version) * kGpuFeatureNumStatus;
93 switch (status) {
94 case kGpuFeatureEnabled:
95 break;
96 case kGpuFeatureBlacklisted:
97 entry_index++;
98 break;
99 case kGpuFeatureDisabled:
100 entry_index += 2;
101 break;
103 return entry_index;
105 #endif // OS_WIN
107 // Send UMA histograms about the enabled features and GPU properties.
108 void UpdateStats(const gpu::GPUInfo& gpu_info,
109 const gpu::GpuBlacklist* blacklist,
110 const std::set<int>& blacklisted_features) {
111 uint32 max_entry_id = blacklist->max_entry_id();
112 if (max_entry_id == 0) {
113 // GPU Blacklist was not loaded. No need to go further.
114 return;
117 const base::CommandLine& command_line =
118 *base::CommandLine::ForCurrentProcess();
119 bool disabled = false;
121 // Use entry 0 to capture the total number of times that data
122 // was recorded in this histogram in order to have a convenient
123 // denominator to compute blacklist percentages for the rest of the
124 // entries.
125 UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResultsPerEntry",
126 0, max_entry_id + 1);
128 if (blacklisted_features.size() != 0) {
129 std::vector<uint32> flag_entries;
130 blacklist->GetDecisionEntries(&flag_entries, disabled);
131 DCHECK_GT(flag_entries.size(), 0u);
132 for (size_t i = 0; i < flag_entries.size(); ++i) {
133 UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResultsPerEntry",
134 flag_entries[i], max_entry_id + 1);
138 // This counts how many users are affected by a disabled entry - this allows
139 // us to understand the impact of an entry before enable it.
140 std::vector<uint32> flag_disabled_entries;
141 disabled = true;
142 blacklist->GetDecisionEntries(&flag_disabled_entries, disabled);
143 for (uint32 disabled_entry : flag_disabled_entries) {
144 UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResultsPerDisabledEntry",
145 disabled_entry, max_entry_id + 1);
148 const gpu::GpuFeatureType kGpuFeatures[] = {
149 gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS,
150 gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING,
151 gpu::GPU_FEATURE_TYPE_GPU_RASTERIZATION,
152 gpu::GPU_FEATURE_TYPE_WEBGL};
153 const std::string kGpuBlacklistFeatureHistogramNames[] = {
154 "GPU.BlacklistFeatureTestResults.Accelerated2dCanvas",
155 "GPU.BlacklistFeatureTestResults.GpuCompositing",
156 "GPU.BlacklistFeatureTestResults.GpuRasterization",
157 "GPU.BlacklistFeatureTestResults.Webgl"};
158 const bool kGpuFeatureUserFlags[] = {
159 command_line.HasSwitch(switches::kDisableAccelerated2dCanvas),
160 command_line.HasSwitch(switches::kDisableGpu),
161 command_line.HasSwitch(switches::kDisableGpuRasterization),
162 command_line.HasSwitch(switches::kDisableExperimentalWebGL)};
163 #if defined(OS_WIN)
164 const std::string kGpuBlacklistFeatureHistogramNamesWin[] = {
165 "GPU.BlacklistFeatureTestResultsWindows.Accelerated2dCanvas",
166 "GPU.BlacklistFeatureTestResultsWindows.GpuCompositing",
167 "GPU.BlacklistFeatureTestResultsWindows.GpuRasterization",
168 "GPU.BlacklistFeatureTestResultsWindows.Webgl"};
169 #endif
170 const size_t kNumFeatures =
171 sizeof(kGpuFeatures) / sizeof(gpu::GpuFeatureType);
172 for (size_t i = 0; i < kNumFeatures; ++i) {
173 // We can't use UMA_HISTOGRAM_ENUMERATION here because the same name is
174 // expected if the macro is used within a loop.
175 GpuFeatureStatus value = kGpuFeatureEnabled;
176 if (blacklisted_features.count(kGpuFeatures[i]))
177 value = kGpuFeatureBlacklisted;
178 else if (kGpuFeatureUserFlags[i])
179 value = kGpuFeatureDisabled;
180 base::HistogramBase* histogram_pointer = base::LinearHistogram::FactoryGet(
181 kGpuBlacklistFeatureHistogramNames[i],
182 1, kGpuFeatureNumStatus, kGpuFeatureNumStatus + 1,
183 base::HistogramBase::kUmaTargetedHistogramFlag);
184 histogram_pointer->Add(value);
185 #if defined(OS_WIN)
186 histogram_pointer = base::LinearHistogram::FactoryGet(
187 kGpuBlacklistFeatureHistogramNamesWin[i],
188 1, kNumWinSubVersions * kGpuFeatureNumStatus,
189 kNumWinSubVersions * kGpuFeatureNumStatus + 1,
190 base::HistogramBase::kUmaTargetedHistogramFlag);
191 histogram_pointer->Add(GetGpuBlacklistHistogramValueWin(value));
192 #endif
195 UMA_HISTOGRAM_SPARSE_SLOWLY("GPU.GLResetNotificationStrategy",
196 gpu_info.gl_reset_notification_strategy);
199 // Combine the integers into a string, seperated by ','.
200 std::string IntSetToString(const std::set<int>& list) {
201 std::string rt;
202 for (std::set<int>::const_iterator it = list.begin();
203 it != list.end(); ++it) {
204 if (!rt.empty())
205 rt += ",";
206 rt += base::IntToString(*it);
208 return rt;
211 #if defined(OS_MACOSX)
212 void DisplayReconfigCallback(CGDirectDisplayID display,
213 CGDisplayChangeSummaryFlags flags,
214 void* gpu_data_manager) {
215 if (flags == kCGDisplayBeginConfigurationFlag)
216 return; // This call contains no information about the display change
218 GpuDataManagerImpl* manager =
219 reinterpret_cast<GpuDataManagerImpl*>(gpu_data_manager);
220 DCHECK(manager);
222 // Display change.
223 bool display_changed = false;
224 uint32_t displayCount;
225 CGGetActiveDisplayList(0, NULL, &displayCount);
226 if (displayCount != manager->GetDisplayCount()) {
227 manager->SetDisplayCount(displayCount);
228 display_changed = true;
231 // Gpu change.
232 bool gpu_changed = false;
233 if (flags & kCGDisplayAddFlag) {
234 uint32 vendor_id, device_id;
235 if (gpu::CollectGpuID(&vendor_id, &device_id) == gpu::kCollectInfoSuccess) {
236 gpu_changed = manager->UpdateActiveGpu(vendor_id, device_id);
240 if (display_changed || gpu_changed)
241 manager->HandleGpuSwitch();
243 #endif // OS_MACOSX
245 // Block all domains' use of 3D APIs for this many milliseconds if
246 // approaching a threshold where system stability might be compromised.
247 const int64 kBlockAllDomainsMs = 10000;
248 const int kNumResetsWithinDuration = 1;
250 // Enums for UMA histograms.
251 enum BlockStatusHistogram {
252 BLOCK_STATUS_NOT_BLOCKED,
253 BLOCK_STATUS_SPECIFIC_DOMAIN_BLOCKED,
254 BLOCK_STATUS_ALL_DOMAINS_BLOCKED,
255 BLOCK_STATUS_MAX
258 } // namespace anonymous
260 void GpuDataManagerImplPrivate::InitializeForTesting(
261 const std::string& gpu_blacklist_json,
262 const gpu::GPUInfo& gpu_info) {
263 // This function is for testing only, so disable histograms.
264 update_histograms_ = false;
266 // Prevent all further initialization.
267 finalized_ = true;
269 InitializeImpl(gpu_blacklist_json, std::string(), gpu_info);
272 bool GpuDataManagerImplPrivate::IsFeatureBlacklisted(int feature) const {
273 #if defined(OS_CHROMEOS)
274 if (feature == gpu::GPU_FEATURE_TYPE_PANEL_FITTING &&
275 base::CommandLine::ForCurrentProcess()->HasSwitch(
276 switches::kDisablePanelFitting)) {
277 return true;
279 #endif // OS_CHROMEOS
280 if (use_swiftshader_ || ShouldUseWarp()) {
281 // Skia's software rendering is probably more efficient than going through
282 // software emulation of the GPU, so use that.
283 if (feature == gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS)
284 return true;
285 return false;
288 return (blacklisted_features_.count(feature) == 1);
291 bool GpuDataManagerImplPrivate::IsDriverBugWorkaroundActive(int feature) const {
292 return (gpu_driver_bugs_.count(feature) == 1);
295 size_t GpuDataManagerImplPrivate::GetBlacklistedFeatureCount() const {
296 if (use_swiftshader_ || ShouldUseWarp())
297 return 1;
298 return blacklisted_features_.size();
301 void GpuDataManagerImplPrivate::SetDisplayCount(unsigned int display_count) {
302 display_count_ = display_count;
305 unsigned int GpuDataManagerImplPrivate::GetDisplayCount() const {
306 return display_count_;
309 gpu::GPUInfo GpuDataManagerImplPrivate::GetGPUInfo() const {
310 return gpu_info_;
313 void GpuDataManagerImplPrivate::GetGpuProcessHandles(
314 const GpuDataManager::GetGpuProcessHandlesCallback& callback) const {
315 GpuProcessHost::GetProcessHandles(callback);
318 bool GpuDataManagerImplPrivate::GpuAccessAllowed(
319 std::string* reason) const {
320 if (use_swiftshader_ || ShouldUseWarp())
321 return true;
323 if (!gpu_process_accessible_) {
324 if (reason) {
325 *reason = "GPU process launch failed.";
327 return false;
330 if (card_blacklisted_) {
331 if (reason) {
332 *reason = "GPU access is disabled ";
333 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
334 if (command_line->HasSwitch(switches::kDisableGpu))
335 *reason += "through commandline switch --disable-gpu.";
336 else
337 *reason += "in chrome://settings.";
339 return false;
342 // We only need to block GPU process if more features are disallowed other
343 // than those in the preliminary gpu feature flags because the latter work
344 // through renderer commandline switches.
345 std::set<int> features = preliminary_blacklisted_features_;
346 gpu::MergeFeatureSets(&features, blacklisted_features_);
347 if (features.size() > preliminary_blacklisted_features_.size()) {
348 if (reason) {
349 *reason = "Features are disabled upon full but not preliminary GPU info.";
351 return false;
354 if (blacklisted_features_.size() == gpu::NUMBER_OF_GPU_FEATURE_TYPES) {
355 // On Linux, we use cached GL strings to make blacklist decsions at browser
356 // startup time. We need to launch the GPU process to validate these
357 // strings even if all features are blacklisted. If all GPU features are
358 // disabled, the GPU process will only initialize GL bindings, create a GL
359 // context, and collect full GPU info.
360 #if !defined(OS_LINUX)
361 if (reason) {
362 *reason = "All GPU features are blacklisted.";
364 return false;
365 #endif
368 return true;
371 void GpuDataManagerImplPrivate::RequestCompleteGpuInfoIfNeeded() {
372 if (complete_gpu_info_already_requested_ || IsCompleteGpuInfoAvailable())
373 return;
374 complete_gpu_info_already_requested_ = true;
376 GpuProcessHost::SendOnIO(
377 #if defined(OS_WIN)
378 GpuProcessHost::GPU_PROCESS_KIND_UNSANDBOXED,
379 #else
380 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
381 #endif
382 CAUSE_FOR_GPU_LAUNCH_GPUDATAMANAGER_REQUESTCOMPLETEGPUINFOIFNEEDED,
383 new GpuMsg_CollectGraphicsInfo());
386 bool GpuDataManagerImplPrivate::IsEssentialGpuInfoAvailable() const {
387 if (gpu_info_.basic_info_state == gpu::kCollectInfoNone ||
388 gpu_info_.context_info_state == gpu::kCollectInfoNone) {
389 return false;
391 return true;
394 bool GpuDataManagerImplPrivate::IsCompleteGpuInfoAvailable() const {
395 #if defined(OS_WIN)
396 if (gpu_info_.dx_diagnostics_info_state == gpu::kCollectInfoNone)
397 return false;
398 #endif
399 return IsEssentialGpuInfoAvailable();
402 void GpuDataManagerImplPrivate::RequestVideoMemoryUsageStatsUpdate() const {
403 GpuProcessHost::SendOnIO(
404 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
405 CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH,
406 new GpuMsg_GetVideoMemoryUsageStats());
409 bool GpuDataManagerImplPrivate::ShouldUseSwiftShader() const {
410 return use_swiftshader_;
413 void GpuDataManagerImplPrivate::RegisterSwiftShaderPath(
414 const base::FilePath& path) {
415 swiftshader_path_ = path;
416 EnableSwiftShaderIfNecessary();
419 bool GpuDataManagerImplPrivate::ShouldUseWarp() const {
420 std::string angle_impl_flag =
421 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
422 switches::kUseANGLE);
423 return use_warp_ || angle_impl_flag == gfx::kANGLEImplementationWARPName;
426 void GpuDataManagerImplPrivate::AddObserver(GpuDataManagerObserver* observer) {
427 GpuDataManagerImpl::UnlockedSession session(owner_);
428 observer_list_->AddObserver(observer);
431 void GpuDataManagerImplPrivate::RemoveObserver(
432 GpuDataManagerObserver* observer) {
433 GpuDataManagerImpl::UnlockedSession session(owner_);
434 observer_list_->RemoveObserver(observer);
437 void GpuDataManagerImplPrivate::UnblockDomainFrom3DAPIs(const GURL& url) {
438 // This method must do two things:
440 // 1. If the specific domain is blocked, then unblock it.
442 // 2. Reset our notion of how many GPU resets have occurred recently.
443 // This is necessary even if the specific domain was blocked.
444 // Otherwise, if we call Are3DAPIsBlocked with the same domain right
445 // after unblocking it, it will probably still be blocked because of
446 // the recent GPU reset caused by that domain.
448 // These policies could be refined, but at a certain point the behavior
449 // will become difficult to explain.
450 std::string domain = GetDomainFromURL(url);
452 blocked_domains_.erase(domain);
453 timestamps_of_gpu_resets_.clear();
456 void GpuDataManagerImplPrivate::DisableGpuWatchdog() {
457 GpuProcessHost::SendOnIO(
458 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
459 CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH,
460 new GpuMsg_DisableWatchdog);
463 void GpuDataManagerImplPrivate::SetGLStrings(const std::string& gl_vendor,
464 const std::string& gl_renderer,
465 const std::string& gl_version) {
466 if (gl_vendor.empty() && gl_renderer.empty() && gl_version.empty())
467 return;
469 // If GPUInfo already got GL strings, do nothing. This is for the rare
470 // situation where GPU process collected GL strings before this call.
471 if (!gpu_info_.gl_vendor.empty() ||
472 !gpu_info_.gl_renderer.empty() ||
473 !gpu_info_.gl_version.empty())
474 return;
476 gpu::GPUInfo gpu_info = gpu_info_;
478 gpu_info.gl_vendor = gl_vendor;
479 gpu_info.gl_renderer = gl_renderer;
480 gpu_info.gl_version = gl_version;
482 gpu::CollectDriverInfoGL(&gpu_info);
484 UpdateGpuInfo(gpu_info);
485 UpdateGpuSwitchingManager(gpu_info);
486 UpdatePreliminaryBlacklistedFeatures();
489 void GpuDataManagerImplPrivate::GetGLStrings(std::string* gl_vendor,
490 std::string* gl_renderer,
491 std::string* gl_version) {
492 DCHECK(gl_vendor && gl_renderer && gl_version);
494 *gl_vendor = gpu_info_.gl_vendor;
495 *gl_renderer = gpu_info_.gl_renderer;
496 *gl_version = gpu_info_.gl_version;
499 void GpuDataManagerImplPrivate::Initialize() {
500 TRACE_EVENT0("startup", "GpuDataManagerImpl::Initialize");
501 if (finalized_) {
502 DVLOG(0) << "GpuDataManagerImpl marked as finalized; skipping Initialize";
503 return;
506 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
507 if (command_line->HasSwitch(switches::kSkipGpuDataLoading))
508 return;
510 gpu::GPUInfo gpu_info;
511 if (command_line->GetSwitchValueASCII(
512 switches::kUseGL) == gfx::kGLImplementationOSMesaName) {
513 // If using the OSMesa GL implementation, use fake vendor and device ids to
514 // make sure it never gets blacklisted. This is better than simply
515 // cancelling GPUInfo gathering as it allows us to proceed with loading the
516 // blacklist below which may have non-device specific entries we want to
517 // apply anyways (e.g., OS version blacklisting).
518 gpu_info.gpu.vendor_id = 0xffff;
519 gpu_info.gpu.device_id = 0xffff;
521 // Also declare the driver_vendor to be osmesa to be able to specify
522 // exceptions based on driver_vendor==osmesa for some blacklist rules.
523 gpu_info.driver_vendor = gfx::kGLImplementationOSMesaName;
524 } else {
525 TRACE_EVENT0("startup",
526 "GpuDataManagerImpl::Initialize:CollectBasicGraphicsInfo");
527 gpu::CollectBasicGraphicsInfo(&gpu_info);
529 #if defined(ARCH_CPU_X86_FAMILY)
530 if (!gpu_info.gpu.vendor_id || !gpu_info.gpu.device_id) {
531 gpu_info.context_info_state = gpu::kCollectInfoNonFatalFailure;
532 #if defined(OS_WIN)
533 gpu_info.dx_diagnostics_info_state = gpu::kCollectInfoNonFatalFailure;
534 #endif // OS_WIN
536 #endif // ARCH_CPU_X86_FAMILY
538 std::string gpu_blacklist_string;
539 std::string gpu_driver_bug_list_string;
540 if (!command_line->HasSwitch(switches::kIgnoreGpuBlacklist) &&
541 !command_line->HasSwitch(switches::kUseGpuInTests)) {
542 gpu_blacklist_string = gpu::kSoftwareRenderingListJson;
544 if (!command_line->HasSwitch(switches::kDisableGpuDriverBugWorkarounds)) {
545 gpu_driver_bug_list_string = gpu::kGpuDriverBugListJson;
547 InitializeImpl(gpu_blacklist_string,
548 gpu_driver_bug_list_string,
549 gpu_info);
551 if (command_line->HasSwitch(switches::kSingleProcess) ||
552 command_line->HasSwitch(switches::kInProcessGPU)) {
553 command_line->AppendSwitch(switches::kDisableGpuWatchdog);
554 AppendGpuCommandLine(command_line);
558 void GpuDataManagerImplPrivate::UpdateGpuInfoHelper() {
559 GetContentClient()->SetGpuInfo(gpu_info_);
561 if (gpu_blacklist_) {
562 std::set<int> features = gpu_blacklist_->MakeDecision(
563 gpu::GpuControlList::kOsAny, std::string(), gpu_info_);
564 if (update_histograms_)
565 UpdateStats(gpu_info_, gpu_blacklist_.get(), features);
567 UpdateBlacklistedFeatures(features);
569 if (gpu_driver_bug_list_) {
570 gpu_driver_bugs_ = gpu_driver_bug_list_->MakeDecision(
571 gpu::GpuControlList::kOsAny, std::string(), gpu_info_);
573 disabled_extensions_ =
574 base::JoinString(gpu_driver_bug_list_->GetDisabledExtensions(), " ");
576 gpu::GpuDriverBugList::AppendWorkaroundsFromCommandLine(
577 &gpu_driver_bugs_, *base::CommandLine::ForCurrentProcess());
579 // We have to update GpuFeatureType before notify all the observers.
580 NotifyGpuInfoUpdate();
583 void GpuDataManagerImplPrivate::UpdateGpuInfo(const gpu::GPUInfo& gpu_info) {
584 // No further update of gpu_info if falling back to SwiftShader.
585 if (use_swiftshader_ || ShouldUseWarp())
586 return;
588 bool was_info_available = IsCompleteGpuInfoAvailable();
589 gpu::MergeGPUInfo(&gpu_info_, gpu_info);
590 if (IsCompleteGpuInfoAvailable()) {
591 complete_gpu_info_already_requested_ = true;
592 } else if (was_info_available) {
593 // Allow future requests to go through properly.
594 complete_gpu_info_already_requested_ = false;
597 UpdateGpuInfoHelper();
600 void GpuDataManagerImplPrivate::UpdateVideoMemoryUsageStats(
601 const GPUVideoMemoryUsageStats& video_memory_usage_stats) {
602 GpuDataManagerImpl::UnlockedSession session(owner_);
603 observer_list_->Notify(FROM_HERE,
604 &GpuDataManagerObserver::OnVideoMemoryUsageStatsUpdate,
605 video_memory_usage_stats);
608 void GpuDataManagerImplPrivate::AppendRendererCommandLine(
609 base::CommandLine* command_line) const {
610 DCHECK(command_line);
612 if (ShouldDisableAcceleratedVideoDecode(command_line))
613 command_line->AppendSwitch(switches::kDisableAcceleratedVideoDecode);
614 #if defined(ENABLE_WEBRTC)
615 if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE) &&
616 !command_line->HasSwitch(switches::kDisableWebRtcHWEncoding))
617 command_line->AppendSwitch(switches::kDisableWebRtcHWEncoding);
618 #endif
620 #if defined(USE_AURA)
621 if (!CanUseGpuBrowserCompositor())
622 command_line->AppendSwitch(switches::kDisableGpuCompositing);
623 #endif
626 void GpuDataManagerImplPrivate::AppendGpuCommandLine(
627 base::CommandLine* command_line) const {
628 DCHECK(command_line);
630 std::string use_gl =
631 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
632 switches::kUseGL);
633 base::FilePath swiftshader_path =
634 base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
635 switches::kSwiftShaderPath);
636 if (gpu_driver_bugs_.find(gpu::DISABLE_D3D11) != gpu_driver_bugs_.end())
637 command_line->AppendSwitch(switches::kDisableD3D11);
638 if (use_swiftshader_) {
639 command_line->AppendSwitchASCII(switches::kUseGL, "swiftshader");
640 if (swiftshader_path.empty())
641 swiftshader_path = swiftshader_path_;
642 } else if ((IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL) ||
643 IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING) ||
644 IsFeatureBlacklisted(
645 gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS)) &&
646 (use_gl == "any")) {
647 command_line->AppendSwitchASCII(
648 switches::kUseGL, gfx::kGLImplementationOSMesaName);
649 } else if (!use_gl.empty()) {
650 command_line->AppendSwitchASCII(switches::kUseGL, use_gl);
652 if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus())
653 command_line->AppendSwitchASCII(switches::kSupportsDualGpus, "true");
654 else
655 command_line->AppendSwitchASCII(switches::kSupportsDualGpus, "false");
657 if (!swiftshader_path.empty()) {
658 command_line->AppendSwitchPath(switches::kSwiftShaderPath,
659 swiftshader_path);
662 if (!gpu_driver_bugs_.empty()) {
663 command_line->AppendSwitchASCII(switches::kGpuDriverBugWorkarounds,
664 IntSetToString(gpu_driver_bugs_));
667 if (!disabled_extensions_.empty()) {
668 command_line->AppendSwitchASCII(switches::kDisableGLExtensions,
669 disabled_extensions_);
672 if (ShouldDisableAcceleratedVideoDecode(command_line)) {
673 command_line->AppendSwitch(switches::kDisableAcceleratedVideoDecode);
675 #if defined(ENABLE_WEBRTC)
676 if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE) &&
677 !command_line->HasSwitch(switches::kDisableWebRtcHWEncoding)) {
678 command_line->AppendSwitch(switches::kDisableWebRtcHWEncoding);
680 #endif
682 // Pass GPU and driver information to GPU process. We try to avoid full GPU
683 // info collection at GPU process startup, but we need gpu vendor_id,
684 // device_id, driver_vendor, driver_version for deciding whether we need to
685 // collect full info (on Linux) and for crash reporting purpose.
686 command_line->AppendSwitchASCII(switches::kGpuVendorID,
687 base::StringPrintf("0x%04x", gpu_info_.gpu.vendor_id));
688 command_line->AppendSwitchASCII(switches::kGpuDeviceID,
689 base::StringPrintf("0x%04x", gpu_info_.gpu.device_id));
690 command_line->AppendSwitchASCII(switches::kGpuDriverVendor,
691 gpu_info_.driver_vendor);
692 command_line->AppendSwitchASCII(switches::kGpuDriverVersion,
693 gpu_info_.driver_version);
695 if (ShouldUseWarp() && !command_line->HasSwitch(switches::kUseANGLE)) {
696 command_line->AppendSwitchASCII(switches::kUseANGLE,
697 gfx::kANGLEImplementationWARPName);
701 void GpuDataManagerImplPrivate::AppendPluginCommandLine(
702 base::CommandLine* command_line) const {
703 DCHECK(command_line);
705 #if defined(OS_MACOSX)
706 // TODO(jbauman): Add proper blacklist support for core animation plugins so
707 // special-casing this video card won't be necessary. See
708 // http://crbug.com/134015
709 if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING)) {
710 if (!command_line->HasSwitch(
711 switches::kDisableCoreAnimationPlugins))
712 command_line->AppendSwitch(
713 switches::kDisableCoreAnimationPlugins);
715 #endif
718 void GpuDataManagerImplPrivate::UpdateRendererWebPrefs(
719 WebPreferences* prefs) const {
720 DCHECK(prefs);
722 if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL)) {
723 prefs->experimental_webgl_enabled = false;
724 prefs->pepper_3d_enabled = false;
726 if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH3D))
727 prefs->flash_3d_enabled = false;
728 if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D)) {
729 prefs->flash_stage3d_enabled = false;
730 prefs->flash_stage3d_baseline_enabled = false;
732 if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE))
733 prefs->flash_stage3d_baseline_enabled = false;
734 if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS))
735 prefs->accelerated_2d_canvas_enabled = false;
736 // TODO(senorblanco): The renderer shouldn't have an extra setting
737 // for this, but should rely on extension availability.
738 // Note that |gl_multisampling_enabled| only affects the decoder's
739 // default framebuffer allocation, which does not support
740 // multisampled_render_to_texture, only msaa with explicit resolve.
741 if (IsDriverBugWorkaroundActive(
742 gpu::DISABLE_CHROMIUM_FRAMEBUFFER_MULTISAMPLE) ||
743 (IsDriverBugWorkaroundActive(gpu::DISABLE_MULTIMONITOR_MULTISAMPLING) &&
744 display_count_ > 1))
745 prefs->gl_multisampling_enabled = false;
747 #if defined(USE_AURA)
748 if (!CanUseGpuBrowserCompositor()) {
749 prefs->accelerated_2d_canvas_enabled = false;
750 prefs->pepper_3d_enabled = false;
752 #endif
754 const base::CommandLine* command_line =
755 base::CommandLine::ForCurrentProcess();
756 if (!ShouldDisableAcceleratedVideoDecode(command_line) &&
757 !command_line->HasSwitch(switches::kDisableAcceleratedVideoDecode)) {
758 prefs->pepper_accelerated_video_decode_enabled = true;
762 void GpuDataManagerImplPrivate::DisableHardwareAcceleration() {
763 card_blacklisted_ = true;
765 for (int i = 0; i < gpu::NUMBER_OF_GPU_FEATURE_TYPES; ++i)
766 blacklisted_features_.insert(i);
768 EnableWarpIfNecessary();
769 EnableSwiftShaderIfNecessary();
770 NotifyGpuInfoUpdate();
773 std::string GpuDataManagerImplPrivate::GetBlacklistVersion() const {
774 if (gpu_blacklist_)
775 return gpu_blacklist_->version();
776 return "0";
779 std::string GpuDataManagerImplPrivate::GetDriverBugListVersion() const {
780 if (gpu_driver_bug_list_)
781 return gpu_driver_bug_list_->version();
782 return "0";
785 void GpuDataManagerImplPrivate::GetBlacklistReasons(
786 base::ListValue* reasons) const {
787 if (gpu_blacklist_)
788 gpu_blacklist_->GetReasons(reasons, "disabledFeatures");
789 if (gpu_driver_bug_list_)
790 gpu_driver_bug_list_->GetReasons(reasons, "workarounds");
793 std::vector<std::string>
794 GpuDataManagerImplPrivate::GetDriverBugWorkarounds() const {
795 std::vector<std::string> workarounds;
796 for (std::set<int>::const_iterator it = gpu_driver_bugs_.begin();
797 it != gpu_driver_bugs_.end(); ++it) {
798 workarounds.push_back(
799 gpu::GpuDriverBugWorkaroundTypeToString(
800 static_cast<gpu::GpuDriverBugWorkaroundType>(*it)));
802 return workarounds;
805 void GpuDataManagerImplPrivate::AddLogMessage(
806 int level, const std::string& header, const std::string& message) {
807 log_messages_.push_back(LogMessage(level, header, message));
810 void GpuDataManagerImplPrivate::ProcessCrashed(
811 base::TerminationStatus exit_code) {
812 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
813 // Unretained is ok, because it's posted to UI thread, the thread
814 // where the singleton GpuDataManagerImpl lives until the end.
815 BrowserThread::PostTask(
816 BrowserThread::UI,
817 FROM_HERE,
818 base::Bind(&GpuDataManagerImpl::ProcessCrashed,
819 base::Unretained(owner_),
820 exit_code));
821 return;
824 gpu_info_.process_crash_count = GpuProcessHost::gpu_crash_count();
825 GpuDataManagerImpl::UnlockedSession session(owner_);
826 observer_list_->Notify(
827 FROM_HERE, &GpuDataManagerObserver::OnGpuProcessCrashed, exit_code);
831 base::ListValue* GpuDataManagerImplPrivate::GetLogMessages() const {
832 base::ListValue* value = new base::ListValue;
833 for (size_t ii = 0; ii < log_messages_.size(); ++ii) {
834 base::DictionaryValue* dict = new base::DictionaryValue();
835 dict->SetInteger("level", log_messages_[ii].level);
836 dict->SetString("header", log_messages_[ii].header);
837 dict->SetString("message", log_messages_[ii].message);
838 value->Append(dict);
840 return value;
843 void GpuDataManagerImplPrivate::HandleGpuSwitch() {
844 GpuDataManagerImpl::UnlockedSession session(owner_);
845 // Notify observers in the browser process.
846 ui::GpuSwitchingManager::GetInstance()->NotifyGpuSwitched();
847 // Pass the notification to the GPU process to notify observers there.
848 GpuProcessHost::SendOnIO(
849 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
850 CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH,
851 new GpuMsg_GpuSwitched);
854 bool GpuDataManagerImplPrivate::UpdateActiveGpu(
855 uint32 vendor_id, uint32 device_id) {
856 if (gpu_info_.gpu.vendor_id == vendor_id &&
857 gpu_info_.gpu.device_id == device_id) {
858 // The primary GPU is active.
859 if (gpu_info_.gpu.active)
860 return false;
861 gpu_info_.gpu.active = true;
862 for (size_t ii = 0; ii < gpu_info_.secondary_gpus.size(); ++ii)
863 gpu_info_.secondary_gpus[ii].active = false;
864 } else {
865 // A secondary GPU is active.
866 for (size_t ii = 0; ii < gpu_info_.secondary_gpus.size(); ++ii) {
867 if (gpu_info_.secondary_gpus[ii].vendor_id == vendor_id &&
868 gpu_info_.secondary_gpus[ii].device_id == device_id) {
869 if (gpu_info_.secondary_gpus[ii].active)
870 return false;
871 gpu_info_.secondary_gpus[ii].active = true;
872 } else {
873 gpu_info_.secondary_gpus[ii].active = false;
876 gpu_info_.gpu.active = false;
878 UpdateGpuInfoHelper();
879 return true;
882 bool GpuDataManagerImplPrivate::CanUseGpuBrowserCompositor() const {
883 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
884 switches::kDisableGpuCompositing))
885 return false;
886 if (ShouldUseWarp())
887 return true;
888 if (ShouldUseSwiftShader())
889 return false;
890 if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING))
891 return false;
892 return true;
896 bool GpuDataManagerImplPrivate::ShouldDisableAcceleratedVideoDecode(
897 const base::CommandLine* command_line) const {
898 // Make sure that we initialize the experiment first to make sure that
899 // statistics are bucket correctly in all cases.
900 // This experiment is temporary and will be removed once enough data
901 // to resolve crbug/442039 has been collected.
902 const std::string group_name = base::FieldTrialList::FindFullName(
903 "DisableAcceleratedVideoDecode");
904 if (command_line->HasSwitch(switches::kDisableAcceleratedVideoDecode)) {
905 // It was already disabled on the command line.
906 return false;
908 if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE))
909 return true;
910 if (group_name == "Disabled")
911 return true;
912 return false;
915 void GpuDataManagerImplPrivate::GetDisabledExtensions(
916 std::string* disabled_extensions) const {
917 DCHECK(disabled_extensions);
919 *disabled_extensions = disabled_extensions_;
922 void GpuDataManagerImplPrivate::BlockDomainFrom3DAPIs(
923 const GURL& url, GpuDataManagerImpl::DomainGuilt guilt) {
924 BlockDomainFrom3DAPIsAtTime(url, guilt, base::Time::Now());
927 bool GpuDataManagerImplPrivate::Are3DAPIsBlocked(const GURL& url,
928 int render_process_id,
929 int render_view_id,
930 ThreeDAPIType requester) {
931 bool blocked = Are3DAPIsBlockedAtTime(url, base::Time::Now()) !=
932 GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED;
933 if (blocked) {
934 // Unretained is ok, because it's posted to UI thread, the thread
935 // where the singleton GpuDataManagerImpl lives until the end.
936 BrowserThread::PostTask(
937 BrowserThread::UI, FROM_HERE,
938 base::Bind(&GpuDataManagerImpl::Notify3DAPIBlocked,
939 base::Unretained(owner_), url, render_process_id,
940 render_view_id, requester));
943 return blocked;
946 void GpuDataManagerImplPrivate::DisableDomainBlockingFor3DAPIsForTesting() {
947 domain_blocking_enabled_ = false;
950 // static
951 GpuDataManagerImplPrivate* GpuDataManagerImplPrivate::Create(
952 GpuDataManagerImpl* owner) {
953 return new GpuDataManagerImplPrivate(owner);
956 GpuDataManagerImplPrivate::GpuDataManagerImplPrivate(
957 GpuDataManagerImpl* owner)
958 : complete_gpu_info_already_requested_(false),
959 observer_list_(new GpuDataManagerObserverList),
960 use_swiftshader_(false),
961 use_warp_(false),
962 card_blacklisted_(false),
963 update_histograms_(true),
964 window_count_(0),
965 domain_blocking_enabled_(true),
966 owner_(owner),
967 display_count_(0),
968 gpu_process_accessible_(true),
969 finalized_(false) {
970 DCHECK(owner_);
971 const base::CommandLine* command_line =
972 base::CommandLine::ForCurrentProcess();
973 if (command_line->HasSwitch(switches::kDisableGpu))
974 DisableHardwareAcceleration();
976 #if defined(OS_MACOSX)
977 CGGetActiveDisplayList (0, NULL, &display_count_);
978 CGDisplayRegisterReconfigurationCallback(DisplayReconfigCallback, owner_);
979 #endif // OS_MACOSX
981 // For testing only.
982 if (command_line->HasSwitch(switches::kDisableDomainBlockingFor3DAPIs)) {
983 domain_blocking_enabled_ = false;
987 GpuDataManagerImplPrivate::~GpuDataManagerImplPrivate() {
988 #if defined(OS_MACOSX)
989 CGDisplayRemoveReconfigurationCallback(DisplayReconfigCallback, owner_);
990 #endif
993 void GpuDataManagerImplPrivate::InitializeImpl(
994 const std::string& gpu_blacklist_json,
995 const std::string& gpu_driver_bug_list_json,
996 const gpu::GPUInfo& gpu_info) {
997 const bool log_gpu_control_list_decisions =
998 base::CommandLine::ForCurrentProcess()->HasSwitch(
999 switches::kLogGpuControlListDecisions);
1001 if (!gpu_blacklist_json.empty()) {
1002 gpu_blacklist_.reset(gpu::GpuBlacklist::Create());
1003 if (log_gpu_control_list_decisions)
1004 gpu_blacklist_->enable_control_list_logging("gpu_blacklist");
1005 bool success = gpu_blacklist_->LoadList(
1006 gpu_blacklist_json, gpu::GpuControlList::kCurrentOsOnly);
1007 DCHECK(success);
1009 if (!gpu_driver_bug_list_json.empty()) {
1010 gpu_driver_bug_list_.reset(gpu::GpuDriverBugList::Create());
1011 if (log_gpu_control_list_decisions)
1012 gpu_driver_bug_list_->enable_control_list_logging("gpu_driver_bug_list");
1013 bool success = gpu_driver_bug_list_->LoadList(
1014 gpu_driver_bug_list_json, gpu::GpuControlList::kCurrentOsOnly);
1015 DCHECK(success);
1018 gpu_info_ = gpu_info;
1019 UpdateGpuInfo(gpu_info);
1020 UpdateGpuSwitchingManager(gpu_info);
1021 UpdatePreliminaryBlacklistedFeatures();
1024 void GpuDataManagerImplPrivate::UpdateBlacklistedFeatures(
1025 const std::set<int>& features) {
1026 blacklisted_features_ = features;
1028 // Force disable using the GPU for these features, even if they would
1029 // otherwise be allowed.
1030 if (card_blacklisted_) {
1031 blacklisted_features_.insert(gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING);
1032 blacklisted_features_.insert(gpu::GPU_FEATURE_TYPE_WEBGL);
1035 EnableWarpIfNecessary();
1036 EnableSwiftShaderIfNecessary();
1039 void GpuDataManagerImplPrivate::UpdatePreliminaryBlacklistedFeatures() {
1040 preliminary_blacklisted_features_ = blacklisted_features_;
1043 void GpuDataManagerImplPrivate::UpdateGpuSwitchingManager(
1044 const gpu::GPUInfo& gpu_info) {
1045 // The vendor IDs might be 0 on non-PCI devices (like Android), but
1046 // the length of the vector is all we care about in most cases.
1047 std::vector<uint32> vendor_ids;
1048 vendor_ids.push_back(gpu_info.gpu.vendor_id);
1049 for (const auto& device : gpu_info.secondary_gpus) {
1050 vendor_ids.push_back(device.vendor_id);
1052 ui::GpuSwitchingManager::GetInstance()->SetGpuVendorIds(vendor_ids);
1054 if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus()) {
1055 if (gpu_driver_bugs_.count(gpu::FORCE_DISCRETE_GPU) == 1)
1056 ui::GpuSwitchingManager::GetInstance()->ForceUseOfDiscreteGpu();
1057 else if (gpu_driver_bugs_.count(gpu::FORCE_INTEGRATED_GPU) == 1)
1058 ui::GpuSwitchingManager::GetInstance()->ForceUseOfIntegratedGpu();
1062 void GpuDataManagerImplPrivate::NotifyGpuInfoUpdate() {
1063 observer_list_->Notify(FROM_HERE, &GpuDataManagerObserver::OnGpuInfoUpdate);
1066 void GpuDataManagerImplPrivate::EnableSwiftShaderIfNecessary() {
1067 if (ShouldUseWarp())
1068 return;
1070 if (!GpuAccessAllowed(NULL) ||
1071 blacklisted_features_.count(gpu::GPU_FEATURE_TYPE_WEBGL)) {
1072 if (!swiftshader_path_.empty() &&
1073 !base::CommandLine::ForCurrentProcess()->HasSwitch(
1074 switches::kDisableSoftwareRasterizer))
1075 use_swiftshader_ = true;
1079 void GpuDataManagerImplPrivate::EnableWarpIfNecessary() {
1080 #if defined(OS_WIN)
1081 if (use_warp_)
1082 return;
1083 // We should only use WARP if we are unable to use the regular GPU for
1084 // compositing, and if we in Metro mode.
1085 use_warp_ = base::CommandLine::ForCurrentProcess()->HasSwitch(
1086 switches::kViewerConnect) &&
1087 !CanUseGpuBrowserCompositor();
1088 #endif
1091 void GpuDataManagerImplPrivate::ForceWarpModeForTesting() {
1092 use_warp_ = true;
1095 std::string GpuDataManagerImplPrivate::GetDomainFromURL(
1096 const GURL& url) const {
1097 // For the moment, we just use the host, or its IP address, as the
1098 // entry in the set, rather than trying to figure out the top-level
1099 // domain. This does mean that a.foo.com and b.foo.com will be
1100 // treated independently in the blocking of a given domain, but it
1101 // would require a third-party library to reliably figure out the
1102 // top-level domain from a URL.
1103 if (!url.has_host()) {
1104 return std::string();
1107 return url.host();
1110 void GpuDataManagerImplPrivate::BlockDomainFrom3DAPIsAtTime(
1111 const GURL& url,
1112 GpuDataManagerImpl::DomainGuilt guilt,
1113 base::Time at_time) {
1114 if (!domain_blocking_enabled_)
1115 return;
1117 std::string domain = GetDomainFromURL(url);
1119 DomainBlockEntry& entry = blocked_domains_[domain];
1120 entry.last_guilt = guilt;
1121 timestamps_of_gpu_resets_.push_back(at_time);
1124 GpuDataManagerImpl::DomainBlockStatus
1125 GpuDataManagerImplPrivate::Are3DAPIsBlockedAtTime(
1126 const GURL& url, base::Time at_time) const {
1127 if (!domain_blocking_enabled_)
1128 return GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED;
1130 // Note: adjusting the policies in this code will almost certainly
1131 // require adjusting the associated unit tests.
1132 std::string domain = GetDomainFromURL(url);
1134 DomainBlockMap::const_iterator iter = blocked_domains_.find(domain);
1135 if (iter != blocked_domains_.end()) {
1136 // Err on the side of caution, and assume that if a particular
1137 // domain shows up in the block map, it's there for a good
1138 // reason and don't let its presence there automatically expire.
1140 UMA_HISTOGRAM_ENUMERATION("GPU.BlockStatusForClient3DAPIs",
1141 BLOCK_STATUS_SPECIFIC_DOMAIN_BLOCKED,
1142 BLOCK_STATUS_MAX);
1144 return GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_BLOCKED;
1147 // Look at the timestamps of the recent GPU resets to see if there are
1148 // enough within the threshold which would cause us to blacklist all
1149 // domains. This doesn't need to be overly precise -- if time goes
1150 // backward due to a system clock adjustment, that's fine.
1152 // TODO(kbr): make this pay attention to the TDR thresholds in the
1153 // Windows registry, but make sure it continues to be testable.
1155 std::list<base::Time>::iterator iter = timestamps_of_gpu_resets_.begin();
1156 int num_resets_within_timeframe = 0;
1157 while (iter != timestamps_of_gpu_resets_.end()) {
1158 base::Time time = *iter;
1159 base::TimeDelta delta_t = at_time - time;
1161 // If this entry has "expired", just remove it.
1162 if (delta_t.InMilliseconds() > kBlockAllDomainsMs) {
1163 iter = timestamps_of_gpu_resets_.erase(iter);
1164 continue;
1167 ++num_resets_within_timeframe;
1168 ++iter;
1171 if (num_resets_within_timeframe >= kNumResetsWithinDuration) {
1172 UMA_HISTOGRAM_ENUMERATION("GPU.BlockStatusForClient3DAPIs",
1173 BLOCK_STATUS_ALL_DOMAINS_BLOCKED,
1174 BLOCK_STATUS_MAX);
1176 return GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_ALL_DOMAINS_BLOCKED;
1180 UMA_HISTOGRAM_ENUMERATION("GPU.BlockStatusForClient3DAPIs",
1181 BLOCK_STATUS_NOT_BLOCKED,
1182 BLOCK_STATUS_MAX);
1184 return GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED;
1187 int64 GpuDataManagerImplPrivate::GetBlockAllDomainsDurationInMs() const {
1188 return kBlockAllDomainsMs;
1191 void GpuDataManagerImplPrivate::Notify3DAPIBlocked(const GURL& url,
1192 int render_process_id,
1193 int render_view_id,
1194 ThreeDAPIType requester) {
1195 GpuDataManagerImpl::UnlockedSession session(owner_);
1196 observer_list_->Notify(FROM_HERE, &GpuDataManagerObserver::DidBlock3DAPIs,
1197 url, render_process_id, render_view_id, requester);
1200 void GpuDataManagerImplPrivate::OnGpuProcessInitFailure() {
1201 gpu_process_accessible_ = false;
1202 gpu_info_.context_info_state = gpu::kCollectInfoFatalFailure;
1203 #if defined(OS_WIN)
1204 gpu_info_.dx_diagnostics_info_state = gpu::kCollectInfoFatalFailure;
1205 #endif
1206 complete_gpu_info_already_requested_ = true;
1207 // Some observers might be waiting.
1208 NotifyGpuInfoUpdate();
1211 } // namespace content