Remove PlatformFile from profile_browsertest
[chromium-blink-merge.git] / content / browser / gpu / gpu_data_manager_impl_private.cc
blob26c1775ab641e86a753cc42df000a92466e7792a
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/debug/trace_event.h"
11 #include "base/metrics/field_trial.h"
12 #include "base/metrics/histogram.h"
13 #include "base/metrics/sparse_histogram.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/stringprintf.h"
16 #include "base/sys_info.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 "gpu/command_buffer/service/gpu_switches.h"
27 #include "gpu/config/gpu_control_list_jsons.h"
28 #include "gpu/config/gpu_driver_bug_workaround_type.h"
29 #include "gpu/config/gpu_feature_type.h"
30 #include "gpu/config/gpu_info_collector.h"
31 #include "gpu/config/gpu_util.h"
32 #include "ui/base/ui_base_switches.h"
33 #include "ui/gl/gl_implementation.h"
34 #include "ui/gl/gl_switches.h"
35 #include "ui/gl/gpu_switching_manager.h"
36 #include "webkit/common/webpreferences.h"
38 #if defined(OS_MACOSX)
39 #include <ApplicationServices/ApplicationServices.h>
40 #endif // OS_MACOSX
41 #if defined(OS_WIN)
42 #include "base/win/windows_version.h"
43 #endif // OS_WIN
44 #if defined(OS_ANDROID)
45 #include "ui/gfx/android/device_display_info.h"
46 #endif // OS_ANDROID
48 namespace content {
50 namespace {
52 enum GpuFeatureStatus {
53 kGpuFeatureEnabled = 0,
54 kGpuFeatureBlacklisted = 1,
55 kGpuFeatureDisabled = 2, // disabled by user but not blacklisted
56 kGpuFeatureNumStatus
59 #if defined(OS_WIN)
61 enum WinSubVersion {
62 kWinOthers = 0,
63 kWinXP,
64 kWinVista,
65 kWin7,
66 kWin8,
67 kNumWinSubVersions
70 int GetGpuBlacklistHistogramValueWin(GpuFeatureStatus status) {
71 static WinSubVersion sub_version = kNumWinSubVersions;
72 if (sub_version == kNumWinSubVersions) {
73 sub_version = kWinOthers;
74 std::string version_str = base::SysInfo::OperatingSystemVersion();
75 size_t pos = version_str.find_first_not_of("0123456789.");
76 if (pos != std::string::npos)
77 version_str = version_str.substr(0, pos);
78 Version os_version(version_str);
79 if (os_version.IsValid() && os_version.components().size() >= 2) {
80 const std::vector<uint16>& version_numbers = os_version.components();
81 if (version_numbers[0] == 5)
82 sub_version = kWinXP;
83 else if (version_numbers[0] == 6 && version_numbers[1] == 0)
84 sub_version = kWinVista;
85 else if (version_numbers[0] == 6 && version_numbers[1] == 1)
86 sub_version = kWin7;
87 else if (version_numbers[0] == 6 && version_numbers[1] == 2)
88 sub_version = kWin8;
91 int entry_index = static_cast<int>(sub_version) * kGpuFeatureNumStatus;
92 switch (status) {
93 case kGpuFeatureEnabled:
94 break;
95 case kGpuFeatureBlacklisted:
96 entry_index++;
97 break;
98 case kGpuFeatureDisabled:
99 entry_index += 2;
100 break;
102 return entry_index;
104 #endif // OS_WIN
106 // Send UMA histograms about the enabled features and GPU properties.
107 void UpdateStats(const gpu::GPUInfo& gpu_info,
108 const gpu::GpuBlacklist* blacklist,
109 const std::set<int>& blacklisted_features) {
110 uint32 max_entry_id = blacklist->max_entry_id();
111 if (max_entry_id == 0) {
112 // GPU Blacklist was not loaded. No need to go further.
113 return;
116 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
117 bool disabled = false;
119 // Use entry 0 to capture the total number of times that data
120 // was recorded in this histogram in order to have a convenient
121 // denominator to compute blacklist percentages for the rest of the
122 // entries.
123 UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResultsPerEntry",
124 0, max_entry_id + 1);
126 if (blacklisted_features.size() != 0) {
127 std::vector<uint32> flag_entries;
128 blacklist->GetDecisionEntries(&flag_entries, disabled);
129 DCHECK_GT(flag_entries.size(), 0u);
130 for (size_t i = 0; i < flag_entries.size(); ++i) {
131 UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResultsPerEntry",
132 flag_entries[i], max_entry_id + 1);
136 // This counts how many users are affected by a disabled entry - this allows
137 // us to understand the impact of an entry before enable it.
138 std::vector<uint32> flag_disabled_entries;
139 disabled = true;
140 blacklist->GetDecisionEntries(&flag_disabled_entries, disabled);
141 for (size_t i = 0; i < flag_disabled_entries.size(); ++i) {
142 UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResultsPerDisabledEntry",
143 flag_disabled_entries[i], max_entry_id + 1);
146 const gpu::GpuFeatureType kGpuFeatures[] = {
147 gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS,
148 gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING,
149 gpu::GPU_FEATURE_TYPE_WEBGL
151 const std::string kGpuBlacklistFeatureHistogramNames[] = {
152 "GPU.BlacklistFeatureTestResults.Accelerated2dCanvas",
153 "GPU.BlacklistFeatureTestResults.AcceleratedCompositing",
154 "GPU.BlacklistFeatureTestResults.Webgl",
156 const bool kGpuFeatureUserFlags[] = {
157 command_line.HasSwitch(switches::kDisableAccelerated2dCanvas),
158 command_line.HasSwitch(switches::kDisableAcceleratedCompositing),
159 command_line.HasSwitch(switches::kDisableExperimentalWebGL),
161 #if defined(OS_WIN)
162 const std::string kGpuBlacklistFeatureHistogramNamesWin[] = {
163 "GPU.BlacklistFeatureTestResultsWindows.Accelerated2dCanvas",
164 "GPU.BlacklistFeatureTestResultsWindows.AcceleratedCompositing",
165 "GPU.BlacklistFeatureTestResultsWindows.Webgl",
167 #endif
168 const size_t kNumFeatures =
169 sizeof(kGpuFeatures) / sizeof(gpu::GpuFeatureType);
170 for (size_t i = 0; i < kNumFeatures; ++i) {
171 // We can't use UMA_HISTOGRAM_ENUMERATION here because the same name is
172 // expected if the macro is used within a loop.
173 GpuFeatureStatus value = kGpuFeatureEnabled;
174 if (blacklisted_features.count(kGpuFeatures[i]))
175 value = kGpuFeatureBlacklisted;
176 else if (kGpuFeatureUserFlags[i])
177 value = kGpuFeatureDisabled;
178 base::HistogramBase* histogram_pointer = base::LinearHistogram::FactoryGet(
179 kGpuBlacklistFeatureHistogramNames[i],
180 1, kGpuFeatureNumStatus, kGpuFeatureNumStatus + 1,
181 base::HistogramBase::kUmaTargetedHistogramFlag);
182 histogram_pointer->Add(value);
183 #if defined(OS_WIN)
184 histogram_pointer = base::LinearHistogram::FactoryGet(
185 kGpuBlacklistFeatureHistogramNamesWin[i],
186 1, kNumWinSubVersions * kGpuFeatureNumStatus,
187 kNumWinSubVersions * kGpuFeatureNumStatus + 1,
188 base::HistogramBase::kUmaTargetedHistogramFlag);
189 histogram_pointer->Add(GetGpuBlacklistHistogramValueWin(value));
190 #endif
193 UMA_HISTOGRAM_SPARSE_SLOWLY("GPU.GLResetNotificationStrategy",
194 gpu_info.gl_reset_notification_strategy);
197 // Combine the integers into a string, seperated by ','.
198 std::string IntSetToString(const std::set<int>& list) {
199 std::string rt;
200 for (std::set<int>::const_iterator it = list.begin();
201 it != list.end(); ++it) {
202 if (!rt.empty())
203 rt += ",";
204 rt += base::IntToString(*it);
206 return rt;
209 #if defined(OS_MACOSX)
210 void DisplayReconfigCallback(CGDirectDisplayID display,
211 CGDisplayChangeSummaryFlags flags,
212 void* gpu_data_manager) {
213 if (flags == kCGDisplayBeginConfigurationFlag)
214 return; // This call contains no information about the display change
216 GpuDataManagerImpl* manager =
217 reinterpret_cast<GpuDataManagerImpl*>(gpu_data_manager);
218 DCHECK(manager);
220 uint32_t displayCount;
221 CGGetActiveDisplayList(0, NULL, &displayCount);
223 bool fireGpuSwitch = flags & kCGDisplayAddFlag;
225 if (displayCount != manager->GetDisplayCount()) {
226 manager->SetDisplayCount(displayCount);
227 fireGpuSwitch = true;
230 if (fireGpuSwitch)
231 manager->HandleGpuSwitch();
233 #endif // OS_MACOSX
235 #if defined(OS_ANDROID)
236 void ApplyAndroidWorkarounds(const gpu::GPUInfo& gpu_info,
237 CommandLine* command_line) {
238 std::string vendor(StringToLowerASCII(gpu_info.gl_vendor));
239 std::string renderer(StringToLowerASCII(gpu_info.gl_renderer));
240 bool is_img =
241 gpu_info.gl_vendor.find("Imagination") != std::string::npos;
243 gfx::DeviceDisplayInfo info;
244 int default_tile_size = 256;
246 // TODO(epenner): Now that this is somewhat generic, maybe we can
247 // unify this for all platforms (http://crbug.com/159524)
249 bool real_size_supported = true;
250 int display_width = info.GetPhysicalDisplayWidth();
251 int display_height = info.GetPhysicalDisplayHeight();
252 if (display_width == 0 || display_height == 0) {
253 real_size_supported = false;
254 display_width = info.GetDisplayWidth();
255 display_height = info.GetDisplayHeight();
258 int portrait_width = std::min(display_width, display_height);
259 int landscape_width = std::max(display_width, display_height);
261 if (real_size_supported) {
262 // Maximum HD dimensions should be 768x1280
263 // Maximum FHD dimensions should be 1200x1920
264 if (portrait_width > 768 || landscape_width > 1280)
265 default_tile_size = 384;
266 if (portrait_width > 1200 || landscape_width > 1920)
267 default_tile_size = 512;
269 // Adjust for some resolutions that barely straddle an extra
270 // tile when in portrait mode. This helps worst case scroll/raster
271 // by not needing a full extra tile for each row.
272 if (default_tile_size == 256 && portrait_width == 768)
273 default_tile_size += 32;
274 if (default_tile_size == 384 && portrait_width == 1200)
275 default_tile_size += 32;
276 } else {
277 // We don't know the exact resolution due to screen controls etc.
278 // So this just estimates the values above using tile counts.
279 int numTiles = (display_width * display_height) / (256 * 256);
280 if (numTiles > 16)
281 default_tile_size = 384;
282 if (numTiles >= 40)
283 default_tile_size = 512;
286 // IMG: Fast async texture uploads only work with non-power-of-two,
287 // but still multiple-of-eight sizes.
288 // http://crbug.com/168099
289 if (is_img)
290 default_tile_size -= 8;
292 // Set the command line if it isn't already set and we changed
293 // the default tile size.
294 if (default_tile_size != 256 &&
295 !command_line->HasSwitch(switches::kDefaultTileWidth) &&
296 !command_line->HasSwitch(switches::kDefaultTileHeight)) {
297 std::stringstream size;
298 size << default_tile_size;
299 command_line->AppendSwitchASCII(
300 switches::kDefaultTileWidth, size.str());
301 command_line->AppendSwitchASCII(
302 switches::kDefaultTileHeight, size.str());
305 #endif // OS_ANDROID
307 // Overwrite force gpu workaround if a commandline switch exists.
308 void AdjustGpuSwitchingOption(std::set<int>* workarounds) {
309 DCHECK(workarounds);
310 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
311 std::string option = command_line.GetSwitchValueASCII(
312 switches::kGpuSwitching);
313 if (option == switches::kGpuSwitchingOptionNameForceDiscrete) {
314 workarounds->erase(gpu::FORCE_INTEGRATED_GPU);
315 workarounds->insert(gpu::FORCE_DISCRETE_GPU);
316 } else if (option == switches::kGpuSwitchingOptionNameForceIntegrated) {
317 workarounds->erase(gpu::FORCE_DISCRETE_GPU);
318 workarounds->insert(gpu::FORCE_INTEGRATED_GPU);
322 // Block all domains' use of 3D APIs for this many milliseconds if
323 // approaching a threshold where system stability might be compromised.
324 const int64 kBlockAllDomainsMs = 10000;
325 const int kNumResetsWithinDuration = 1;
327 // Enums for UMA histograms.
328 enum BlockStatusHistogram {
329 BLOCK_STATUS_NOT_BLOCKED,
330 BLOCK_STATUS_SPECIFIC_DOMAIN_BLOCKED,
331 BLOCK_STATUS_ALL_DOMAINS_BLOCKED,
332 BLOCK_STATUS_MAX
335 } // namespace anonymous
337 void GpuDataManagerImplPrivate::InitializeForTesting(
338 const std::string& gpu_blacklist_json,
339 const gpu::GPUInfo& gpu_info) {
340 // This function is for testing only, so disable histograms.
341 update_histograms_ = false;
343 // Prevent all further initialization.
344 finalized_ = true;
346 InitializeImpl(gpu_blacklist_json, std::string(), gpu_info);
349 bool GpuDataManagerImplPrivate::IsFeatureBlacklisted(int feature) const {
350 #if defined(OS_CHROMEOS)
351 if (feature == gpu::GPU_FEATURE_TYPE_PANEL_FITTING &&
352 CommandLine::ForCurrentProcess()->HasSwitch(
353 switches::kDisablePanelFitting)) {
354 return true;
356 #endif // OS_CHROMEOS
357 if (use_swiftshader_) {
358 // Skia's software rendering is probably more efficient than going through
359 // software emulation of the GPU, so use that.
360 if (feature == gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS)
361 return true;
362 return false;
365 return (blacklisted_features_.count(feature) == 1);
368 bool GpuDataManagerImplPrivate::IsDriverBugWorkaroundActive(int feature) const {
369 return (gpu_driver_bugs_.count(feature) == 1);
372 size_t GpuDataManagerImplPrivate::GetBlacklistedFeatureCount() const {
373 if (use_swiftshader_)
374 return 1;
375 return blacklisted_features_.size();
378 void GpuDataManagerImplPrivate::SetDisplayCount(unsigned int display_count) {
379 display_count_ = display_count;
382 unsigned int GpuDataManagerImplPrivate::GetDisplayCount() const {
383 return display_count_;
386 gpu::GPUInfo GpuDataManagerImplPrivate::GetGPUInfo() const {
387 return gpu_info_;
390 void GpuDataManagerImplPrivate::GetGpuProcessHandles(
391 const GpuDataManager::GetGpuProcessHandlesCallback& callback) const {
392 GpuProcessHost::GetProcessHandles(callback);
395 bool GpuDataManagerImplPrivate::GpuAccessAllowed(
396 std::string* reason) const {
397 if (use_swiftshader_)
398 return true;
400 if (!gpu_process_accessible_) {
401 if (reason) {
402 *reason = "GPU process launch failed.";
404 return false;
407 if (card_blacklisted_) {
408 if (reason) {
409 *reason = "GPU access is disabled ";
410 CommandLine* command_line = CommandLine::ForCurrentProcess();
411 if (command_line->HasSwitch(switches::kDisableGpu))
412 *reason += "through commandline switch --disable-gpu.";
413 else
414 *reason += "in chrome://settings.";
416 return false;
419 // We only need to block GPU process if more features are disallowed other
420 // than those in the preliminary gpu feature flags because the latter work
421 // through renderer commandline switches.
422 std::set<int> features = preliminary_blacklisted_features_;
423 gpu::MergeFeatureSets(&features, blacklisted_features_);
424 if (features.size() > preliminary_blacklisted_features_.size()) {
425 if (reason) {
426 *reason = "Features are disabled upon full but not preliminary GPU info.";
428 return false;
431 if (blacklisted_features_.size() == gpu::NUMBER_OF_GPU_FEATURE_TYPES) {
432 // On Linux, we use cached GL strings to make blacklist decsions at browser
433 // startup time. We need to launch the GPU process to validate these
434 // strings even if all features are blacklisted. If all GPU features are
435 // disabled, the GPU process will only initialize GL bindings, create a GL
436 // context, and collect full GPU info.
437 #if !defined(OS_LINUX)
438 if (reason) {
439 *reason = "All GPU features are blacklisted.";
441 return false;
442 #endif
445 return true;
448 void GpuDataManagerImplPrivate::RequestCompleteGpuInfoIfNeeded() {
449 if (complete_gpu_info_already_requested_ || gpu_info_.finalized)
450 return;
451 complete_gpu_info_already_requested_ = true;
453 GpuProcessHost::SendOnIO(
454 #if defined(OS_WIN)
455 GpuProcessHost::GPU_PROCESS_KIND_UNSANDBOXED,
456 #else
457 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
458 #endif
459 CAUSE_FOR_GPU_LAUNCH_GPUDATAMANAGER_REQUESTCOMPLETEGPUINFOIFNEEDED,
460 new GpuMsg_CollectGraphicsInfo());
463 bool GpuDataManagerImplPrivate::IsCompleteGpuInfoAvailable() const {
464 return gpu_info_.finalized;
467 void GpuDataManagerImplPrivate::RequestVideoMemoryUsageStatsUpdate() const {
468 GpuProcessHost::SendOnIO(
469 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
470 CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH,
471 new GpuMsg_GetVideoMemoryUsageStats());
474 bool GpuDataManagerImplPrivate::ShouldUseSwiftShader() const {
475 return use_swiftshader_;
478 void GpuDataManagerImplPrivate::RegisterSwiftShaderPath(
479 const base::FilePath& path) {
480 swiftshader_path_ = path;
481 EnableSwiftShaderIfNecessary();
484 void GpuDataManagerImplPrivate::AddObserver(GpuDataManagerObserver* observer) {
485 GpuDataManagerImpl::UnlockedSession session(owner_);
486 observer_list_->AddObserver(observer);
489 void GpuDataManagerImplPrivate::RemoveObserver(
490 GpuDataManagerObserver* observer) {
491 GpuDataManagerImpl::UnlockedSession session(owner_);
492 observer_list_->RemoveObserver(observer);
495 void GpuDataManagerImplPrivate::UnblockDomainFrom3DAPIs(const GURL& url) {
496 // This method must do two things:
498 // 1. If the specific domain is blocked, then unblock it.
500 // 2. Reset our notion of how many GPU resets have occurred recently.
501 // This is necessary even if the specific domain was blocked.
502 // Otherwise, if we call Are3DAPIsBlocked with the same domain right
503 // after unblocking it, it will probably still be blocked because of
504 // the recent GPU reset caused by that domain.
506 // These policies could be refined, but at a certain point the behavior
507 // will become difficult to explain.
508 std::string domain = GetDomainFromURL(url);
510 blocked_domains_.erase(domain);
511 timestamps_of_gpu_resets_.clear();
514 void GpuDataManagerImplPrivate::DisableGpuWatchdog() {
515 GpuProcessHost::SendOnIO(
516 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
517 CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH,
518 new GpuMsg_DisableWatchdog);
521 void GpuDataManagerImplPrivate::SetGLStrings(const std::string& gl_vendor,
522 const std::string& gl_renderer,
523 const std::string& gl_version) {
524 if (gl_vendor.empty() && gl_renderer.empty() && gl_version.empty())
525 return;
527 // If GPUInfo already got GL strings, do nothing. This is for the rare
528 // situation where GPU process collected GL strings before this call.
529 if (!gpu_info_.gl_vendor.empty() ||
530 !gpu_info_.gl_renderer.empty() ||
531 !gpu_info_.gl_version_string.empty())
532 return;
534 gpu::GPUInfo gpu_info = gpu_info_;
536 gpu_info.gl_vendor = gl_vendor;
537 gpu_info.gl_renderer = gl_renderer;
538 gpu_info.gl_version_string = gl_version;
540 gpu::CollectDriverInfoGL(&gpu_info);
542 UpdateGpuInfo(gpu_info);
543 UpdateGpuSwitchingManager(gpu_info);
544 UpdatePreliminaryBlacklistedFeatures();
547 void GpuDataManagerImplPrivate::GetGLStrings(std::string* gl_vendor,
548 std::string* gl_renderer,
549 std::string* gl_version) {
550 DCHECK(gl_vendor && gl_renderer && gl_version);
552 *gl_vendor = gpu_info_.gl_vendor;
553 *gl_renderer = gpu_info_.gl_renderer;
554 *gl_version = gpu_info_.gl_version_string;
557 void GpuDataManagerImplPrivate::Initialize() {
558 TRACE_EVENT0("startup", "GpuDataManagerImpl::Initialize");
559 if (finalized_) {
560 DVLOG(0) << "GpuDataManagerImpl marked as finalized; skipping Initialize";
561 return;
564 const CommandLine* command_line = CommandLine::ForCurrentProcess();
565 if (command_line->HasSwitch(switches::kSkipGpuDataLoading))
566 return;
568 gpu::GPUInfo gpu_info;
569 if (command_line->GetSwitchValueASCII(
570 switches::kUseGL) == gfx::kGLImplementationOSMesaName) {
571 // If using the OSMesa GL implementation, use fake vendor and device ids to
572 // make sure it never gets blacklisted. This is better than simply
573 // cancelling GPUInfo gathering as it allows us to proceed with loading the
574 // blacklist below which may have non-device specific entries we want to
575 // apply anyways (e.g., OS version blacklisting).
576 gpu_info.gpu.vendor_id = 0xffff;
577 gpu_info.gpu.device_id = 0xffff;
579 // Also declare the driver_vendor to be osmesa to be able to specify
580 // exceptions based on driver_vendor==osmesa for some blacklist rules.
581 gpu_info.driver_vendor = gfx::kGLImplementationOSMesaName;
582 } else {
583 TRACE_EVENT0("startup",
584 "GpuDataManagerImpl::Initialize:CollectBasicGraphicsInfo");
585 gpu::CollectBasicGraphicsInfo(&gpu_info);
587 #if defined(ARCH_CPU_X86_FAMILY)
588 if (!gpu_info.gpu.vendor_id || !gpu_info.gpu.device_id)
589 gpu_info.finalized = true;
590 #endif
592 std::string gpu_blacklist_string;
593 std::string gpu_driver_bug_list_string;
594 if (!command_line->HasSwitch(switches::kIgnoreGpuBlacklist) &&
595 !command_line->HasSwitch(switches::kUseGpuInTests)) {
596 gpu_blacklist_string = gpu::kSoftwareRenderingListJson;
598 if (!command_line->HasSwitch(switches::kDisableGpuDriverBugWorkarounds)) {
599 gpu_driver_bug_list_string = gpu::kGpuDriverBugListJson;
601 InitializeImpl(gpu_blacklist_string,
602 gpu_driver_bug_list_string,
603 gpu_info);
606 void GpuDataManagerImplPrivate::UpdateGpuInfo(const gpu::GPUInfo& gpu_info) {
607 // No further update of gpu_info if falling back to SwiftShader.
608 if (use_swiftshader_)
609 return;
611 gpu::MergeGPUInfo(&gpu_info_, gpu_info);
612 complete_gpu_info_already_requested_ =
613 complete_gpu_info_already_requested_ || gpu_info_.finalized;
615 GetContentClient()->SetGpuInfo(gpu_info_);
617 if (gpu_blacklist_) {
618 std::set<int> features = gpu_blacklist_->MakeDecision(
619 gpu::GpuControlList::kOsAny, std::string(), gpu_info_);
620 if (update_histograms_)
621 UpdateStats(gpu_info_, gpu_blacklist_.get(), features);
623 UpdateBlacklistedFeatures(features);
625 gpu_driver_bugs_ =
626 gpu::WorkaroundsFromCommandLine(CommandLine::ForCurrentProcess());
627 if (gpu_driver_bugs_.empty() && gpu_driver_bug_list_) {
628 gpu_driver_bugs_ = gpu_driver_bug_list_->MakeDecision(
629 gpu::GpuControlList::kOsAny, std::string(), gpu_info_);
631 AdjustGpuSwitchingOption(&gpu_driver_bugs_);
633 // We have to update GpuFeatureType before notify all the observers.
634 NotifyGpuInfoUpdate();
637 void GpuDataManagerImplPrivate::UpdateVideoMemoryUsageStats(
638 const GPUVideoMemoryUsageStats& video_memory_usage_stats) {
639 GpuDataManagerImpl::UnlockedSession session(owner_);
640 observer_list_->Notify(&GpuDataManagerObserver::OnVideoMemoryUsageStatsUpdate,
641 video_memory_usage_stats);
644 void GpuDataManagerImplPrivate::AppendRendererCommandLine(
645 CommandLine* command_line) const {
646 DCHECK(command_line);
648 if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) &&
649 !command_line->HasSwitch(switches::kDisableAcceleratedCompositing))
650 command_line->AppendSwitch(switches::kDisableAcceleratedCompositing);
651 if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE) &&
652 !command_line->HasSwitch(switches::kDisableAcceleratedVideoDecode))
653 command_line->AppendSwitch(switches::kDisableAcceleratedVideoDecode);
654 #if defined(ENABLE_WEBRTC)
655 if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE) &&
656 !command_line->HasSwitch(switches::kDisableWebRtcHWEncoding))
657 command_line->AppendSwitch(switches::kDisableWebRtcHWEncoding);
658 #endif
660 if (use_software_compositor_ &&
661 !command_line->HasSwitch(switches::kEnableSoftwareCompositing))
662 command_line->AppendSwitch(switches::kEnableSoftwareCompositing);
664 #if defined(USE_AURA)
665 if (!CanUseGpuBrowserCompositor())
666 command_line->AppendSwitch(switches::kDisableGpuCompositing);
667 #endif
670 void GpuDataManagerImplPrivate::AppendGpuCommandLine(
671 CommandLine* command_line) const {
672 DCHECK(command_line);
674 std::string use_gl =
675 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switches::kUseGL);
676 base::FilePath swiftshader_path =
677 CommandLine::ForCurrentProcess()->GetSwitchValuePath(
678 switches::kSwiftShaderPath);
679 if (gpu_driver_bugs_.find(gpu::DISABLE_D3D11) != gpu_driver_bugs_.end())
680 command_line->AppendSwitch(switches::kDisableD3D11);
681 if (use_swiftshader_) {
682 command_line->AppendSwitchASCII(switches::kUseGL, "swiftshader");
683 if (swiftshader_path.empty())
684 swiftshader_path = swiftshader_path_;
685 } else if ((IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL) ||
686 IsFeatureBlacklisted(
687 gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) ||
688 IsFeatureBlacklisted(
689 gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS)) &&
690 (use_gl == "any")) {
691 command_line->AppendSwitchASCII(
692 switches::kUseGL, gfx::kGLImplementationOSMesaName);
693 } else if (!use_gl.empty()) {
694 command_line->AppendSwitchASCII(switches::kUseGL, use_gl);
696 if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus())
697 command_line->AppendSwitchASCII(switches::kSupportsDualGpus, "true");
698 else
699 command_line->AppendSwitchASCII(switches::kSupportsDualGpus, "false");
701 if (!swiftshader_path.empty()) {
702 command_line->AppendSwitchPath(switches::kSwiftShaderPath,
703 swiftshader_path);
706 if (!gpu_driver_bugs_.empty()) {
707 command_line->AppendSwitchASCII(switches::kGpuDriverBugWorkarounds,
708 IntSetToString(gpu_driver_bugs_));
711 if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE) &&
712 !command_line->HasSwitch(switches::kDisableAcceleratedVideoDecode)) {
713 command_line->AppendSwitch(switches::kDisableAcceleratedVideoDecode);
715 #if defined(ENABLE_WEBRTC)
716 if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE) &&
717 !command_line->HasSwitch(switches::kDisableWebRtcHWEncoding)) {
718 command_line->AppendSwitch(switches::kDisableWebRtcHWEncoding);
720 #endif
722 // Pass GPU and driver information to GPU process. We try to avoid full GPU
723 // info collection at GPU process startup, but we need gpu vendor_id,
724 // device_id, driver_vendor, driver_version for deciding whether we need to
725 // collect full info (on Linux) and for crash reporting purpose.
726 command_line->AppendSwitchASCII(switches::kGpuVendorID,
727 base::StringPrintf("0x%04x", gpu_info_.gpu.vendor_id));
728 command_line->AppendSwitchASCII(switches::kGpuDeviceID,
729 base::StringPrintf("0x%04x", gpu_info_.gpu.device_id));
730 command_line->AppendSwitchASCII(switches::kGpuDriverVendor,
731 gpu_info_.driver_vendor);
732 command_line->AppendSwitchASCII(switches::kGpuDriverVersion,
733 gpu_info_.driver_version);
736 void GpuDataManagerImplPrivate::AppendPluginCommandLine(
737 CommandLine* command_line) const {
738 DCHECK(command_line);
740 #if defined(OS_MACOSX)
741 // TODO(jbauman): Add proper blacklist support for core animation plugins so
742 // special-casing this video card won't be necessary. See
743 // http://crbug.com/134015
744 if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) ||
745 CommandLine::ForCurrentProcess()->HasSwitch(
746 switches::kDisableAcceleratedCompositing)) {
747 if (!command_line->HasSwitch(
748 switches::kDisableCoreAnimationPlugins))
749 command_line->AppendSwitch(
750 switches::kDisableCoreAnimationPlugins);
752 #endif
755 void GpuDataManagerImplPrivate::UpdateRendererWebPrefs(
756 WebPreferences* prefs) const {
757 DCHECK(prefs);
759 if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING))
760 prefs->accelerated_compositing_enabled = false;
761 if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL)) {
762 prefs->experimental_webgl_enabled = false;
763 prefs->pepper_3d_enabled = false;
765 if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH3D))
766 prefs->flash_3d_enabled = false;
767 if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D)) {
768 prefs->flash_stage3d_enabled = false;
769 prefs->flash_stage3d_baseline_enabled = false;
771 if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE))
772 prefs->flash_stage3d_baseline_enabled = false;
773 if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS))
774 prefs->accelerated_2d_canvas_enabled = false;
775 if (IsDriverBugWorkaroundActive(gpu::DISABLE_MULTISAMPLING) ||
776 (IsDriverBugWorkaroundActive(gpu::DISABLE_MULTIMONITOR_MULTISAMPLING) &&
777 display_count_ > 1))
778 prefs->gl_multisampling_enabled = false;
779 if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_3D_CSS)) {
780 prefs->accelerated_compositing_for_3d_transforms_enabled = false;
781 prefs->accelerated_compositing_for_animation_enabled = false;
783 if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO))
784 prefs->accelerated_compositing_for_video_enabled = false;
786 // Accelerated video and animation are slower than regular when using
787 // SwiftShader. 3D CSS or Pepper 3D may also be too slow to be worthwhile.
788 if (ShouldUseSwiftShader()) {
789 prefs->accelerated_compositing_for_video_enabled = false;
790 prefs->accelerated_compositing_for_animation_enabled = false;
791 prefs->accelerated_compositing_for_3d_transforms_enabled = false;
792 prefs->accelerated_compositing_for_plugins_enabled = false;
793 prefs->pepper_3d_enabled = false;
796 if (use_software_compositor_) {
797 prefs->force_compositing_mode = true;
798 prefs->accelerated_compositing_enabled = true;
799 prefs->accelerated_compositing_for_3d_transforms_enabled = true;
800 prefs->accelerated_compositing_for_animation_enabled = true;
801 prefs->accelerated_compositing_for_plugins_enabled = true;
802 prefs->accelerated_compositing_for_video_enabled = true;
805 #if defined(USE_AURA)
806 if (!CanUseGpuBrowserCompositor()) {
807 prefs->accelerated_2d_canvas_enabled = false;
808 prefs->pepper_3d_enabled = false;
810 #endif
812 if (!IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE) &&
813 !CommandLine::ForCurrentProcess()->HasSwitch(
814 switches::kDisableAcceleratedVideoDecode)) {
815 prefs->pepper_accelerated_video_decode_enabled = true;
819 void GpuDataManagerImplPrivate::DisableHardwareAcceleration() {
820 card_blacklisted_ = true;
822 for (int i = 0; i < gpu::NUMBER_OF_GPU_FEATURE_TYPES; ++i)
823 blacklisted_features_.insert(i);
825 EnableSwiftShaderIfNecessary();
826 NotifyGpuInfoUpdate();
829 std::string GpuDataManagerImplPrivate::GetBlacklistVersion() const {
830 if (gpu_blacklist_)
831 return gpu_blacklist_->version();
832 return "0";
835 std::string GpuDataManagerImplPrivate::GetDriverBugListVersion() const {
836 if (gpu_driver_bug_list_)
837 return gpu_driver_bug_list_->version();
838 return "0";
841 void GpuDataManagerImplPrivate::GetBlacklistReasons(
842 base::ListValue* reasons) const {
843 if (gpu_blacklist_)
844 gpu_blacklist_->GetReasons(reasons, "disabledFeatures");
845 if (gpu_driver_bug_list_)
846 gpu_driver_bug_list_->GetReasons(reasons, "workarounds");
849 void GpuDataManagerImplPrivate::GetDriverBugWorkarounds(
850 base::ListValue* workarounds) const {
851 for (std::set<int>::const_iterator it = gpu_driver_bugs_.begin();
852 it != gpu_driver_bugs_.end(); ++it) {
853 workarounds->AppendString(
854 gpu::GpuDriverBugWorkaroundTypeToString(
855 static_cast<gpu::GpuDriverBugWorkaroundType>(*it)));
859 void GpuDataManagerImplPrivate::AddLogMessage(
860 int level, const std::string& header, const std::string& message) {
861 log_messages_.push_back(LogMessage(level, header, message));
864 void GpuDataManagerImplPrivate::ProcessCrashed(
865 base::TerminationStatus exit_code) {
866 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
867 // Unretained is ok, because it's posted to UI thread, the thread
868 // where the singleton GpuDataManagerImpl lives until the end.
869 BrowserThread::PostTask(
870 BrowserThread::UI,
871 FROM_HERE,
872 base::Bind(&GpuDataManagerImpl::ProcessCrashed,
873 base::Unretained(owner_),
874 exit_code));
875 return;
878 GpuDataManagerImpl::UnlockedSession session(owner_);
879 observer_list_->Notify(
880 &GpuDataManagerObserver::OnGpuProcessCrashed, exit_code);
884 base::ListValue* GpuDataManagerImplPrivate::GetLogMessages() const {
885 base::ListValue* value = new base::ListValue;
886 for (size_t ii = 0; ii < log_messages_.size(); ++ii) {
887 base::DictionaryValue* dict = new base::DictionaryValue();
888 dict->SetInteger("level", log_messages_[ii].level);
889 dict->SetString("header", log_messages_[ii].header);
890 dict->SetString("message", log_messages_[ii].message);
891 value->Append(dict);
893 return value;
896 void GpuDataManagerImplPrivate::HandleGpuSwitch() {
897 GpuDataManagerImpl::UnlockedSession session(owner_);
898 observer_list_->Notify(&GpuDataManagerObserver::OnGpuSwitching);
901 bool GpuDataManagerImplPrivate::CanUseGpuBrowserCompositor() const {
902 return !ShouldUseSwiftShader() &&
903 !IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) &&
904 !IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE);
907 void GpuDataManagerImplPrivate::BlockDomainFrom3DAPIs(
908 const GURL& url, GpuDataManagerImpl::DomainGuilt guilt) {
909 BlockDomainFrom3DAPIsAtTime(url, guilt, base::Time::Now());
912 bool GpuDataManagerImplPrivate::Are3DAPIsBlocked(const GURL& url,
913 int render_process_id,
914 int render_view_id,
915 ThreeDAPIType requester) {
916 bool blocked = Are3DAPIsBlockedAtTime(url, base::Time::Now()) !=
917 GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED;
918 if (blocked) {
919 // Unretained is ok, because it's posted to UI thread, the thread
920 // where the singleton GpuDataManagerImpl lives until the end.
921 BrowserThread::PostTask(
922 BrowserThread::UI, FROM_HERE,
923 base::Bind(&GpuDataManagerImpl::Notify3DAPIBlocked,
924 base::Unretained(owner_), url, render_process_id,
925 render_view_id, requester));
928 return blocked;
931 void GpuDataManagerImplPrivate::DisableDomainBlockingFor3DAPIsForTesting() {
932 domain_blocking_enabled_ = false;
935 // static
936 GpuDataManagerImplPrivate* GpuDataManagerImplPrivate::Create(
937 GpuDataManagerImpl* owner) {
938 return new GpuDataManagerImplPrivate(owner);
941 GpuDataManagerImplPrivate::GpuDataManagerImplPrivate(
942 GpuDataManagerImpl* owner)
943 : complete_gpu_info_already_requested_(false),
944 observer_list_(new GpuDataManagerObserverList),
945 use_swiftshader_(false),
946 card_blacklisted_(false),
947 update_histograms_(true),
948 window_count_(0),
949 domain_blocking_enabled_(true),
950 owner_(owner),
951 display_count_(0),
952 gpu_process_accessible_(true),
953 use_software_compositor_(false),
954 finalized_(false) {
955 DCHECK(owner_);
956 CommandLine* command_line = CommandLine::ForCurrentProcess();
957 if (command_line->HasSwitch(switches::kDisableAcceleratedCompositing)) {
958 command_line->AppendSwitch(switches::kDisableAccelerated2dCanvas);
959 command_line->AppendSwitch(switches::kDisableAcceleratedLayers);
961 if (command_line->HasSwitch(switches::kDisableGpu))
962 DisableHardwareAcceleration();
963 if (command_line->HasSwitch(switches::kEnableSoftwareCompositing))
964 use_software_compositor_ = true;
965 // TODO(jbauman): enable for Chrome OS
966 #if (defined(USE_AURA) && !defined(OS_CHROMEOS)) || defined(OS_MACOSX)
967 use_software_compositor_ = true;
968 #endif
970 #if defined(OS_MACOSX)
971 CGGetActiveDisplayList (0, NULL, &display_count_);
972 CGDisplayRegisterReconfigurationCallback(DisplayReconfigCallback, owner_);
973 #endif // OS_MACOSX
975 // For testing only.
976 if (command_line->HasSwitch(switches::kDisableDomainBlockingFor3DAPIs)) {
977 domain_blocking_enabled_ = false;
981 GpuDataManagerImplPrivate::~GpuDataManagerImplPrivate() {
982 #if defined(OS_MACOSX)
983 CGDisplayRemoveReconfigurationCallback(DisplayReconfigCallback, owner_);
984 #endif
987 void GpuDataManagerImplPrivate::InitializeImpl(
988 const std::string& gpu_blacklist_json,
989 const std::string& gpu_driver_bug_list_json,
990 const gpu::GPUInfo& gpu_info) {
991 const bool log_gpu_control_list_decisions =
992 CommandLine::ForCurrentProcess()->HasSwitch(
993 switches::kLogGpuControlListDecisions);
995 if (!gpu_blacklist_json.empty()) {
996 gpu_blacklist_.reset(gpu::GpuBlacklist::Create());
997 if (log_gpu_control_list_decisions)
998 gpu_blacklist_->enable_control_list_logging("gpu_blacklist");
999 bool success = gpu_blacklist_->LoadList(
1000 gpu_blacklist_json, gpu::GpuControlList::kCurrentOsOnly);
1001 DCHECK(success);
1003 if (!gpu_driver_bug_list_json.empty()) {
1004 gpu_driver_bug_list_.reset(gpu::GpuDriverBugList::Create());
1005 if (log_gpu_control_list_decisions)
1006 gpu_driver_bug_list_->enable_control_list_logging("gpu_driver_bug_list");
1007 bool success = gpu_driver_bug_list_->LoadList(
1008 gpu_driver_bug_list_json, gpu::GpuControlList::kCurrentOsOnly);
1009 DCHECK(success);
1012 gpu_info_ = gpu_info;
1013 UpdateGpuInfo(gpu_info);
1014 UpdateGpuSwitchingManager(gpu_info);
1015 UpdatePreliminaryBlacklistedFeatures();
1017 #if defined(OS_ANDROID)
1018 ApplyAndroidWorkarounds(gpu_info, CommandLine::ForCurrentProcess());
1019 #endif // OS_ANDROID
1022 void GpuDataManagerImplPrivate::UpdateBlacklistedFeatures(
1023 const std::set<int>& features) {
1024 CommandLine* command_line = CommandLine::ForCurrentProcess();
1025 blacklisted_features_ = features;
1027 // Force disable using the GPU for these features, even if they would
1028 // otherwise be allowed.
1029 if (card_blacklisted_ ||
1030 command_line->HasSwitch(switches::kBlacklistAcceleratedCompositing)) {
1031 blacklisted_features_.insert(
1032 gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING);
1034 if (card_blacklisted_ ||
1035 command_line->HasSwitch(switches::kBlacklistWebGL)) {
1036 blacklisted_features_.insert(gpu::GPU_FEATURE_TYPE_WEBGL);
1039 EnableSwiftShaderIfNecessary();
1042 void GpuDataManagerImplPrivate::UpdatePreliminaryBlacklistedFeatures() {
1043 preliminary_blacklisted_features_ = blacklisted_features_;
1046 void GpuDataManagerImplPrivate::UpdateGpuSwitchingManager(
1047 const gpu::GPUInfo& gpu_info) {
1048 ui::GpuSwitchingManager::GetInstance()->SetGpuCount(
1049 gpu_info.secondary_gpus.size() + 1);
1051 if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus()) {
1052 if (gpu_driver_bugs_.count(gpu::FORCE_DISCRETE_GPU) == 1)
1053 ui::GpuSwitchingManager::GetInstance()->ForceUseOfDiscreteGpu();
1054 else if (gpu_driver_bugs_.count(gpu::FORCE_INTEGRATED_GPU) == 1)
1055 ui::GpuSwitchingManager::GetInstance()->ForceUseOfIntegratedGpu();
1059 void GpuDataManagerImplPrivate::NotifyGpuInfoUpdate() {
1060 observer_list_->Notify(&GpuDataManagerObserver::OnGpuInfoUpdate);
1063 void GpuDataManagerImplPrivate::EnableSwiftShaderIfNecessary() {
1064 if (!GpuAccessAllowed(NULL) ||
1065 blacklisted_features_.count(gpu::GPU_FEATURE_TYPE_WEBGL)) {
1066 if (!swiftshader_path_.empty() &&
1067 !CommandLine::ForCurrentProcess()->HasSwitch(
1068 switches::kDisableSoftwareRasterizer))
1069 use_swiftshader_ = true;
1073 std::string GpuDataManagerImplPrivate::GetDomainFromURL(
1074 const GURL& url) const {
1075 // For the moment, we just use the host, or its IP address, as the
1076 // entry in the set, rather than trying to figure out the top-level
1077 // domain. This does mean that a.foo.com and b.foo.com will be
1078 // treated independently in the blocking of a given domain, but it
1079 // would require a third-party library to reliably figure out the
1080 // top-level domain from a URL.
1081 if (!url.has_host()) {
1082 return std::string();
1085 return url.host();
1088 void GpuDataManagerImplPrivate::BlockDomainFrom3DAPIsAtTime(
1089 const GURL& url,
1090 GpuDataManagerImpl::DomainGuilt guilt,
1091 base::Time at_time) {
1092 if (!domain_blocking_enabled_)
1093 return;
1095 std::string domain = GetDomainFromURL(url);
1097 DomainBlockEntry& entry = blocked_domains_[domain];
1098 entry.last_guilt = guilt;
1099 timestamps_of_gpu_resets_.push_back(at_time);
1102 GpuDataManagerImpl::DomainBlockStatus
1103 GpuDataManagerImplPrivate::Are3DAPIsBlockedAtTime(
1104 const GURL& url, base::Time at_time) const {
1105 if (!domain_blocking_enabled_)
1106 return GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED;
1108 // Note: adjusting the policies in this code will almost certainly
1109 // require adjusting the associated unit tests.
1110 std::string domain = GetDomainFromURL(url);
1112 DomainBlockMap::const_iterator iter = blocked_domains_.find(domain);
1113 if (iter != blocked_domains_.end()) {
1114 // Err on the side of caution, and assume that if a particular
1115 // domain shows up in the block map, it's there for a good
1116 // reason and don't let its presence there automatically expire.
1118 UMA_HISTOGRAM_ENUMERATION("GPU.BlockStatusForClient3DAPIs",
1119 BLOCK_STATUS_SPECIFIC_DOMAIN_BLOCKED,
1120 BLOCK_STATUS_MAX);
1122 return GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_BLOCKED;
1125 // Look at the timestamps of the recent GPU resets to see if there are
1126 // enough within the threshold which would cause us to blacklist all
1127 // domains. This doesn't need to be overly precise -- if time goes
1128 // backward due to a system clock adjustment, that's fine.
1130 // TODO(kbr): make this pay attention to the TDR thresholds in the
1131 // Windows registry, but make sure it continues to be testable.
1133 std::list<base::Time>::iterator iter = timestamps_of_gpu_resets_.begin();
1134 int num_resets_within_timeframe = 0;
1135 while (iter != timestamps_of_gpu_resets_.end()) {
1136 base::Time time = *iter;
1137 base::TimeDelta delta_t = at_time - time;
1139 // If this entry has "expired", just remove it.
1140 if (delta_t.InMilliseconds() > kBlockAllDomainsMs) {
1141 iter = timestamps_of_gpu_resets_.erase(iter);
1142 continue;
1145 ++num_resets_within_timeframe;
1146 ++iter;
1149 if (num_resets_within_timeframe >= kNumResetsWithinDuration) {
1150 UMA_HISTOGRAM_ENUMERATION("GPU.BlockStatusForClient3DAPIs",
1151 BLOCK_STATUS_ALL_DOMAINS_BLOCKED,
1152 BLOCK_STATUS_MAX);
1154 return GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_ALL_DOMAINS_BLOCKED;
1158 UMA_HISTOGRAM_ENUMERATION("GPU.BlockStatusForClient3DAPIs",
1159 BLOCK_STATUS_NOT_BLOCKED,
1160 BLOCK_STATUS_MAX);
1162 return GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED;
1165 int64 GpuDataManagerImplPrivate::GetBlockAllDomainsDurationInMs() const {
1166 return kBlockAllDomainsMs;
1169 void GpuDataManagerImplPrivate::Notify3DAPIBlocked(const GURL& url,
1170 int render_process_id,
1171 int render_view_id,
1172 ThreeDAPIType requester) {
1173 GpuDataManagerImpl::UnlockedSession session(owner_);
1174 observer_list_->Notify(&GpuDataManagerObserver::DidBlock3DAPIs,
1175 url, render_process_id, render_view_id, requester);
1178 void GpuDataManagerImplPrivate::OnGpuProcessInitFailure() {
1179 gpu_process_accessible_ = false;
1180 gpu_info_.finalized = true;
1181 complete_gpu_info_already_requested_ = true;
1182 // Some observers might be waiting.
1183 NotifyGpuInfoUpdate();
1186 } // namespace content