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.
4
5#ifndef CONTENT_BROWSER_GPU_GPU_DATA_MANAGER_IMPL_PRIVATE_H_
6#define CONTENT_BROWSER_GPU_GPU_DATA_MANAGER_IMPL_PRIVATE_H_
7
8#include <list>
9#include <map>
10#include <set>
11#include <string>
12#include <vector>
13
14#include "base/memory/ref_counted.h"
15#include "base/memory/singleton.h"
16#include "base/observer_list_threadsafe.h"
17#include "content/browser/gpu/gpu_data_manager_impl.h"
18#include "gpu/config/gpu_blacklist.h"
19#include "gpu/config/gpu_driver_bug_list.h"
20
21namespace base {
22class CommandLine;
23}
24
25namespace content {
26
27class CONTENT_EXPORT GpuDataManagerImplPrivate {
28 public:
29  static GpuDataManagerImplPrivate* Create(GpuDataManagerImpl* owner);
30
31  void InitializeForTesting(
32      const std::string& gpu_blacklist_json,
33      const gpu::GPUInfo& gpu_info);
34  bool IsFeatureBlacklisted(int feature) const;
35  bool IsDriverBugWorkaroundActive(int feature) const;
36  gpu::GPUInfo GetGPUInfo() const;
37  void GetGpuProcessHandles(
38      const GpuDataManager::GetGpuProcessHandlesCallback& callback) const;
39  bool GpuAccessAllowed(std::string* reason) const;
40  void RequestCompleteGpuInfoIfNeeded();
41  bool IsEssentialGpuInfoAvailable() const;
42  bool IsCompleteGpuInfoAvailable() const;
43  void RequestVideoMemoryUsageStatsUpdate() const;
44  bool ShouldUseSwiftShader() const;
45  void RegisterSwiftShaderPath(const base::FilePath& path);
46  bool ShouldUseWarp() const;
47  void AddObserver(GpuDataManagerObserver* observer);
48  void RemoveObserver(GpuDataManagerObserver* observer);
49  void UnblockDomainFrom3DAPIs(const GURL& url);
50  void DisableGpuWatchdog();
51  void SetGLStrings(const std::string& gl_vendor,
52                    const std::string& gl_renderer,
53                    const std::string& gl_version);
54  void GetGLStrings(std::string* gl_vendor,
55                    std::string* gl_renderer,
56                    std::string* gl_version);
57  void DisableHardwareAcceleration();
58
59  void Initialize();
60
61  void UpdateGpuInfo(const gpu::GPUInfo& gpu_info);
62
63  void UpdateVideoMemoryUsageStats(
64      const GPUVideoMemoryUsageStats& video_memory_usage_stats);
65
66  void AppendRendererCommandLine(base::CommandLine* command_line) const;
67
68  void AppendGpuCommandLine(base::CommandLine* command_line) const;
69
70  void AppendPluginCommandLine(base::CommandLine* command_line) const;
71
72  void UpdateRendererWebPrefs(WebPreferences* prefs) const;
73
74  std::string GetBlacklistVersion() const;
75  std::string GetDriverBugListVersion() const;
76
77  void GetBlacklistReasons(base::ListValue* reasons) const;
78
79  void GetDriverBugWorkarounds(base::ListValue* workarounds) const;
80
81  void AddLogMessage(int level,
82                     const std::string& header,
83                     const std::string& message);
84
85  void ProcessCrashed(base::TerminationStatus exit_code);
86
87  base::ListValue* GetLogMessages() const;
88
89  void HandleGpuSwitch();
90
91  bool CanUseGpuBrowserCompositor() const;
92
93  void BlockDomainFrom3DAPIs(
94      const GURL& url, GpuDataManagerImpl::DomainGuilt guilt);
95  bool Are3DAPIsBlocked(const GURL& url,
96                        int render_process_id,
97                        int render_view_id,
98                        ThreeDAPIType requester);
99
100  void DisableDomainBlockingFor3DAPIsForTesting();
101
102  void Notify3DAPIBlocked(const GURL& url,
103                          int render_process_id,
104                          int render_view_id,
105                          ThreeDAPIType requester);
106
107  size_t GetBlacklistedFeatureCount() const;
108
109  void SetDisplayCount(unsigned int display_count);
110  unsigned int GetDisplayCount() const;
111
112  bool UpdateActiveGpu(uint32 vendor_id, uint32 device_id);
113
114  void OnGpuProcessInitFailure();
115
116  virtual ~GpuDataManagerImplPrivate();
117
118 private:
119  friend class GpuDataManagerImplPrivateTest;
120
121  FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTest,
122                           GpuSideBlacklisting);
123  FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTest,
124                           GpuSideExceptions);
125  FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTest,
126                           DisableHardwareAcceleration);
127  FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTest,
128                           SwiftShaderRendering);
129  FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTest,
130                           SwiftShaderRendering2);
131  FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTest,
132                           WarpEnabledOverridesSwiftShader);
133  FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTest,
134                           GpuInfoUpdate);
135  FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTest,
136                           NoGpuInfoUpdateWithSwiftShader);
137  FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTest,
138                           GPUVideoMemoryUsageStatsUpdate);
139  FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTest,
140                           BlockAllDomainsFrom3DAPIs);
141  FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTest,
142                           UnblockGuiltyDomainFrom3DAPIs);
143  FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTest,
144                           UnblockDomainOfUnknownGuiltFrom3DAPIs);
145  FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTest,
146                           UnblockOtherDomainFrom3DAPIs);
147  FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTest,
148                           UnblockThisDomainFrom3DAPIs);
149#if defined(OS_LINUX)
150  FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTest,
151                           SetGLStrings);
152  FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTest,
153                           SetGLStringsNoEffects);
154#endif
155  FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTest,
156                           GpuDriverBugListSingle);
157  FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTest,
158                           GpuDriverBugListMultiple);
159  FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTest,
160                           BlacklistAllFeatures);
161
162  struct DomainBlockEntry {
163    GpuDataManagerImpl::DomainGuilt last_guilt;
164  };
165
166  typedef std::map<std::string, DomainBlockEntry> DomainBlockMap;
167
168  typedef ObserverListThreadSafe<GpuDataManagerObserver>
169      GpuDataManagerObserverList;
170
171  struct LogMessage {
172    int level;
173    std::string header;
174    std::string message;
175
176    LogMessage(int _level,
177               const std::string& _header,
178               const std::string& _message)
179        : level(_level),
180          header(_header),
181          message(_message) { }
182  };
183
184  explicit GpuDataManagerImplPrivate(GpuDataManagerImpl* owner);
185
186  void InitializeImpl(const std::string& gpu_blacklist_json,
187                      const std::string& gpu_driver_bug_list_json,
188                      const gpu::GPUInfo& gpu_info);
189
190  void UpdateGpuInfoHelper();
191
192  void UpdateBlacklistedFeatures(const std::set<int>& features);
193
194  // This should only be called once at initialization time, when preliminary
195  // gpu info is collected.
196  void UpdatePreliminaryBlacklistedFeatures();
197
198  // Update the GPU switching status.
199  // This should only be called once at initialization time.
200  void UpdateGpuSwitchingManager(const gpu::GPUInfo& gpu_info);
201
202  // Notify all observers whenever there is a GPU info update.
203  void NotifyGpuInfoUpdate();
204
205  // Try to switch to SwiftShader rendering, if possible and necessary.
206  void EnableSwiftShaderIfNecessary();
207
208  // Try to switch to WARP rendering if the GPU hardware is not supported or
209  // absent, and if we are trying to run in Windows Metro mode.
210  void EnableWarpIfNecessary();
211
212  // Use only for testing, forces |use_warp_| to true.
213  void ForceWarpModeForTesting();
214
215  // Helper to extract the domain from a given URL.
216  std::string GetDomainFromURL(const GURL& url) const;
217
218  // Implementation functions for blocking of 3D graphics APIs, used
219  // for unit testing.
220  void BlockDomainFrom3DAPIsAtTime(const GURL& url,
221                                   GpuDataManagerImpl::DomainGuilt guilt,
222                                   base::Time at_time);
223  GpuDataManagerImpl::DomainBlockStatus Are3DAPIsBlockedAtTime(
224      const GURL& url, base::Time at_time) const;
225  int64 GetBlockAllDomainsDurationInMs() const;
226
227  bool complete_gpu_info_already_requested_;
228
229  std::set<int> blacklisted_features_;
230  std::set<int> preliminary_blacklisted_features_;
231
232  std::set<int> gpu_driver_bugs_;
233
234  gpu::GPUInfo gpu_info_;
235
236  scoped_ptr<gpu::GpuBlacklist> gpu_blacklist_;
237  scoped_ptr<gpu::GpuDriverBugList> gpu_driver_bug_list_;
238
239  const scoped_refptr<GpuDataManagerObserverList> observer_list_;
240
241  std::vector<LogMessage> log_messages_;
242
243  bool use_swiftshader_;
244
245  bool use_warp_;
246
247  base::FilePath swiftshader_path_;
248
249  // Current card force-blacklisted due to GPU crashes, or disabled through
250  // the --disable-gpu commandline switch.
251  bool card_blacklisted_;
252
253  // We disable histogram stuff in testing, especially in unit tests because
254  // they cause random failures.
255  bool update_histograms_;
256
257  // Number of currently open windows, to be used in gpu memory allocation.
258  int window_count_;
259
260  DomainBlockMap blocked_domains_;
261  mutable std::list<base::Time> timestamps_of_gpu_resets_;
262  bool domain_blocking_enabled_;
263
264  GpuDataManagerImpl* owner_;
265
266  unsigned int display_count_;
267
268  bool gpu_process_accessible_;
269
270  // True if all future Initialize calls should be ignored.
271  bool finalized_;
272
273  DISALLOW_COPY_AND_ASSIGN(GpuDataManagerImplPrivate);
274};
275
276}  // namespace content
277
278#endif  // CONTENT_BROWSER_GPU_GPU_DATA_MANAGER_IMPL_PRIVATE_H_
279
280