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

Unified 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/gpu/gpu_data_manager_impl.cc
diff --git a/content/browser/gpu/gpu_data_manager_impl.cc b/content/browser/gpu/gpu_data_manager_impl.cc
index e41fd751203b641e866235d1d7d817388dbe7c84..d5cef9312bede83d8fc071cd01375c556886284c 100644
--- a/content/browser/gpu/gpu_data_manager_impl.cc
+++ b/content/browser/gpu/gpu_data_manager_impl.cc
@@ -69,6 +69,11 @@ void DisplayReconfigCallback(CGDirectDisplayID display,
}
#endif // OS_MACOSX
+// Block all domains' use of 3D APIs for this many milliseconds if
+// approaching a threshold where system stability might be compromised.
+const int64 kBlockAllDomainsMs = 10000;
+const int kNumResetsWithinDuration = 1;
+
} // namespace anonymous
// static
@@ -90,7 +95,8 @@ GpuDataManagerImpl::GpuDataManagerImpl()
software_rendering_(false),
card_blacklisted_(false),
update_histograms_(true),
- window_count_(0) {
+ window_count_(0),
+ domain_blocking_enabled_(true) {
CommandLine* command_line = CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kDisableAcceleratedCompositing)) {
command_line->AppendSwitch(switches::kDisableAccelerated2dCanvas);
@@ -340,6 +346,40 @@ uint32 GpuDataManagerImpl::GetWindowCount() const {
return window_count_;
}
+void GpuDataManagerImpl::BlockDomainFrom3DAPIs(
+ const GURL& url, DomainGuilt guilt) {
+ BlockDomainFrom3DAPIsAtTime(url, guilt, base::Time::Now());
+}
+
+GpuDataManager::DomainBlockStatus
+GpuDataManagerImpl::Are3DAPIsBlocked(const GURL& url) const {
+ return Are3DAPIsBlockedAtTime(url, base::Time::Now());
+}
+
+void GpuDataManagerImpl::UnblockDomainFrom3DAPIs(const GURL& url) {
+ // This method must do two things:
+ //
+ // 1. If the specific domain is blocked, then unblock it.
+ //
+ // 2. Reset our notion of how many GPU resets have occurred recently.
+ // This is necessary even if the specific domain was blocked.
+ // Otherwise, if we call Are3DAPIsBlocked with the same domain right
+ // after unblocking it, it will probably still be blocked because of
+ // the recent GPU reset caused by that domain.
+ //
+ // These policies could be refined, but at a certain point the behavior
+ // will become difficult to explain.
+ std::string domain = GetDomainFromURL(url);
+
+ base::AutoLock auto_lock(gpu_info_lock_);
+ blocked_domains_.erase(domain);
+ timestamps_of_gpu_resets_.clear();
+}
+
+void GpuDataManagerImpl::DisableDomainBlockingFor3DAPIsForTesting() {
+ domain_blocking_enabled_ = false;
+}
+
void GpuDataManagerImpl::AppendRendererCommandLine(
CommandLine* command_line) const {
DCHECK(command_line);
@@ -567,4 +607,85 @@ void GpuDataManagerImpl::BlacklistCard() {
NotifyGpuInfoUpdate();
}
+std::string GpuDataManagerImpl::GetDomainFromURL(const GURL& url) const {
+ // For the moment, we just use the host, or its IP address, as the
+ // entry in the set, rather than trying to figure out the top-level
+ // domain. This does mean that a.foo.com and b.foo.com will be
+ // treated independently in the blocking of a given domain, but it
+ // would require a third-party library to reliably figure out the
+ // top-level domain from a URL.
+ if (!url.has_host()) {
+ return std::string();
+ }
+
+ return url.host();
+}
+
+void GpuDataManagerImpl::BlockDomainFrom3DAPIsAtTime(
+ const GURL& url, DomainGuilt guilt, base::Time at_time) {
+ if (!domain_blocking_enabled_)
+ return;
+
+ std::string domain = GetDomainFromURL(url);
+
+ base::AutoLock auto_lock(gpu_info_lock_);
+ DomainBlockEntry& entry = blocked_domains_[domain];
+ entry.last_guilt = guilt;
+ timestamps_of_gpu_resets_.push_back(at_time);
+}
+
+GpuDataManager::DomainBlockStatus GpuDataManagerImpl::Are3DAPIsBlockedAtTime(
+ const GURL& url, base::Time at_time) const {
+ if (!domain_blocking_enabled_)
+ return DOMAIN_BLOCK_STATUS_NOT_BLOCKED;
+
+ // Note: adjusting the policies in this code will almost certainly
+ // require adjusting the associated unit tests.
+ std::string domain = GetDomainFromURL(url);
+
+ base::AutoLock auto_lock(gpu_info_lock_);
+ {
+ DomainBlockMap::const_iterator iter = blocked_domains_.find(domain);
+ if (iter != blocked_domains_.end()) {
+ // Err on the side of caution, and assume that if a particular
+ // domain shows up in the block map, it's there for a good
+ // reason and don't let its presence there automatically expire.
+ return DOMAIN_BLOCK_STATUS_BLOCKED;
+ }
+ }
+
+ // Look at the timestamps of the recent GPU resets to see if there are
+ // enough within the threshold which would cause us to blacklist all
+ // domains. This doesn't need to be overly precise -- if time goes
+ // backward due to a system clock adjustment, that's fine.
+ //
+ // TODO(kbr): make this pay attention to the TDR thresholds in the
+ // Windows registry, but make sure it continues to be testable.
+ std::list<base::Time>::iterator iter = timestamps_of_gpu_resets_.begin();
+ int num_resets_within_timeframe = 0;
+ while (iter != timestamps_of_gpu_resets_.end()) {
+ base::Time time = *iter;
+ base::TimeDelta delta_t = at_time - time;
+
+ // If this entry has "expired", just remove it.
+ if (delta_t.InMilliseconds() > kBlockAllDomainsMs) {
+ iter = timestamps_of_gpu_resets_.erase(iter);
+ continue;
+ }
+
+ ++num_resets_within_timeframe;
+ ++iter;
+ }
+
+ if (num_resets_within_timeframe >= kNumResetsWithinDuration) {
+ return DOMAIN_BLOCK_STATUS_ALL_DOMAINS_BLOCKED;
+ }
+
+ return DOMAIN_BLOCK_STATUS_NOT_BLOCKED;
+}
+
+int64 GpuDataManagerImpl::GetBlockAllDomainsDurationInMs() const {
+ return kBlockAllDomainsMs;
+}
+
} // namespace content
« 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