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"
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>
42 #include "base/win/windows_version.h"
44 #if defined(OS_ANDROID)
45 #include "ui/gfx/android/device_display_info.h"
52 enum GpuFeatureStatus
{
53 kGpuFeatureEnabled
= 0,
54 kGpuFeatureBlacklisted
= 1,
55 kGpuFeatureDisabled
= 2, // disabled by user but not blacklisted
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)
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)
87 else if (version_numbers
[0] == 6 && version_numbers
[1] == 2)
91 int entry_index
= static_cast<int>(sub_version
) * kGpuFeatureNumStatus
;
93 case kGpuFeatureEnabled
:
95 case kGpuFeatureBlacklisted
:
98 case kGpuFeatureDisabled
:
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.
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
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
;
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
),
162 const std::string kGpuBlacklistFeatureHistogramNamesWin
[] = {
163 "GPU.BlacklistFeatureTestResultsWindows.Accelerated2dCanvas",
164 "GPU.BlacklistFeatureTestResultsWindows.AcceleratedCompositing",
165 "GPU.BlacklistFeatureTestResultsWindows.Webgl",
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
);
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
));
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
) {
200 for (std::set
<int>::const_iterator it
= list
.begin();
201 it
!= list
.end(); ++it
) {
204 rt
+= base::IntToString(*it
);
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
);
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;
231 manager
->HandleGpuSwitch();
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
));
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;
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);
281 default_tile_size
= 384;
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
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());
307 // Overwrite force gpu workaround if a commandline switch exists.
308 void AdjustGpuSwitchingOption(std::set
<int>* 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
,
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.
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
)) {
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
)
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_
)
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 {
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_
)
400 if (!gpu_process_accessible_
) {
402 *reason
= "GPU process launch failed.";
407 if (card_blacklisted_
) {
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.";
414 *reason
+= "in chrome://settings.";
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()) {
426 *reason
= "Features are disabled upon full but not preliminary GPU info.";
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)
439 *reason
= "All GPU features are blacklisted.";
448 void GpuDataManagerImplPrivate::RequestCompleteGpuInfoIfNeeded() {
449 if (complete_gpu_info_already_requested_
|| gpu_info_
.finalized
)
451 complete_gpu_info_already_requested_
= true;
453 GpuProcessHost::SendOnIO(
455 GpuProcessHost::GPU_PROCESS_KIND_UNSANDBOXED
,
457 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED
,
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())
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())
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");
560 DVLOG(0) << "GpuDataManagerImpl marked as finalized; skipping Initialize";
564 const CommandLine
* command_line
= CommandLine::ForCurrentProcess();
565 if (command_line
->HasSwitch(switches::kSkipGpuDataLoading
))
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
;
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;
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
,
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_
)
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
);
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
);
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
);
670 void GpuDataManagerImplPrivate::AppendGpuCommandLine(
671 CommandLine
* command_line
) const {
672 DCHECK(command_line
);
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
)) &&
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");
699 command_line
->AppendSwitchASCII(switches::kSupportsDualGpus
, "false");
701 if (!swiftshader_path
.empty()) {
702 command_line
->AppendSwitchPath(switches::kSwiftShaderPath
,
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
);
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
);
755 void GpuDataManagerImplPrivate::UpdateRendererWebPrefs(
756 WebPreferences
* prefs
) const {
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
) &&
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;
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 {
831 return gpu_blacklist_
->version();
835 std::string
GpuDataManagerImplPrivate::GetDriverBugListVersion() const {
836 if (gpu_driver_bug_list_
)
837 return gpu_driver_bug_list_
->version();
841 void GpuDataManagerImplPrivate::GetBlacklistReasons(
842 base::ListValue
* reasons
) const {
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(
872 base::Bind(&GpuDataManagerImpl::ProcessCrashed
,
873 base::Unretained(owner_
),
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
);
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
,
915 ThreeDAPIType requester
) {
916 bool blocked
= Are3DAPIsBlockedAtTime(url
, base::Time::Now()) !=
917 GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_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
));
931 void GpuDataManagerImplPrivate::DisableDomainBlockingFor3DAPIsForTesting() {
932 domain_blocking_enabled_
= false;
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),
949 domain_blocking_enabled_(true),
952 gpu_process_accessible_(true),
953 use_software_compositor_(false),
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;
970 #if defined(OS_MACOSX)
971 CGGetActiveDisplayList (0, NULL
, &display_count_
);
972 CGDisplayRegisterReconfigurationCallback(DisplayReconfigCallback
, owner_
);
976 if (command_line
->HasSwitch(switches::kDisableDomainBlockingFor3DAPIs
)) {
977 domain_blocking_enabled_
= false;
981 GpuDataManagerImplPrivate::~GpuDataManagerImplPrivate() {
982 #if defined(OS_MACOSX)
983 CGDisplayRemoveReconfigurationCallback(DisplayReconfigCallback
, owner_
);
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
);
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
);
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();
1088 void GpuDataManagerImplPrivate::BlockDomainFrom3DAPIsAtTime(
1090 GpuDataManagerImpl::DomainGuilt guilt
,
1091 base::Time at_time
) {
1092 if (!domain_blocking_enabled_
)
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
,
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
);
1145 ++num_resets_within_timeframe
;
1149 if (num_resets_within_timeframe
>= kNumResetsWithinDuration
) {
1150 UMA_HISTOGRAM_ENUMERATION("GPU.BlockStatusForClient3DAPIs",
1151 BLOCK_STATUS_ALL_DOMAINS_BLOCKED
,
1154 return GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_ALL_DOMAINS_BLOCKED
;
1158 UMA_HISTOGRAM_ENUMERATION("GPU.BlockStatusForClient3DAPIs",
1159 BLOCK_STATUS_NOT_BLOCKED
,
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
,
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