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

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

Issue 11366237: Add logic to block the use of client 3D APIs (WebGL, Pepper 3D) if context lost notifications are r… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/gpu/gpu_data_manager_impl.h" 5 #include "content/browser/gpu/gpu_data_manager_impl.h"
6 6
7 #if defined(OS_MACOSX) 7 #if defined(OS_MACOSX)
8 #include <ApplicationServices/ApplicationServices.h> 8 #include <ApplicationServices/ApplicationServices.h>
9 #endif // OS_MACOSX 9 #endif // OS_MACOSX
10 10
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 void* gpu_data_manager) { 62 void* gpu_data_manager) {
63 if (flags & kCGDisplayAddFlag) { 63 if (flags & kCGDisplayAddFlag) {
64 GpuDataManagerImpl* manager = 64 GpuDataManagerImpl* manager =
65 reinterpret_cast<GpuDataManagerImpl*>(gpu_data_manager); 65 reinterpret_cast<GpuDataManagerImpl*>(gpu_data_manager);
66 DCHECK(manager); 66 DCHECK(manager);
67 manager->HandleGpuSwitch(); 67 manager->HandleGpuSwitch();
68 } 68 }
69 } 69 }
70 #endif // OS_MACOSX 70 #endif // OS_MACOSX
71 71
72 // Block all domains' use of 3D APIs for this many milliseconds if
73 // approaching a threshold where system stability might be compromised.
74 const int64 kBlockAllDomainsMs = 10000;
75 const int kNumResetsWithinDuration = 1;
76
72 } // namespace anonymous 77 } // namespace anonymous
73 78
74 // static 79 // static
75 GpuDataManager* GpuDataManager::GetInstance() { 80 GpuDataManager* GpuDataManager::GetInstance() {
76 return GpuDataManagerImpl::GetInstance(); 81 return GpuDataManagerImpl::GetInstance();
77 } 82 }
78 83
79 // static 84 // static
80 GpuDataManagerImpl* GpuDataManagerImpl::GetInstance() { 85 GpuDataManagerImpl* GpuDataManagerImpl::GetInstance() {
81 return Singleton<GpuDataManagerImpl>::get(); 86 return Singleton<GpuDataManagerImpl>::get();
82 } 87 }
83 88
84 GpuDataManagerImpl::GpuDataManagerImpl() 89 GpuDataManagerImpl::GpuDataManagerImpl()
85 : complete_gpu_info_already_requested_(false), 90 : complete_gpu_info_already_requested_(false),
86 blacklisted_features_(GPU_FEATURE_TYPE_UNKNOWN), 91 blacklisted_features_(GPU_FEATURE_TYPE_UNKNOWN),
87 preliminary_blacklisted_features_(GPU_FEATURE_TYPE_UNKNOWN), 92 preliminary_blacklisted_features_(GPU_FEATURE_TYPE_UNKNOWN),
88 gpu_switching_(GPU_SWITCHING_OPTION_AUTOMATIC), 93 gpu_switching_(GPU_SWITCHING_OPTION_AUTOMATIC),
89 observer_list_(new GpuDataManagerObserverList), 94 observer_list_(new GpuDataManagerObserverList),
90 software_rendering_(false), 95 software_rendering_(false),
91 card_blacklisted_(false), 96 card_blacklisted_(false),
92 update_histograms_(true), 97 update_histograms_(true),
93 window_count_(0) { 98 window_count_(0),
99 domain_blocking_enabled_(true) {
94 CommandLine* command_line = CommandLine::ForCurrentProcess(); 100 CommandLine* command_line = CommandLine::ForCurrentProcess();
95 if (command_line->HasSwitch(switches::kDisableAcceleratedCompositing)) { 101 if (command_line->HasSwitch(switches::kDisableAcceleratedCompositing)) {
96 command_line->AppendSwitch(switches::kDisableAccelerated2dCanvas); 102 command_line->AppendSwitch(switches::kDisableAccelerated2dCanvas);
97 command_line->AppendSwitch(switches::kDisableAcceleratedLayers); 103 command_line->AppendSwitch(switches::kDisableAcceleratedLayers);
98 } 104 }
99 if (command_line->HasSwitch(switches::kDisableGpu)) 105 if (command_line->HasSwitch(switches::kDisableGpu))
100 BlacklistCard(); 106 BlacklistCard();
101 if (command_line->HasSwitch(switches::kGpuSwitching)) { 107 if (command_line->HasSwitch(switches::kGpuSwitching)) {
102 std::string option_string = command_line->GetSwitchValueASCII( 108 std::string option_string = command_line->GetSwitchValueASCII(
103 switches::kGpuSwitching); 109 switches::kGpuSwitching);
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, 339 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
334 CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH, 340 CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH,
335 new GpuMsg_SetVideoMemoryWindowCount(count)); 341 new GpuMsg_SetVideoMemoryWindowCount(count));
336 } 342 }
337 343
338 uint32 GpuDataManagerImpl::GetWindowCount() const { 344 uint32 GpuDataManagerImpl::GetWindowCount() const {
339 base::AutoLock auto_lock(gpu_info_lock_); 345 base::AutoLock auto_lock(gpu_info_lock_);
340 return window_count_; 346 return window_count_;
341 } 347 }
342 348
349 void GpuDataManagerImpl::BlockDomainFrom3DAPIs(
350 const GURL& url, DomainGuilt guilt) {
351 BlockDomainFrom3DAPIsAtTime(url, guilt, base::Time::Now());
352 }
353
354 GpuDataManager::DomainBlockStatus
355 GpuDataManagerImpl::Are3DAPIsBlocked(
356 const GURL& url) const {
Zhenyao Mo 2012/11/14 16:35:58 nit: you don't need to put this in a new line.
Ken Russell (switch to Gerrit) 2012/11/14 19:09:13 Done.
357 return Are3DAPIsBlockedAtTime(url, base::Time::Now());
358 }
359
360 void GpuDataManagerImpl::UnblockDomainFrom3DAPIs(const GURL& url) {
361 // This method must do two things:
362 //
363 // 1. If the specific domain is blocked, then unblock it.
364 //
365 // 2. Reset our notion of how many GPU resets have occurred recently.
366 // This is necessary even if the specific domain was blocked.
367 // Otherwise, if we call Are3DAPIsBlocked with the same domain right
368 // after unblocking it, it will probably still be blocked because of
369 // the recent GPU reset caused by that domain.
370 //
371 // These policies could be refined, but at a certain point the behavior
372 // will become difficult to explain.
373 std::string domain = GetDomainFromURL(url);
374
375 base::AutoLock auto_lock(gpu_info_lock_);
376 blocked_domains_.erase(domain);
377 timestamps_of_gpu_resets_.clear();
378 }
379
380 void GpuDataManagerImpl::DisableDomainBlockingFor3DAPIsForTesting() {
381 domain_blocking_enabled_ = false;
382 }
383
343 void GpuDataManagerImpl::AppendRendererCommandLine( 384 void GpuDataManagerImpl::AppendRendererCommandLine(
344 CommandLine* command_line) const { 385 CommandLine* command_line) const {
345 DCHECK(command_line); 386 DCHECK(command_line);
346 387
347 uint32 flags = GetBlacklistedFeatures(); 388 uint32 flags = GetBlacklistedFeatures();
348 if ((flags & GPU_FEATURE_TYPE_WEBGL)) { 389 if ((flags & GPU_FEATURE_TYPE_WEBGL)) {
349 #if !defined(OS_ANDROID) 390 #if !defined(OS_ANDROID)
350 if (!command_line->HasSwitch(switches::kDisableExperimentalWebGL)) 391 if (!command_line->HasSwitch(switches::kDisableExperimentalWebGL))
351 command_line->AppendSwitch(switches::kDisableExperimentalWebGL); 392 command_line->AppendSwitch(switches::kDisableExperimentalWebGL);
352 #endif 393 #endif
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 601
561 void GpuDataManagerImpl::BlacklistCard() { 602 void GpuDataManagerImpl::BlacklistCard() {
562 card_blacklisted_ = true; 603 card_blacklisted_ = true;
563 604
564 blacklisted_features_ = GPU_FEATURE_TYPE_ALL; 605 blacklisted_features_ = GPU_FEATURE_TYPE_ALL;
565 606
566 EnableSoftwareRenderingIfNecessary(); 607 EnableSoftwareRenderingIfNecessary();
567 NotifyGpuInfoUpdate(); 608 NotifyGpuInfoUpdate();
568 } 609 }
569 610
611 std::string GpuDataManagerImpl::GetDomainFromURL(const GURL& url) const {
612 // For the moment, we just use the host, or its IP address, as the
613 // entry in the set, rather than trying to figure out the top-level
614 // domain. This does mean that a.foo.com and b.foo.com will be
615 // treated independently in the blocking of a given domain, but it
616 // would require a third-party library to reliably figure out the
617 // top-level domain from a URL.
618 if (!url.has_host()) {
619 return std::string();
620 }
621
622 return url.host();
623 }
624
625 void GpuDataManagerImpl::BlockDomainFrom3DAPIsAtTime(
626 const GURL& url, DomainGuilt guilt, base::Time at_time) {
627 if (!domain_blocking_enabled_)
628 return;
629
630 std::string domain = GetDomainFromURL(url);
631
632 base::AutoLock auto_lock(gpu_info_lock_);
633 DomainBlockEntry& entry = blocked_domains_[domain];
634 entry.last_guilt = guilt;
635 timestamps_of_gpu_resets_.push_back(at_time);
636 }
637
638 GpuDataManager::DomainBlockStatus GpuDataManagerImpl::Are3DAPIsBlockedAtTime(
639 const GURL& url, base::Time at_time) const {
640 if (!domain_blocking_enabled_)
641 return kNotBlocked;
642
643 // Note: adjusting the policies in this code will almost certainly
644 // require adjusting the associated unit tests.
645 std::string domain = GetDomainFromURL(url);
646
647 base::AutoLock auto_lock(gpu_info_lock_);
648 {
649 DomainBlockMap::const_iterator iter = blocked_domains_.find(domain);
650 if (iter != blocked_domains_.end()) {
651 // Err on the side of caution, and assume that if a particular
652 // domain shows up in the block map, it's there for a good
653 // reason and don't let its presence there automatically expire.
654 return kDomainBlocked;
655 }
656 }
657
658 // Look at the timestamps of the recent GPU resets to see if there are
659 // enough within the threshold which would cause us to blacklist all
660 // domains. This doesn't need to be overly precise -- if time goes
661 // backward due to a system clock adjustment, that's fine.
662 //
663 // TODO(kbr): make this pay attention to the TDR thresholds in the
664 // Windows registry, but make sure it continues to be testable.
665 std::list<base::Time>::iterator iter = timestamps_of_gpu_resets_.begin();
666 int num_resets_within_timeframe = 0;
667 while (iter != timestamps_of_gpu_resets_.end()) {
668 base::Time time = *iter;
669 base::TimeDelta delta_t = at_time - time;
670
671 // If this entry has "expired", just remove it.
672 if (delta_t.InMilliseconds() > kBlockAllDomainsMs) {
673 iter = timestamps_of_gpu_resets_.erase(iter);
674 continue;
675 }
676
677 ++num_resets_within_timeframe;
678 ++iter;
679 }
680
681 if (num_resets_within_timeframe >= kNumResetsWithinDuration) {
682 return kAllDomainsBlocked;
683 }
684
685 return kNotBlocked;
686 }
687
688 int64 GpuDataManagerImpl::GetBlockAllDomainsDurationInMs() const {
689 return kBlockAllDomainsMs;
690 }
691
570 } // namespace content 692 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698