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

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

Issue 14794006: Refactor GpuDataManagerImpl to make it thread-safe, now and forever. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 7 years, 7 months 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) 2013 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_private.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
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/bind_helpers.h" 12 #include "base/bind_helpers.h"
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/debug/trace_event.h" 14 #include "base/debug/trace_event.h"
15 #include "base/file_util.h" 15 #include "base/file_util.h"
16 #include "base/metrics/field_trial.h" 16 #include "base/metrics/field_trial.h"
17 #include "base/metrics/histogram.h" 17 #include "base/metrics/histogram.h"
18 #include "base/stringprintf.h" 18 #include "base/stringprintf.h"
19 #include "base/strings/string_number_conversions.h" 19 #include "base/strings/string_number_conversions.h"
20 #include "base/strings/string_piece.h" 20 #include "base/strings/string_piece.h"
21 #include "base/sys_info.h" 21 #include "base/sys_info.h"
22 #include "base/values.h"
23 #include "base/version.h" 22 #include "base/version.h"
24 #include "content/browser/gpu/gpu_process_host.h" 23 #include "content/browser/gpu/gpu_process_host.h"
25 #include "content/browser/gpu/gpu_util.h" 24 #include "content/browser/gpu/gpu_util.h"
26 #include "content/common/gpu/gpu_messages.h" 25 #include "content/common/gpu/gpu_messages.h"
27 #include "content/gpu/gpu_info_collector.h" 26 #include "content/gpu/gpu_info_collector.h"
28 #include "content/public/browser/browser_thread.h" 27 #include "content/public/browser/browser_thread.h"
29 #include "content/public/browser/gpu_data_manager_observer.h" 28 #include "content/public/browser/gpu_data_manager_observer.h"
30 #include "content/public/common/content_client.h" 29 #include "content/public/common/content_client.h"
31 #include "content/public/common/content_constants.h" 30 #include "content/public/common/content_constants.h"
32 #include "content/public/common/content_switches.h" 31 #include "content/public/common/content_switches.h"
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 // Enums for UMA histograms. 94 // Enums for UMA histograms.
96 enum BlockStatusHistogram { 95 enum BlockStatusHistogram {
97 BLOCK_STATUS_NOT_BLOCKED, 96 BLOCK_STATUS_NOT_BLOCKED,
98 BLOCK_STATUS_SPECIFIC_DOMAIN_BLOCKED, 97 BLOCK_STATUS_SPECIFIC_DOMAIN_BLOCKED,
99 BLOCK_STATUS_ALL_DOMAINS_BLOCKED, 98 BLOCK_STATUS_ALL_DOMAINS_BLOCKED,
100 BLOCK_STATUS_MAX 99 BLOCK_STATUS_MAX
101 }; 100 };
102 101
103 } // namespace anonymous 102 } // namespace anonymous
104 103
105 // static 104 void GpuDataManagerImplPrivate::InitializeForTesting(
106 GpuDataManager* GpuDataManager::GetInstance() {
107 return GpuDataManagerImpl::GetInstance();
108 }
109
110 // static
111 GpuDataManagerImpl* GpuDataManagerImpl::GetInstance() {
112 return Singleton<GpuDataManagerImpl>::get();
113 }
114
115 void GpuDataManagerImpl::InitializeForTesting(
116 const std::string& gpu_blacklist_json, 105 const std::string& gpu_blacklist_json,
117 const GPUInfo& gpu_info) { 106 const GPUInfo& gpu_info) {
118 // This function is for testing only, so disable histograms. 107 // This function is for testing only, so disable histograms.
119 update_histograms_ = false; 108 update_histograms_ = false;
120 109
121 InitializeImpl(gpu_blacklist_json, std::string(), std::string(), gpu_info); 110 InitializeImpl(gpu_blacklist_json, std::string(), std::string(), gpu_info);
122 } 111 }
123 112
124 bool GpuDataManagerImpl::IsFeatureBlacklisted(int feature) const { 113 bool GpuDataManagerImplPrivate::IsFeatureBlacklisted(int feature) const {
125 if (use_swiftshader_) { 114 if (use_swiftshader_) {
126 // Skia's software rendering is probably more efficient than going through 115 // Skia's software rendering is probably more efficient than going through
127 // software emulation of the GPU, so use that. 116 // software emulation of the GPU, so use that.
128 if (feature == GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS) 117 if (feature == GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS)
129 return true; 118 return true;
130 return false; 119 return false;
131 } 120 }
132 121
133 return (blacklisted_features_.count(feature) == 1); 122 return (blacklisted_features_.count(feature) == 1);
134 } 123 }
135 124
136 size_t GpuDataManagerImpl::GetBlacklistedFeatureCount() const { 125 size_t GpuDataManagerImplPrivate::GetBlacklistedFeatureCount() const {
137 if (use_swiftshader_) 126 if (use_swiftshader_)
138 return 1; 127 return 1;
139 return blacklisted_features_.size(); 128 return blacklisted_features_.size();
140 } 129 }
141 130
142 void GpuDataManagerImpl::AddGpuSwitchCallback( 131 void GpuDataManagerImplPrivate::AddGpuSwitchCallback(
143 const GpuSwitchCallback& callback) { 132 const GpuSwitchCallback& callback) {
144 gpu_switch_callbacks_.push_back(callback); 133 gpu_switch_callbacks_.push_back(callback);
145 } 134 }
146 135
147 void GpuDataManagerImpl::RemoveGpuSwitchCallback( 136 void GpuDataManagerImplPrivate::RemoveGpuSwitchCallback(
148 const GpuSwitchCallback& callback) { 137 const GpuSwitchCallback& callback) {
149 for (size_t i = 0; i < gpu_switch_callbacks_.size(); i++) { 138 for (size_t i = 0; i < gpu_switch_callbacks_.size(); i++) {
150 if (gpu_switch_callbacks_[i].Equals(callback)) { 139 if (gpu_switch_callbacks_[i].Equals(callback)) {
151 gpu_switch_callbacks_.erase(gpu_switch_callbacks_.begin() + i); 140 gpu_switch_callbacks_.erase(gpu_switch_callbacks_.begin() + i);
152 return; 141 return;
153 } 142 }
154 } 143 }
155 } 144 }
156 145
157 GPUInfo GpuDataManagerImpl::GetGPUInfo() const { 146 GPUInfo GpuDataManagerImplPrivate::GetGPUInfo() const {
158 GPUInfo gpu_info; 147 return gpu_info_;
159 {
160 base::AutoLock auto_lock(gpu_info_lock_);
161 gpu_info = gpu_info_;
162 }
163 return gpu_info;
164 } 148 }
165 149
166 void GpuDataManagerImpl::GetGpuProcessHandles( 150 void GpuDataManagerImplPrivate::GetGpuProcessHandles(
167 const GetGpuProcessHandlesCallback& callback) const { 151 const GpuDataManager::GetGpuProcessHandlesCallback& callback) const {
168 GpuProcessHost::GetProcessHandles(callback); 152 GpuProcessHost::GetProcessHandles(callback);
169 } 153 }
170 154
171 bool GpuDataManagerImpl::GpuAccessAllowed(std::string* reason) const { 155 bool GpuDataManagerImplPrivate::GpuAccessAllowed(
156 std::string* reason) const {
172 if (use_swiftshader_) 157 if (use_swiftshader_)
173 return true; 158 return true;
174 159
175 if (!gpu_info_.gpu_accessible) { 160 if (!gpu_info_.gpu_accessible) {
176 if (reason) { 161 if (reason) {
177 *reason = "GPU process launch failed."; 162 *reason = "GPU process launch failed.";
178 } 163 }
179 return false; 164 return false;
180 } 165 }
181 166
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 if (reason) { 198 if (reason) {
214 *reason = "All GPU features are blacklisted."; 199 *reason = "All GPU features are blacklisted.";
215 } 200 }
216 return false; 201 return false;
217 #endif 202 #endif
218 } 203 }
219 204
220 return true; 205 return true;
221 } 206 }
222 207
223 void GpuDataManagerImpl::RequestCompleteGpuInfoIfNeeded() { 208 void GpuDataManagerImplPrivate::RequestCompleteGpuInfoIfNeeded() {
224 if (complete_gpu_info_already_requested_ || gpu_info_.finalized) 209 if (complete_gpu_info_already_requested_ || gpu_info_.finalized)
225 return; 210 return;
226 complete_gpu_info_already_requested_ = true; 211 complete_gpu_info_already_requested_ = true;
227 212
228 GpuProcessHost::SendOnIO( 213 GpuProcessHost::SendOnIO(
229 #if defined(OS_WIN) 214 #if defined(OS_WIN)
230 GpuProcessHost::GPU_PROCESS_KIND_UNSANDBOXED, 215 GpuProcessHost::GPU_PROCESS_KIND_UNSANDBOXED,
231 #else 216 #else
232 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, 217 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
233 #endif 218 #endif
234 CAUSE_FOR_GPU_LAUNCH_GPUDATAMANAGER_REQUESTCOMPLETEGPUINFOIFNEEDED, 219 CAUSE_FOR_GPU_LAUNCH_GPUDATAMANAGER_REQUESTCOMPLETEGPUINFOIFNEEDED,
235 new GpuMsg_CollectGraphicsInfo()); 220 new GpuMsg_CollectGraphicsInfo());
236 } 221 }
237 222
238 bool GpuDataManagerImpl::IsCompleteGpuInfoAvailable() const { 223 bool GpuDataManagerImplPrivate::IsCompleteGpuInfoAvailable() const {
239 return gpu_info_.finalized; 224 return gpu_info_.finalized;
240 } 225 }
241 226
242 void GpuDataManagerImpl::RequestVideoMemoryUsageStatsUpdate() const { 227 void GpuDataManagerImplPrivate::RequestVideoMemoryUsageStatsUpdate() const {
243 GpuProcessHost::SendOnIO( 228 GpuProcessHost::SendOnIO(
244 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, 229 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
245 CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH, 230 CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH,
246 new GpuMsg_GetVideoMemoryUsageStats()); 231 new GpuMsg_GetVideoMemoryUsageStats());
247 } 232 }
248 233
249 bool GpuDataManagerImpl::ShouldUseSwiftShader() const { 234 bool GpuDataManagerImplPrivate::ShouldUseSwiftShader() const {
250 return use_swiftshader_; 235 return use_swiftshader_;
251 } 236 }
252 237
253 void GpuDataManagerImpl::RegisterSwiftShaderPath(const base::FilePath& path) { 238 void GpuDataManagerImplPrivate::RegisterSwiftShaderPath(
239 const base::FilePath& path) {
254 swiftshader_path_ = path; 240 swiftshader_path_ = path;
255 EnableSwiftShaderIfNecessary(); 241 EnableSwiftShaderIfNecessary();
256 } 242 }
257 243
258 void GpuDataManagerImpl::AddObserver(GpuDataManagerObserver* observer) { 244 void GpuDataManagerImplPrivate::AddObserver(GpuDataManagerObserver* observer) {
245 GpuDataManagerImpl::UnlockedSession session(owner_);
259 observer_list_->AddObserver(observer); 246 observer_list_->AddObserver(observer);
260 } 247 }
261 248
262 void GpuDataManagerImpl::RemoveObserver(GpuDataManagerObserver* observer) { 249 void GpuDataManagerImplPrivate::RemoveObserver(
250 GpuDataManagerObserver* observer) {
251 GpuDataManagerImpl::UnlockedSession session(owner_);
263 observer_list_->RemoveObserver(observer); 252 observer_list_->RemoveObserver(observer);
264 } 253 }
265 254
266 void GpuDataManagerImpl::UnblockDomainFrom3DAPIs(const GURL& url) { 255 void GpuDataManagerImplPrivate::UnblockDomainFrom3DAPIs(const GURL& url) {
267 // This method must do two things: 256 // This method must do two things:
268 // 257 //
269 // 1. If the specific domain is blocked, then unblock it. 258 // 1. If the specific domain is blocked, then unblock it.
270 // 259 //
271 // 2. Reset our notion of how many GPU resets have occurred recently. 260 // 2. Reset our notion of how many GPU resets have occurred recently.
272 // This is necessary even if the specific domain was blocked. 261 // This is necessary even if the specific domain was blocked.
273 // Otherwise, if we call Are3DAPIsBlocked with the same domain right 262 // Otherwise, if we call Are3DAPIsBlocked with the same domain right
274 // after unblocking it, it will probably still be blocked because of 263 // after unblocking it, it will probably still be blocked because of
275 // the recent GPU reset caused by that domain. 264 // the recent GPU reset caused by that domain.
276 // 265 //
277 // These policies could be refined, but at a certain point the behavior 266 // These policies could be refined, but at a certain point the behavior
278 // will become difficult to explain. 267 // will become difficult to explain.
279 std::string domain = GetDomainFromURL(url); 268 std::string domain = GetDomainFromURL(url);
280 269
281 base::AutoLock auto_lock(gpu_info_lock_);
282 blocked_domains_.erase(domain); 270 blocked_domains_.erase(domain);
283 timestamps_of_gpu_resets_.clear(); 271 timestamps_of_gpu_resets_.clear();
284 } 272 }
285 273
286 void GpuDataManagerImpl::DisableGpuWatchdog() { 274 void GpuDataManagerImplPrivate::DisableGpuWatchdog() {
287 GpuProcessHost::SendOnIO( 275 GpuProcessHost::SendOnIO(
288 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, 276 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
289 CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH, 277 CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH,
290 new GpuMsg_DisableWatchdog); 278 new GpuMsg_DisableWatchdog);
291 } 279 }
292 280
293 void GpuDataManagerImpl::SetGLStrings(const std::string& gl_vendor, 281 void GpuDataManagerImplPrivate::SetGLStrings(const std::string& gl_vendor,
294 const std::string& gl_renderer, 282 const std::string& gl_renderer,
295 const std::string& gl_version) { 283 const std::string& gl_version) {
296 if (gl_vendor.empty() && gl_renderer.empty() && gl_version.empty()) 284 if (gl_vendor.empty() && gl_renderer.empty() && gl_version.empty())
297 return; 285 return;
298 286
299 GPUInfo gpu_info; 287 // If GPUInfo already got GL strings, do nothing. This is for the rare
300 { 288 // situation where GPU process collected GL strings before this call.
301 base::AutoLock auto_lock(gpu_info_lock_); 289 if (!gpu_info_.gl_vendor.empty() ||
302 // If GPUInfo already got GL strings, do nothing. This is for the rare 290 !gpu_info_.gl_renderer.empty() ||
303 // situation where GPU process collected GL strings before this call. 291 !gpu_info_.gl_version_string.empty())
304 if (!gpu_info_.gl_vendor.empty() || 292 return;
305 !gpu_info_.gl_renderer.empty() || 293
306 !gpu_info_.gl_version_string.empty()) 294 GPUInfo gpu_info = gpu_info_;
307 return;
308 gpu_info = gpu_info_;
309 }
310 295
311 gpu_info.gl_vendor = gl_vendor; 296 gpu_info.gl_vendor = gl_vendor;
312 gpu_info.gl_renderer = gl_renderer; 297 gpu_info.gl_renderer = gl_renderer;
313 gpu_info.gl_version_string = gl_version; 298 gpu_info.gl_version_string = gl_version;
314 299
315 gpu_info_collector::CollectDriverInfoGL(&gpu_info); 300 gpu_info_collector::CollectDriverInfoGL(&gpu_info);
316 301
317 UpdateGpuInfo(gpu_info); 302 UpdateGpuInfo(gpu_info);
318 UpdateGpuSwitchingManager(gpu_info); 303 UpdateGpuSwitchingManager(gpu_info);
319 UpdatePreliminaryBlacklistedFeatures(); 304 UpdatePreliminaryBlacklistedFeatures();
320 } 305 }
321 306
322 void GpuDataManagerImpl::GetGLStrings(std::string* gl_vendor, 307 void GpuDataManagerImplPrivate::GetGLStrings(std::string* gl_vendor,
323 std::string* gl_renderer, 308 std::string* gl_renderer,
324 std::string* gl_version) { 309 std::string* gl_version) {
325 DCHECK(gl_vendor && gl_renderer && gl_version); 310 DCHECK(gl_vendor && gl_renderer && gl_version);
326 311
327 base::AutoLock auto_lock(gpu_info_lock_);
328 *gl_vendor = gpu_info_.gl_vendor; 312 *gl_vendor = gpu_info_.gl_vendor;
329 *gl_renderer = gpu_info_.gl_renderer; 313 *gl_renderer = gpu_info_.gl_renderer;
330 *gl_version = gpu_info_.gl_version_string; 314 *gl_version = gpu_info_.gl_version_string;
331 } 315 }
332 316
333 317 void GpuDataManagerImplPrivate::Initialize() {
334 void GpuDataManagerImpl::Initialize() {
335 TRACE_EVENT0("startup", "GpuDataManagerImpl::Initialize"); 318 TRACE_EVENT0("startup", "GpuDataManagerImpl::Initialize");
336 CommandLine* command_line = CommandLine::ForCurrentProcess(); 319 CommandLine* command_line = CommandLine::ForCurrentProcess();
337 if (command_line->HasSwitch(switches::kSkipGpuDataLoading)) 320 if (command_line->HasSwitch(switches::kSkipGpuDataLoading))
338 return; 321 return;
339 322
340 GPUInfo gpu_info; 323 GPUInfo gpu_info;
341 { 324 {
342 TRACE_EVENT0("startup", 325 TRACE_EVENT0("startup",
343 "GpuDataManagerImpl::Initialize:CollectBasicGraphicsInfo"); 326 "GpuDataManagerImpl::Initialize:CollectBasicGraphicsInfo");
344 gpu_info_collector::CollectBasicGraphicsInfo(&gpu_info); 327 gpu_info_collector::CollectBasicGraphicsInfo(&gpu_info);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 // have a GPU process, we append the browser process commandline. 359 // have a GPU process, we append the browser process commandline.
377 if (command_line->HasSwitch(switches::kSingleProcess) || 360 if (command_line->HasSwitch(switches::kSingleProcess) ||
378 command_line->HasSwitch(switches::kInProcessGPU)) { 361 command_line->HasSwitch(switches::kInProcessGPU)) {
379 if (!gpu_driver_bugs_.empty()) { 362 if (!gpu_driver_bugs_.empty()) {
380 command_line->AppendSwitchASCII(switches::kGpuDriverBugWorkarounds, 363 command_line->AppendSwitchASCII(switches::kGpuDriverBugWorkarounds,
381 IntSetToString(gpu_driver_bugs_)); 364 IntSetToString(gpu_driver_bugs_));
382 } 365 }
383 } 366 }
384 } 367 }
385 368
386 void GpuDataManagerImpl::UpdateGpuInfo(const GPUInfo& gpu_info) { 369 void GpuDataManagerImplPrivate::UpdateGpuInfo(const GPUInfo& gpu_info) {
387 // No further update of gpu_info if falling back to SwiftShader. 370 // No further update of gpu_info if falling back to SwiftShader.
388 if (use_swiftshader_) 371 if (use_swiftshader_)
389 return; 372 return;
390 373
391 GPUInfo my_gpu_info; 374 gpu_info_collector::MergeGPUInfo(&gpu_info_, gpu_info);
392 { 375 complete_gpu_info_already_requested_ =
393 base::AutoLock auto_lock(gpu_info_lock_); 376 complete_gpu_info_already_requested_ || gpu_info_.finalized;
394 gpu_info_collector::MergeGPUInfo(&gpu_info_, gpu_info);
395 complete_gpu_info_already_requested_ =
396 complete_gpu_info_already_requested_ || gpu_info_.finalized;
397 my_gpu_info = gpu_info_;
398 }
399 377
400 GetContentClient()->SetGpuInfo(my_gpu_info); 378 GetContentClient()->SetGpuInfo(gpu_info_);
401 379
402 if (gpu_blacklist_) { 380 if (gpu_blacklist_) {
403 std::set<int> features = gpu_blacklist_->MakeDecision( 381 std::set<int> features = gpu_blacklist_->MakeDecision(
404 GpuControlList::kOsAny, std::string(), my_gpu_info); 382 GpuControlList::kOsAny, std::string(), gpu_info_);
405 if (update_histograms_) 383 if (update_histograms_)
406 UpdateStats(gpu_blacklist_.get(), features); 384 UpdateStats(gpu_blacklist_.get(), features);
407 385
408 UpdateBlacklistedFeatures(features); 386 UpdateBlacklistedFeatures(features);
409 } 387 }
410 if (gpu_switching_list_) { 388 if (gpu_switching_list_) {
411 std::set<int> option = gpu_switching_list_->MakeDecision( 389 std::set<int> option = gpu_switching_list_->MakeDecision(
412 GpuControlList::kOsAny, std::string(), my_gpu_info); 390 GpuControlList::kOsAny, std::string(), gpu_info_);
413 if (option.size() == 1) { 391 if (option.size() == 1) {
414 // Blacklist decision should not overwrite commandline switch from users. 392 // Blacklist decision should not overwrite commandline switch from users.
415 CommandLine* command_line = CommandLine::ForCurrentProcess(); 393 CommandLine* command_line = CommandLine::ForCurrentProcess();
416 if (!command_line->HasSwitch(switches::kGpuSwitching)) 394 if (!command_line->HasSwitch(switches::kGpuSwitching))
417 gpu_switching_ = static_cast<GpuSwitchingOption>(*(option.begin())); 395 gpu_switching_ = static_cast<GpuSwitchingOption>(*(option.begin()));
418 } 396 }
419 } 397 }
420 if (gpu_driver_bug_list_) 398 if (gpu_driver_bug_list_)
421 gpu_driver_bugs_ = gpu_driver_bug_list_->MakeDecision( 399 gpu_driver_bugs_ = gpu_driver_bug_list_->MakeDecision(
422 GpuControlList::kOsAny, std::string(), my_gpu_info); 400 GpuControlList::kOsAny, std::string(), gpu_info_);
423 401
424 // We have to update GpuFeatureType before notify all the observers. 402 // We have to update GpuFeatureType before notify all the observers.
425 NotifyGpuInfoUpdate(); 403 NotifyGpuInfoUpdate();
426 } 404 }
427 405
428 void GpuDataManagerImpl::UpdateVideoMemoryUsageStats( 406 void GpuDataManagerImplPrivate::UpdateVideoMemoryUsageStats(
429 const GPUVideoMemoryUsageStats& video_memory_usage_stats) { 407 const GPUVideoMemoryUsageStats& video_memory_usage_stats) {
408 GpuDataManagerImpl::UnlockedSession session(owner_);
430 observer_list_->Notify(&GpuDataManagerObserver::OnVideoMemoryUsageStatsUpdate, 409 observer_list_->Notify(&GpuDataManagerObserver::OnVideoMemoryUsageStatsUpdate,
431 video_memory_usage_stats); 410 video_memory_usage_stats);
432 } 411 }
433 412
434 void GpuDataManagerImpl::AppendRendererCommandLine( 413 void GpuDataManagerImplPrivate::AppendRendererCommandLine(
435 CommandLine* command_line) const { 414 CommandLine* command_line) const {
436 DCHECK(command_line); 415 DCHECK(command_line);
437 416
438 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_WEBGL)) { 417 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_WEBGL)) {
439 #if !defined(OS_ANDROID) 418 #if !defined(OS_ANDROID)
440 if (!command_line->HasSwitch(switches::kDisableExperimentalWebGL)) 419 if (!command_line->HasSwitch(switches::kDisableExperimentalWebGL))
441 command_line->AppendSwitch(switches::kDisableExperimentalWebGL); 420 command_line->AppendSwitch(switches::kDisableExperimentalWebGL);
442 #endif 421 #endif
443 if (!command_line->HasSwitch(switches::kDisablePepper3d)) 422 if (!command_line->HasSwitch(switches::kDisablePepper3d))
444 command_line->AppendSwitch(switches::kDisablePepper3d); 423 command_line->AppendSwitch(switches::kDisablePepper3d);
445 } 424 }
446 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_MULTISAMPLING) && 425 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_MULTISAMPLING) &&
447 !command_line->HasSwitch(switches::kDisableGLMultisampling)) 426 !command_line->HasSwitch(switches::kDisableGLMultisampling))
448 command_line->AppendSwitch(switches::kDisableGLMultisampling); 427 command_line->AppendSwitch(switches::kDisableGLMultisampling);
449 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) && 428 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) &&
450 !command_line->HasSwitch(switches::kDisableAcceleratedCompositing)) 429 !command_line->HasSwitch(switches::kDisableAcceleratedCompositing))
451 command_line->AppendSwitch(switches::kDisableAcceleratedCompositing); 430 command_line->AppendSwitch(switches::kDisableAcceleratedCompositing);
452 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS) && 431 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS) &&
453 !command_line->HasSwitch(switches::kDisableAccelerated2dCanvas)) 432 !command_line->HasSwitch(switches::kDisableAccelerated2dCanvas))
454 command_line->AppendSwitch(switches::kDisableAccelerated2dCanvas); 433 command_line->AppendSwitch(switches::kDisableAccelerated2dCanvas);
455 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE) && 434 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE) &&
456 !command_line->HasSwitch(switches::kDisableAcceleratedVideoDecode)) 435 !command_line->HasSwitch(switches::kDisableAcceleratedVideoDecode))
457 command_line->AppendSwitch(switches::kDisableAcceleratedVideoDecode); 436 command_line->AppendSwitch(switches::kDisableAcceleratedVideoDecode);
458 if (ShouldUseSwiftShader()) 437 if (ShouldUseSwiftShader())
459 command_line->AppendSwitch(switches::kDisableFlashFullscreen3d); 438 command_line->AppendSwitch(switches::kDisableFlashFullscreen3d);
460 } 439 }
461 440
462 void GpuDataManagerImpl::AppendGpuCommandLine( 441 void GpuDataManagerImplPrivate::AppendGpuCommandLine(
463 CommandLine* command_line) const { 442 CommandLine* command_line) const {
464 DCHECK(command_line); 443 DCHECK(command_line);
465 444
466 std::string use_gl = 445 std::string use_gl =
467 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switches::kUseGL); 446 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switches::kUseGL);
468 base::FilePath swiftshader_path = 447 base::FilePath swiftshader_path =
469 CommandLine::ForCurrentProcess()->GetSwitchValuePath( 448 CommandLine::ForCurrentProcess()->GetSwitchValuePath(
470 switches::kSwiftShaderPath); 449 switches::kSwiftShaderPath);
471 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_MULTISAMPLING) && 450 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_MULTISAMPLING) &&
472 !command_line->HasSwitch(switches::kDisableGLMultisampling)) 451 !command_line->HasSwitch(switches::kDisableGLMultisampling))
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 // http://crbug.com/177611 499 // http://crbug.com/177611
521 // Thinkpad USB Port Replicator driver causes GPU process to crash when the 500 // Thinkpad USB Port Replicator driver causes GPU process to crash when the
522 // sandbox is enabled. http://crbug.com/181665. 501 // sandbox is enabled. http://crbug.com/181665.
523 if ((gpu_info_.display_link_version.IsValid() 502 if ((gpu_info_.display_link_version.IsValid()
524 && gpu_info_.display_link_version.IsOlderThan("7.2")) || 503 && gpu_info_.display_link_version.IsOlderThan("7.2")) ||
525 gpu_info_.lenovo_dcute) { 504 gpu_info_.lenovo_dcute) {
526 command_line->AppendSwitch(switches::kReduceGpuSandbox); 505 command_line->AppendSwitch(switches::kReduceGpuSandbox);
527 } 506 }
528 #endif 507 #endif
529 508
530 { 509 if (gpu_info_.optimus)
531 base::AutoLock auto_lock(gpu_info_lock_); 510 command_line->AppendSwitch(switches::kReduceGpuSandbox);
532 if (gpu_info_.optimus) 511 if (gpu_info_.amd_switchable) {
533 command_line->AppendSwitch(switches::kReduceGpuSandbox); 512 // The image transport surface currently doesn't work with AMD Dynamic
534 if (gpu_info_.amd_switchable) { 513 // Switchable graphics.
535 // The image transport surface currently doesn't work with AMD Dynamic 514 command_line->AppendSwitch(switches::kReduceGpuSandbox);
536 // Switchable graphics. 515 command_line->AppendSwitch(switches::kDisableImageTransportSurface);
537 command_line->AppendSwitch(switches::kReduceGpuSandbox);
538 command_line->AppendSwitch(switches::kDisableImageTransportSurface);
539 }
540 // Pass GPU and driver information to GPU process. We try to avoid full GPU
541 // info collection at GPU process startup, but we need gpu vendor_id,
542 // device_id, driver_vendor, driver_version for deciding whether we need to
543 // collect full info (on Linux) and for crash reporting purpose.
544 command_line->AppendSwitchASCII(switches::kGpuVendorID,
545 base::StringPrintf("0x%04x", gpu_info_.gpu.vendor_id));
546 command_line->AppendSwitchASCII(switches::kGpuDeviceID,
547 base::StringPrintf("0x%04x", gpu_info_.gpu.device_id));
548 command_line->AppendSwitchASCII(switches::kGpuDriverVendor,
549 gpu_info_.driver_vendor);
550 command_line->AppendSwitchASCII(switches::kGpuDriverVersion,
551 gpu_info_.driver_version);
552 } 516 }
517 // Pass GPU and driver information to GPU process. We try to avoid full GPU
518 // info collection at GPU process startup, but we need gpu vendor_id,
519 // device_id, driver_vendor, driver_version for deciding whether we need to
520 // collect full info (on Linux) and for crash reporting purpose.
521 command_line->AppendSwitchASCII(switches::kGpuVendorID,
522 base::StringPrintf("0x%04x", gpu_info_.gpu.vendor_id));
523 command_line->AppendSwitchASCII(switches::kGpuDeviceID,
524 base::StringPrintf("0x%04x", gpu_info_.gpu.device_id));
525 command_line->AppendSwitchASCII(switches::kGpuDriverVendor,
526 gpu_info_.driver_vendor);
527 command_line->AppendSwitchASCII(switches::kGpuDriverVersion,
528 gpu_info_.driver_version);
553 } 529 }
554 530
555 void GpuDataManagerImpl::AppendPluginCommandLine( 531 void GpuDataManagerImplPrivate::AppendPluginCommandLine(
556 CommandLine* command_line) const { 532 CommandLine* command_line) const {
557 DCHECK(command_line); 533 DCHECK(command_line);
558 534
559 #if defined(OS_MACOSX) 535 #if defined(OS_MACOSX)
560 // TODO(jbauman): Add proper blacklist support for core animation plugins so 536 // TODO(jbauman): Add proper blacklist support for core animation plugins so
561 // special-casing this video card won't be necessary. See 537 // special-casing this video card won't be necessary. See
562 // http://crbug.com/134015 538 // http://crbug.com/134015
563 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) || 539 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) ||
564 CommandLine::ForCurrentProcess()->HasSwitch( 540 CommandLine::ForCurrentProcess()->HasSwitch(
565 switches::kDisableAcceleratedCompositing)) { 541 switches::kDisableAcceleratedCompositing)) {
566 if (!command_line->HasSwitch( 542 if (!command_line->HasSwitch(
567 switches::kDisableCoreAnimationPlugins)) 543 switches::kDisableCoreAnimationPlugins))
568 command_line->AppendSwitch( 544 command_line->AppendSwitch(
569 switches::kDisableCoreAnimationPlugins); 545 switches::kDisableCoreAnimationPlugins);
570 } 546 }
571 #endif 547 #endif
572 } 548 }
573 549
574 void GpuDataManagerImpl::UpdateRendererWebPrefs(WebPreferences* prefs) const { 550 void GpuDataManagerImplPrivate::UpdateRendererWebPrefs(
551 WebPreferences* prefs) const {
575 DCHECK(prefs); 552 DCHECK(prefs);
576 553
577 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING)) 554 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING))
578 prefs->accelerated_compositing_enabled = false; 555 prefs->accelerated_compositing_enabled = false;
579 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_WEBGL)) 556 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_WEBGL))
580 prefs->experimental_webgl_enabled = false; 557 prefs->experimental_webgl_enabled = false;
581 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_FLASH3D)) 558 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_FLASH3D))
582 prefs->flash_3d_enabled = false; 559 prefs->flash_3d_enabled = false;
583 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_FLASH_STAGE3D)) { 560 if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_FLASH_STAGE3D)) {
584 prefs->flash_stage3d_enabled = false; 561 prefs->flash_stage3d_enabled = false;
(...skipping 15 matching lines...) Expand all
600 // Accelerated video and animation are slower than regular when using 577 // Accelerated video and animation are slower than regular when using
601 // SwiftShader. 3D CSS may also be too slow to be worthwhile. 578 // SwiftShader. 3D CSS may also be too slow to be worthwhile.
602 if (ShouldUseSwiftShader()) { 579 if (ShouldUseSwiftShader()) {
603 prefs->accelerated_compositing_for_video_enabled = false; 580 prefs->accelerated_compositing_for_video_enabled = false;
604 prefs->accelerated_compositing_for_animation_enabled = false; 581 prefs->accelerated_compositing_for_animation_enabled = false;
605 prefs->accelerated_compositing_for_3d_transforms_enabled = false; 582 prefs->accelerated_compositing_for_3d_transforms_enabled = false;
606 prefs->accelerated_compositing_for_plugins_enabled = false; 583 prefs->accelerated_compositing_for_plugins_enabled = false;
607 } 584 }
608 } 585 }
609 586
610 GpuSwitchingOption GpuDataManagerImpl::GetGpuSwitchingOption() const { 587 GpuSwitchingOption GpuDataManagerImplPrivate::GetGpuSwitchingOption() const {
611 if (!ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus()) 588 if (!ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus())
612 return GPU_SWITCHING_OPTION_UNKNOWN; 589 return GPU_SWITCHING_OPTION_UNKNOWN;
613 return gpu_switching_; 590 return gpu_switching_;
614 } 591 }
615 592
616 void GpuDataManagerImpl::DisableHardwareAcceleration() { 593 void GpuDataManagerImplPrivate::DisableHardwareAcceleration() {
617 card_blacklisted_ = true; 594 card_blacklisted_ = true;
618 595
619 for (int i = 0; i < NUMBER_OF_GPU_FEATURE_TYPES; ++i) 596 for (int i = 0; i < NUMBER_OF_GPU_FEATURE_TYPES; ++i)
620 blacklisted_features_.insert(i); 597 blacklisted_features_.insert(i);
621 598
622 EnableSwiftShaderIfNecessary(); 599 EnableSwiftShaderIfNecessary();
623 NotifyGpuInfoUpdate(); 600 NotifyGpuInfoUpdate();
624 } 601 }
625 602
626 std::string GpuDataManagerImpl::GetBlacklistVersion() const { 603 std::string GpuDataManagerImplPrivate::GetBlacklistVersion() const {
627 if (gpu_blacklist_) 604 if (gpu_blacklist_)
628 return gpu_blacklist_->version(); 605 return gpu_blacklist_->version();
629 return "0"; 606 return "0";
630 } 607 }
631 608
632 base::ListValue* GpuDataManagerImpl::GetBlacklistReasons() const { 609 base::ListValue* GpuDataManagerImplPrivate::GetBlacklistReasons() const {
633 ListValue* reasons = new ListValue(); 610 ListValue* reasons = new ListValue();
634 if (gpu_blacklist_) 611 if (gpu_blacklist_)
635 gpu_blacklist_->GetReasons(reasons); 612 gpu_blacklist_->GetReasons(reasons);
636 return reasons; 613 return reasons;
637 } 614 }
638 615
639 void GpuDataManagerImpl::AddLogMessage( 616 void GpuDataManagerImplPrivate::AddLogMessage(
640 int level, const std::string& header, const std::string& message) { 617 int level, const std::string& header, const std::string& message) {
641 base::AutoLock auto_lock(log_messages_lock_);
642 DictionaryValue* dict = new DictionaryValue(); 618 DictionaryValue* dict = new DictionaryValue();
643 dict->SetInteger("level", level); 619 dict->SetInteger("level", level);
644 dict->SetString("header", header); 620 dict->SetString("header", header);
645 dict->SetString("message", message); 621 dict->SetString("message", message);
646 log_messages_.Append(dict); 622 log_messages_.Append(dict);
647 } 623 }
648 624
649 void GpuDataManagerImpl::ProcessCrashed(base::TerminationStatus exit_code) { 625 void GpuDataManagerImplPrivate::ProcessCrashed(
626 base::TerminationStatus exit_code) {
650 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 627 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
651 BrowserThread::PostTask(BrowserThread::UI, 628 if (owner_) {
652 FROM_HERE, 629 // Unretained is ok, because it's posted to UI thread, the thread
653 base::Bind(&GpuDataManagerImpl::ProcessCrashed, 630 // where the singleton GpuDataManagerImpl lives until the end.
654 base::Unretained(this), 631 BrowserThread::PostTask(
655 exit_code)); 632 BrowserThread::UI,
633 FROM_HERE,
634 base::Bind(&GpuDataManagerImpl::ProcessCrashed,
635 base::Unretained(owner_),
636 exit_code));
637 }
656 return; 638 return;
657 } 639 }
658 observer_list_->Notify(&GpuDataManagerObserver::OnGpuProcessCrashed, 640 {
659 exit_code); 641 GpuDataManagerImpl::UnlockedSession session(owner_);
642 observer_list_->Notify(
643 &GpuDataManagerObserver::OnGpuProcessCrashed, exit_code);
644 }
660 } 645 }
661 646
662 base::ListValue* GpuDataManagerImpl::GetLogMessages() const { 647 base::ListValue* GpuDataManagerImplPrivate::GetLogMessages() const {
663 base::ListValue* value; 648 base::ListValue* value;
664 { 649 value = log_messages_.DeepCopy();
665 base::AutoLock auto_lock(log_messages_lock_);
666 value = log_messages_.DeepCopy();
667 }
668 return value; 650 return value;
669 } 651 }
670 652
671 void GpuDataManagerImpl::HandleGpuSwitch() { 653 void GpuDataManagerImplPrivate::HandleGpuSwitch() {
672 complete_gpu_info_already_requested_ = false; 654 complete_gpu_info_already_requested_ = false;
673 gpu_info_.finalized = false; 655 gpu_info_.finalized = false;
674 for (size_t i = 0; i < gpu_switch_callbacks_.size(); ++i) 656 for (size_t i = 0; i < gpu_switch_callbacks_.size(); ++i)
675 gpu_switch_callbacks_[i].Run(); 657 gpu_switch_callbacks_[i].Run();
Zhenyao Mo 2013/05/10 18:33:32 This is another place that callbacks can re-enter
676 } 658 }
677 659
678 #if defined(OS_WIN) 660 #if defined(OS_WIN)
679 bool GpuDataManagerImpl::IsUsingAcceleratedSurface() const { 661 bool GpuDataManagerImplPrivate::IsUsingAcceleratedSurface() const {
680 if (base::win::GetVersion() < base::win::VERSION_VISTA) 662 if (base::win::GetVersion() < base::win::VERSION_VISTA)
681 return false; 663 return false;
682 664
683 if (gpu_info_.amd_switchable) 665 if (gpu_info_.amd_switchable)
684 return false; 666 return false;
685 if (use_swiftshader_) 667 if (use_swiftshader_)
686 return false; 668 return false;
687 CommandLine* command_line = CommandLine::ForCurrentProcess(); 669 CommandLine* command_line = CommandLine::ForCurrentProcess();
688 if (command_line->HasSwitch(switches::kDisableImageTransportSurface)) 670 if (command_line->HasSwitch(switches::kDisableImageTransportSurface))
689 return false; 671 return false;
690 return !IsFeatureBlacklisted(GPU_FEATURE_TYPE_TEXTURE_SHARING); 672 return !IsFeatureBlacklisted(GPU_FEATURE_TYPE_TEXTURE_SHARING);
691 } 673 }
692 #endif 674 #endif
693 675
694 void GpuDataManagerImpl::BlockDomainFrom3DAPIs( 676 void GpuDataManagerImplPrivate::BlockDomainFrom3DAPIs(
695 const GURL& url, DomainGuilt guilt) { 677 const GURL& url, GpuDataManagerImpl::DomainGuilt guilt) {
696 BlockDomainFrom3DAPIsAtTime(url, guilt, base::Time::Now()); 678 BlockDomainFrom3DAPIsAtTime(url, guilt, base::Time::Now());
697 } 679 }
698 680
699 bool GpuDataManagerImpl::Are3DAPIsBlocked(const GURL& url, 681 bool GpuDataManagerImplPrivate::Are3DAPIsBlocked(const GURL& url,
700 int render_process_id, 682 int render_process_id,
701 int render_view_id, 683 int render_view_id,
702 ThreeDAPIType requester) { 684 ThreeDAPIType requester) {
703 bool blocked = Are3DAPIsBlockedAtTime(url, base::Time::Now()) != 685 bool blocked = Are3DAPIsBlockedAtTime(url, base::Time::Now()) !=
704 GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED; 686 GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED;
705 if (blocked) { 687 if (blocked && owner_) {
688 // Unretained is ok, because it's posted to UI thread, the thread
689 // where the singleton GpuDataManagerImpl lives until the end.
706 BrowserThread::PostTask( 690 BrowserThread::PostTask(
707 BrowserThread::UI, FROM_HERE, 691 BrowserThread::UI, FROM_HERE,
708 base::Bind(&GpuDataManagerImpl::Notify3DAPIBlocked, 692 base::Bind(&GpuDataManagerImpl::Notify3DAPIBlocked,
709 base::Unretained(this), url, render_process_id, 693 base::Unretained(owner_), url, render_process_id,
710 render_view_id, requester)); 694 render_view_id, requester));
711 } 695 }
712 696
713 return blocked; 697 return blocked;
714 } 698 }
715 699
716 void GpuDataManagerImpl::DisableDomainBlockingFor3DAPIsForTesting() { 700 void GpuDataManagerImplPrivate::DisableDomainBlockingFor3DAPIsForTesting() {
717 domain_blocking_enabled_ = false; 701 domain_blocking_enabled_ = false;
718 } 702 }
719 703
720 GpuDataManagerImpl::GpuDataManagerImpl() 704 // static
705 GpuDataManagerImplPrivate* GpuDataManagerImplPrivate::Create(
706 GpuDataManagerImpl* owner) {
707 GpuDataManagerImplPrivate* rt = new GpuDataManagerImplPrivate();
708 rt->owner_ = owner;
709 return rt;
710 }
711
712 GpuDataManagerImplPrivate::GpuDataManagerImplPrivate()
721 : complete_gpu_info_already_requested_(false), 713 : complete_gpu_info_already_requested_(false),
722 gpu_switching_(GPU_SWITCHING_OPTION_AUTOMATIC), 714 gpu_switching_(GPU_SWITCHING_OPTION_AUTOMATIC),
723 observer_list_(new GpuDataManagerObserverList), 715 observer_list_(new GpuDataManagerObserverList),
724 use_swiftshader_(false), 716 use_swiftshader_(false),
725 card_blacklisted_(false), 717 card_blacklisted_(false),
726 update_histograms_(true), 718 update_histograms_(true),
727 window_count_(0), 719 window_count_(0),
728 domain_blocking_enabled_(true) { 720 domain_blocking_enabled_(true),
721 owner_(NULL) {
729 CommandLine* command_line = CommandLine::ForCurrentProcess(); 722 CommandLine* command_line = CommandLine::ForCurrentProcess();
730 if (command_line->HasSwitch(switches::kDisableAcceleratedCompositing)) { 723 if (command_line->HasSwitch(switches::kDisableAcceleratedCompositing)) {
731 command_line->AppendSwitch(switches::kDisableAccelerated2dCanvas); 724 command_line->AppendSwitch(switches::kDisableAccelerated2dCanvas);
732 command_line->AppendSwitch(switches::kDisableAcceleratedLayers); 725 command_line->AppendSwitch(switches::kDisableAcceleratedLayers);
733 } 726 }
734 if (command_line->HasSwitch(switches::kDisableGpu)) 727 if (command_line->HasSwitch(switches::kDisableGpu))
735 DisableHardwareAcceleration(); 728 DisableHardwareAcceleration();
736 if (command_line->HasSwitch(switches::kGpuSwitching)) { 729 if (command_line->HasSwitch(switches::kGpuSwitching)) {
737 std::string option_string = command_line->GetSwitchValueASCII( 730 std::string option_string = command_line->GetSwitchValueASCII(
738 switches::kGpuSwitching); 731 switches::kGpuSwitching);
739 GpuSwitchingOption option = StringToGpuSwitchingOption(option_string); 732 GpuSwitchingOption option = StringToGpuSwitchingOption(option_string);
740 if (option != GPU_SWITCHING_OPTION_UNKNOWN) 733 if (option != GPU_SWITCHING_OPTION_UNKNOWN)
741 gpu_switching_ = option; 734 gpu_switching_ = option;
742 } 735 }
743 736
744 #if defined(OS_MACOSX) 737 #if defined(OS_MACOSX)
745 CGDisplayRegisterReconfigurationCallback(DisplayReconfigCallback, this); 738 CGDisplayRegisterReconfigurationCallback(DisplayReconfigCallback, this);
746 #endif // OS_MACOSX 739 #endif // OS_MACOSX
747 } 740 }
748 741
749 GpuDataManagerImpl::~GpuDataManagerImpl() { 742 GpuDataManagerImplPrivate::~GpuDataManagerImplPrivate() {
750 #if defined(OS_MACOSX) 743 #if defined(OS_MACOSX)
751 CGDisplayRemoveReconfigurationCallback(DisplayReconfigCallback, this); 744 CGDisplayRemoveReconfigurationCallback(DisplayReconfigCallback, this);
752 #endif 745 #endif
753 } 746 }
754 747
755 void GpuDataManagerImpl::InitializeImpl( 748 void GpuDataManagerImplPrivate::InitializeImpl(
756 const std::string& gpu_blacklist_json, 749 const std::string& gpu_blacklist_json,
757 const std::string& gpu_switching_list_json, 750 const std::string& gpu_switching_list_json,
758 const std::string& gpu_driver_bug_list_json, 751 const std::string& gpu_driver_bug_list_json,
759 const GPUInfo& gpu_info) { 752 const GPUInfo& gpu_info) {
760 std::string browser_version_string = ProcessVersionString( 753 std::string browser_version_string = ProcessVersionString(
761 GetContentClient()->GetProduct()); 754 GetContentClient()->GetProduct());
762 CHECK(!browser_version_string.empty()); 755 CHECK(!browser_version_string.empty());
763 756
764 if (!gpu_blacklist_json.empty()) { 757 if (!gpu_blacklist_json.empty()) {
765 gpu_blacklist_.reset(GpuBlacklist::Create()); 758 gpu_blacklist_.reset(GpuBlacklist::Create());
766 gpu_blacklist_->LoadList( 759 gpu_blacklist_->LoadList(
767 browser_version_string, gpu_blacklist_json, 760 browser_version_string, gpu_blacklist_json,
768 GpuControlList::kCurrentOsOnly); 761 GpuControlList::kCurrentOsOnly);
769 } 762 }
770 if (!gpu_switching_list_json.empty()) { 763 if (!gpu_switching_list_json.empty()) {
771 gpu_switching_list_.reset(GpuSwitchingList::Create()); 764 gpu_switching_list_.reset(GpuSwitchingList::Create());
772 gpu_switching_list_->LoadList( 765 gpu_switching_list_->LoadList(
773 browser_version_string, gpu_switching_list_json, 766 browser_version_string, gpu_switching_list_json,
774 GpuControlList::kCurrentOsOnly); 767 GpuControlList::kCurrentOsOnly);
775 } 768 }
776 if (!gpu_driver_bug_list_json.empty()) { 769 if (!gpu_driver_bug_list_json.empty()) {
777 gpu_driver_bug_list_.reset(GpuDriverBugList::Create()); 770 gpu_driver_bug_list_.reset(GpuDriverBugList::Create());
778 gpu_driver_bug_list_->LoadList( 771 gpu_driver_bug_list_->LoadList(
779 browser_version_string, gpu_driver_bug_list_json, 772 browser_version_string, gpu_driver_bug_list_json,
780 GpuControlList::kCurrentOsOnly); 773 GpuControlList::kCurrentOsOnly);
781 } 774 }
782 775
783 { 776 gpu_info_ = gpu_info;
784 base::AutoLock auto_lock(gpu_info_lock_);
785 gpu_info_ = gpu_info;
786 }
787 UpdateGpuInfo(gpu_info); 777 UpdateGpuInfo(gpu_info);
788 UpdateGpuSwitchingManager(gpu_info); 778 UpdateGpuSwitchingManager(gpu_info);
789 UpdatePreliminaryBlacklistedFeatures(); 779 UpdatePreliminaryBlacklistedFeatures();
790 } 780 }
791 781
792 void GpuDataManagerImpl::UpdateBlacklistedFeatures( 782 void GpuDataManagerImplPrivate::UpdateBlacklistedFeatures(
793 const std::set<int>& features) { 783 const std::set<int>& features) {
794 CommandLine* command_line = CommandLine::ForCurrentProcess(); 784 CommandLine* command_line = CommandLine::ForCurrentProcess();
795 blacklisted_features_ = features; 785 blacklisted_features_ = features;
796 786
797 // Force disable using the GPU for these features, even if they would 787 // Force disable using the GPU for these features, even if they would
798 // otherwise be allowed. 788 // otherwise be allowed.
799 if (card_blacklisted_ || 789 if (card_blacklisted_ ||
800 command_line->HasSwitch(switches::kBlacklistAcceleratedCompositing)) { 790 command_line->HasSwitch(switches::kBlacklistAcceleratedCompositing)) {
801 blacklisted_features_.insert(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING); 791 blacklisted_features_.insert(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING);
802 } 792 }
803 if (card_blacklisted_ || 793 if (card_blacklisted_ ||
804 command_line->HasSwitch(switches::kBlacklistWebGL)) { 794 command_line->HasSwitch(switches::kBlacklistWebGL)) {
805 blacklisted_features_.insert(GPU_FEATURE_TYPE_WEBGL); 795 blacklisted_features_.insert(GPU_FEATURE_TYPE_WEBGL);
806 } 796 }
807 797
808 EnableSwiftShaderIfNecessary(); 798 EnableSwiftShaderIfNecessary();
809 } 799 }
810 800
811 void GpuDataManagerImpl::UpdatePreliminaryBlacklistedFeatures() { 801 void GpuDataManagerImplPrivate::UpdatePreliminaryBlacklistedFeatures() {
812 preliminary_blacklisted_features_ = blacklisted_features_; 802 preliminary_blacklisted_features_ = blacklisted_features_;
813 } 803 }
814 804
815 void GpuDataManagerImpl::UpdateGpuSwitchingManager(const GPUInfo& gpu_info) { 805 void GpuDataManagerImplPrivate::UpdateGpuSwitchingManager(
806 const GPUInfo& gpu_info) {
816 ui::GpuSwitchingManager::GetInstance()->SetGpuCount( 807 ui::GpuSwitchingManager::GetInstance()->SetGpuCount(
817 gpu_info.secondary_gpus.size() + 1); 808 gpu_info.secondary_gpus.size() + 1);
818 809
819 if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus()) { 810 if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus()) {
820 switch (gpu_switching_) { 811 switch (gpu_switching_) {
821 case GPU_SWITCHING_OPTION_FORCE_DISCRETE: 812 case GPU_SWITCHING_OPTION_FORCE_DISCRETE:
822 ui::GpuSwitchingManager::GetInstance()->ForceUseOfDiscreteGpu(); 813 ui::GpuSwitchingManager::GetInstance()->ForceUseOfDiscreteGpu();
823 break; 814 break;
824 case GPU_SWITCHING_OPTION_FORCE_INTEGRATED: 815 case GPU_SWITCHING_OPTION_FORCE_INTEGRATED:
825 ui::GpuSwitchingManager::GetInstance()->ForceUseOfIntegratedGpu(); 816 ui::GpuSwitchingManager::GetInstance()->ForceUseOfIntegratedGpu();
826 break; 817 break;
827 case GPU_SWITCHING_OPTION_AUTOMATIC: 818 case GPU_SWITCHING_OPTION_AUTOMATIC:
828 case GPU_SWITCHING_OPTION_UNKNOWN: 819 case GPU_SWITCHING_OPTION_UNKNOWN:
829 break; 820 break;
830 } 821 }
831 } 822 }
832 } 823 }
833 824
834 void GpuDataManagerImpl::NotifyGpuInfoUpdate() { 825 void GpuDataManagerImplPrivate::NotifyGpuInfoUpdate() {
835 observer_list_->Notify(&GpuDataManagerObserver::OnGpuInfoUpdate); 826 observer_list_->Notify(&GpuDataManagerObserver::OnGpuInfoUpdate);
836 } 827 }
837 828
838 void GpuDataManagerImpl::EnableSwiftShaderIfNecessary() { 829 void GpuDataManagerImplPrivate::EnableSwiftShaderIfNecessary() {
839 if (!GpuAccessAllowed(NULL) || 830 if (!GpuAccessAllowed(NULL) ||
840 blacklisted_features_.count(GPU_FEATURE_TYPE_WEBGL)) { 831 blacklisted_features_.count(GPU_FEATURE_TYPE_WEBGL)) {
841 if (!swiftshader_path_.empty() && 832 if (!swiftshader_path_.empty() &&
842 !CommandLine::ForCurrentProcess()->HasSwitch( 833 !CommandLine::ForCurrentProcess()->HasSwitch(
843 switches::kDisableSoftwareRasterizer)) 834 switches::kDisableSoftwareRasterizer))
844 use_swiftshader_ = true; 835 use_swiftshader_ = true;
845 } 836 }
846 } 837 }
847 838
848 std::string GpuDataManagerImpl::GetDomainFromURL(const GURL& url) const { 839 std::string GpuDataManagerImplPrivate::GetDomainFromURL(
840 const GURL& url) const {
849 // For the moment, we just use the host, or its IP address, as the 841 // For the moment, we just use the host, or its IP address, as the
850 // entry in the set, rather than trying to figure out the top-level 842 // entry in the set, rather than trying to figure out the top-level
851 // domain. This does mean that a.foo.com and b.foo.com will be 843 // domain. This does mean that a.foo.com and b.foo.com will be
852 // treated independently in the blocking of a given domain, but it 844 // treated independently in the blocking of a given domain, but it
853 // would require a third-party library to reliably figure out the 845 // would require a third-party library to reliably figure out the
854 // top-level domain from a URL. 846 // top-level domain from a URL.
855 if (!url.has_host()) { 847 if (!url.has_host()) {
856 return std::string(); 848 return std::string();
857 } 849 }
858 850
859 return url.host(); 851 return url.host();
860 } 852 }
861 853
862 void GpuDataManagerImpl::BlockDomainFrom3DAPIsAtTime( 854 void GpuDataManagerImplPrivate::BlockDomainFrom3DAPIsAtTime(
863 const GURL& url, DomainGuilt guilt, base::Time at_time) { 855 const GURL& url,
856 GpuDataManagerImpl::DomainGuilt guilt,
857 base::Time at_time) {
864 if (!domain_blocking_enabled_) 858 if (!domain_blocking_enabled_)
865 return; 859 return;
866 860
867 std::string domain = GetDomainFromURL(url); 861 std::string domain = GetDomainFromURL(url);
868 862
869 base::AutoLock auto_lock(gpu_info_lock_);
870 DomainBlockEntry& entry = blocked_domains_[domain]; 863 DomainBlockEntry& entry = blocked_domains_[domain];
871 entry.last_guilt = guilt; 864 entry.last_guilt = guilt;
872 timestamps_of_gpu_resets_.push_back(at_time); 865 timestamps_of_gpu_resets_.push_back(at_time);
873 } 866 }
874 867
875 GpuDataManagerImpl::DomainBlockStatus 868 GpuDataManagerImpl::DomainBlockStatus
876 GpuDataManagerImpl::Are3DAPIsBlockedAtTime( 869 GpuDataManagerImplPrivate::Are3DAPIsBlockedAtTime(
877 const GURL& url, base::Time at_time) const { 870 const GURL& url, base::Time at_time) const {
878 if (!domain_blocking_enabled_) 871 if (!domain_blocking_enabled_)
879 return DOMAIN_BLOCK_STATUS_NOT_BLOCKED; 872 return GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED;
880 873
881 // Note: adjusting the policies in this code will almost certainly 874 // Note: adjusting the policies in this code will almost certainly
882 // require adjusting the associated unit tests. 875 // require adjusting the associated unit tests.
883 std::string domain = GetDomainFromURL(url); 876 std::string domain = GetDomainFromURL(url);
884 877
885 base::AutoLock auto_lock(gpu_info_lock_); 878 DomainBlockMap::const_iterator iter = blocked_domains_.find(domain);
886 { 879 if (iter != blocked_domains_.end()) {
887 DomainBlockMap::const_iterator iter = blocked_domains_.find(domain); 880 // Err on the side of caution, and assume that if a particular
888 if (iter != blocked_domains_.end()) { 881 // domain shows up in the block map, it's there for a good
889 // Err on the side of caution, and assume that if a particular 882 // reason and don't let its presence there automatically expire.
890 // domain shows up in the block map, it's there for a good
891 // reason and don't let its presence there automatically expire.
892 883
893 UMA_HISTOGRAM_ENUMERATION("GPU.BlockStatusForClient3DAPIs", 884 UMA_HISTOGRAM_ENUMERATION("GPU.BlockStatusForClient3DAPIs",
894 BLOCK_STATUS_SPECIFIC_DOMAIN_BLOCKED, 885 BLOCK_STATUS_SPECIFIC_DOMAIN_BLOCKED,
895 BLOCK_STATUS_MAX); 886 BLOCK_STATUS_MAX);
896 887
897 return DOMAIN_BLOCK_STATUS_BLOCKED; 888 return GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_BLOCKED;
898 }
899 } 889 }
900 890
901 // Look at the timestamps of the recent GPU resets to see if there are 891 // Look at the timestamps of the recent GPU resets to see if there are
902 // enough within the threshold which would cause us to blacklist all 892 // enough within the threshold which would cause us to blacklist all
903 // domains. This doesn't need to be overly precise -- if time goes 893 // domains. This doesn't need to be overly precise -- if time goes
904 // backward due to a system clock adjustment, that's fine. 894 // backward due to a system clock adjustment, that's fine.
905 // 895 //
906 // TODO(kbr): make this pay attention to the TDR thresholds in the 896 // TODO(kbr): make this pay attention to the TDR thresholds in the
907 // Windows registry, but make sure it continues to be testable. 897 // Windows registry, but make sure it continues to be testable.
908 std::list<base::Time>::iterator iter = timestamps_of_gpu_resets_.begin(); 898 {
909 int num_resets_within_timeframe = 0; 899 std::list<base::Time>::iterator iter = timestamps_of_gpu_resets_.begin();
910 while (iter != timestamps_of_gpu_resets_.end()) { 900 int num_resets_within_timeframe = 0;
911 base::Time time = *iter; 901 while (iter != timestamps_of_gpu_resets_.end()) {
912 base::TimeDelta delta_t = at_time - time; 902 base::Time time = *iter;
903 base::TimeDelta delta_t = at_time - time;
913 904
914 // If this entry has "expired", just remove it. 905 // If this entry has "expired", just remove it.
915 if (delta_t.InMilliseconds() > kBlockAllDomainsMs) { 906 if (delta_t.InMilliseconds() > kBlockAllDomainsMs) {
916 iter = timestamps_of_gpu_resets_.erase(iter); 907 iter = timestamps_of_gpu_resets_.erase(iter);
917 continue; 908 continue;
909 }
910
911 ++num_resets_within_timeframe;
912 ++iter;
918 } 913 }
919 914
920 ++num_resets_within_timeframe; 915 if (num_resets_within_timeframe >= kNumResetsWithinDuration) {
921 ++iter; 916 UMA_HISTOGRAM_ENUMERATION("GPU.BlockStatusForClient3DAPIs",
922 } 917 BLOCK_STATUS_ALL_DOMAINS_BLOCKED,
918 BLOCK_STATUS_MAX);
923 919
924 if (num_resets_within_timeframe >= kNumResetsWithinDuration) { 920 return GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_ALL_DOMAINS_BLOCKED;
925 UMA_HISTOGRAM_ENUMERATION("GPU.BlockStatusForClient3DAPIs", 921 }
926 BLOCK_STATUS_ALL_DOMAINS_BLOCKED,
927 BLOCK_STATUS_MAX);
928
929 return DOMAIN_BLOCK_STATUS_ALL_DOMAINS_BLOCKED;
930 } 922 }
931 923
932 UMA_HISTOGRAM_ENUMERATION("GPU.BlockStatusForClient3DAPIs", 924 UMA_HISTOGRAM_ENUMERATION("GPU.BlockStatusForClient3DAPIs",
933 BLOCK_STATUS_NOT_BLOCKED, 925 BLOCK_STATUS_NOT_BLOCKED,
934 BLOCK_STATUS_MAX); 926 BLOCK_STATUS_MAX);
935 927
936 return DOMAIN_BLOCK_STATUS_NOT_BLOCKED; 928 return GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED;
937 } 929 }
938 930
939 int64 GpuDataManagerImpl::GetBlockAllDomainsDurationInMs() const { 931 int64 GpuDataManagerImplPrivate::GetBlockAllDomainsDurationInMs() const {
940 return kBlockAllDomainsMs; 932 return kBlockAllDomainsMs;
941 } 933 }
942 934
943 void GpuDataManagerImpl::Notify3DAPIBlocked(const GURL& url, 935 void GpuDataManagerImplPrivate::Notify3DAPIBlocked(const GURL& url,
944 int render_process_id, 936 int render_process_id,
945 int render_view_id, 937 int render_view_id,
946 ThreeDAPIType requester) { 938 ThreeDAPIType requester) {
939 GpuDataManagerImpl::UnlockedSession session(owner_);
947 observer_list_->Notify(&GpuDataManagerObserver::DidBlock3DAPIs, 940 observer_list_->Notify(&GpuDataManagerObserver::DidBlock3DAPIs,
948 url, render_process_id, render_view_id, requester); 941 url, render_process_id, render_view_id, requester);
949 } 942 }
950 943
951 } // namespace content 944 } // namespace content
945
OLDNEW
« no previous file with comments | « content/browser/gpu/gpu_data_manager_impl_private.h ('k') | content/browser/gpu/gpu_data_manager_impl_private_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698