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

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: Addressed review feedback from zmo and jam. 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(const GURL& url) const {
356 return Are3DAPIsBlockedAtTime(url, base::Time::Now());
357 }
358
359 void GpuDataManagerImpl::UnblockDomainFrom3DAPIs(const GURL& url) {
360 // This method must do two things:
361 //
362 // 1. If the specific domain is blocked, then unblock it.
363 //
364 // 2. Reset our notion of how many GPU resets have occurred recently.
365 // This is necessary even if the specific domain was blocked.
366 // Otherwise, if we call Are3DAPIsBlocked with the same domain right
367 // after unblocking it, it will probably still be blocked because of
368 // the recent GPU reset caused by that domain.
369 //
370 // These policies could be refined, but at a certain point the behavior
371 // will become difficult to explain.
372 std::string domain = GetDomainFromURL(url);
373
374 base::AutoLock auto_lock(gpu_info_lock_);
375 blocked_domains_.erase(domain);
376 timestamps_of_gpu_resets_.clear();
377 }
378
379 void GpuDataManagerImpl::DisableDomainBlockingFor3DAPIsForTesting() {
380 domain_blocking_enabled_ = false;
381 }
382
343 void GpuDataManagerImpl::AppendRendererCommandLine( 383 void GpuDataManagerImpl::AppendRendererCommandLine(
344 CommandLine* command_line) const { 384 CommandLine* command_line) const {
345 DCHECK(command_line); 385 DCHECK(command_line);
346 386
347 uint32 flags = GetBlacklistedFeatures(); 387 uint32 flags = GetBlacklistedFeatures();
348 if ((flags & GPU_FEATURE_TYPE_WEBGL)) { 388 if ((flags & GPU_FEATURE_TYPE_WEBGL)) {
349 #if !defined(OS_ANDROID) 389 #if !defined(OS_ANDROID)
350 if (!command_line->HasSwitch(switches::kDisableExperimentalWebGL)) 390 if (!command_line->HasSwitch(switches::kDisableExperimentalWebGL))
351 command_line->AppendSwitch(switches::kDisableExperimentalWebGL); 391 command_line->AppendSwitch(switches::kDisableExperimentalWebGL);
352 #endif 392 #endif
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 600
561 void GpuDataManagerImpl::BlacklistCard() { 601 void GpuDataManagerImpl::BlacklistCard() {
562 card_blacklisted_ = true; 602 card_blacklisted_ = true;
563 603
564 blacklisted_features_ = GPU_FEATURE_TYPE_ALL; 604 blacklisted_features_ = GPU_FEATURE_TYPE_ALL;
565 605
566 EnableSoftwareRenderingIfNecessary(); 606 EnableSoftwareRenderingIfNecessary();
567 NotifyGpuInfoUpdate(); 607 NotifyGpuInfoUpdate();
568 } 608 }
569 609
610 std::string GpuDataManagerImpl::GetDomainFromURL(const GURL& url) const {
611 // For the moment, we just use the host, or its IP address, as the
612 // entry in the set, rather than trying to figure out the top-level
613 // domain. This does mean that a.foo.com and b.foo.com will be
614 // treated independently in the blocking of a given domain, but it
615 // would require a third-party library to reliably figure out the
616 // top-level domain from a URL.
617 if (!url.has_host()) {
618 return std::string();
619 }
620
621 return url.host();
622 }
623
624 void GpuDataManagerImpl::BlockDomainFrom3DAPIsAtTime(
625 const GURL& url, DomainGuilt guilt, base::Time at_time) {
626 if (!domain_blocking_enabled_)
627 return;
628
629 std::string domain = GetDomainFromURL(url);
630
631 base::AutoLock auto_lock(gpu_info_lock_);
632 DomainBlockEntry& entry = blocked_domains_[domain];
633 entry.last_guilt = guilt;
634 timestamps_of_gpu_resets_.push_back(at_time);
635 }
636
637 GpuDataManager::DomainBlockStatus GpuDataManagerImpl::Are3DAPIsBlockedAtTime(
638 const GURL& url, base::Time at_time) const {
639 if (!domain_blocking_enabled_)
640 return DOMAIN_BLOCK_STATUS_NOT_BLOCKED;
641
642 // Note: adjusting the policies in this code will almost certainly
643 // require adjusting the associated unit tests.
644 std::string domain = GetDomainFromURL(url);
645
646 base::AutoLock auto_lock(gpu_info_lock_);
647 {
648 DomainBlockMap::const_iterator iter = blocked_domains_.find(domain);
649 if (iter != blocked_domains_.end()) {
650 // Err on the side of caution, and assume that if a particular
651 // domain shows up in the block map, it's there for a good
652 // reason and don't let its presence there automatically expire.
653 return DOMAIN_BLOCK_STATUS_BLOCKED;
654 }
655 }
656
657 // Look at the timestamps of the recent GPU resets to see if there are
658 // enough within the threshold which would cause us to blacklist all
659 // domains. This doesn't need to be overly precise -- if time goes
660 // backward due to a system clock adjustment, that's fine.
661 //
662 // TODO(kbr): make this pay attention to the TDR thresholds in the
663 // Windows registry, but make sure it continues to be testable.
664 std::list<base::Time>::iterator iter = timestamps_of_gpu_resets_.begin();
665 int num_resets_within_timeframe = 0;
666 while (iter != timestamps_of_gpu_resets_.end()) {
667 base::Time time = *iter;
668 base::TimeDelta delta_t = at_time - time;
669
670 // If this entry has "expired", just remove it.
671 if (delta_t.InMilliseconds() > kBlockAllDomainsMs) {
672 iter = timestamps_of_gpu_resets_.erase(iter);
673 continue;
674 }
675
676 ++num_resets_within_timeframe;
677 ++iter;
678 }
679
680 if (num_resets_within_timeframe >= kNumResetsWithinDuration) {
681 return DOMAIN_BLOCK_STATUS_ALL_DOMAINS_BLOCKED;
682 }
683
684 return DOMAIN_BLOCK_STATUS_NOT_BLOCKED;
685 }
686
687 int64 GpuDataManagerImpl::GetBlockAllDomainsDurationInMs() const {
688 return kBlockAllDomainsMs;
689 }
690
570 } // namespace content 691 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/gpu/gpu_data_manager_impl.h ('k') | content/browser/gpu/gpu_data_manager_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698