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

Side by Side Diff: chrome/browser/gpu_blacklist.cc

Issue 5612002: Blacklist bad GPU drivers: currenly we disable all gpu related features if th... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: removing one garbage line in the code Created 10 years 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
(Empty)
1 // Copyright (c) 2010 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 #include "chrome/browser/gpu_blacklist.h"
6
7 #include "base/json/json_reader.h"
8 #include "base/logging.h"
9 #include "base/stringprintf.h"
10 #include "base/string_number_conversions.h"
11 #include "base/sys_info.h"
12 #include "base/values.h"
13 #include "base/version.h"
14 #include "chrome/common/gpu_info.h"
15
16 GpuBlacklist::VersionInfo::VersionInfo(const std::string& version_op,
17 const std::string& version_string,
18 const std::string& version_string2) {
19 op_ = StringToOp(version_op);
20 if (op_ == kUnknown || op_ == kAny)
21 return;
22 version_.reset(Version::GetVersionFromString(version_string));
23 if (version_.get() == NULL) {
24 op_ = kUnknown;
25 return;
26 }
27 if (op_ == kBetween) {
28 version2_.reset(Version::GetVersionFromString(version_string2));
29 if (version2_.get() == NULL)
30 op_ = kUnknown;
31 }
32 }
33
34 GpuBlacklist::VersionInfo::~VersionInfo() {
35 }
36
37 bool GpuBlacklist::VersionInfo::Contains(const Version& version) const {
38 if (op_ == kUnknown)
39 return false;
40 if (op_ == kAny)
41 return true;
42 if (op_ == kEQ) {
43 // Handles cases where 10.6 is considered as containing 10.6.*.
44 const std::vector<uint16>& components_reference = version_->components();
45 const std::vector<uint16>& components = version.components();
46 for (size_t i = 0; i < components_reference.size(); ++i) {
47 if (i >= components.size() && components_reference[i] != 0)
48 return false;
49 if (components[i] != components_reference[i])
50 return false;
51 }
52 return true;
53 }
54 int relation = version.CompareTo(*version_);
55 if (op_ == kEQ)
56 return (relation == 0);
57 else if (op_ == kLT)
58 return (relation < 0);
59 else if (op_ == kLE)
60 return (relation <= 0);
61 else if (op_ == kGT)
62 return (relation > 0);
63 else if (op_ == kGE)
64 return (relation >= 0);
65 // op_ == kBetween
66 if (relation < 0)
67 return false;
68 return version.CompareTo(*version2_) <= 0;
69 }
70
71 bool GpuBlacklist::VersionInfo::IsValid() const {
72 return op_ != kUnknown;
73 }
74
75 GpuBlacklist::VersionInfo::Op GpuBlacklist::VersionInfo::StringToOp(
76 const std::string& version_op) {
77 if (version_op == "=")
78 return kEQ;
79 else if (version_op == "<")
80 return kLT;
81 else if (version_op == "<=")
82 return kLE;
83 else if (version_op == ">")
84 return kGT;
85 else if (version_op == ">=")
86 return kGE;
87 else if (version_op == "any")
88 return kAny;
89 else if (version_op == "between")
90 return kBetween;
91 return kUnknown;
92 }
93
94 GpuBlacklist::OsInfo::OsInfo(const std::string& os,
95 const std::string& version_op,
96 const std::string& version_string,
97 const std::string& version_string2) {
98 type_ = StringToOsType(os);
99 if (type_ != kOsUnknown) {
100 version_info_.reset(
101 new VersionInfo(version_op, version_string, version_string2));
102 }
103 }
104
105 bool GpuBlacklist::OsInfo::Contains(OsType type,
106 const Version& version) const {
107 if (!IsValid())
108 return false;
109 if (type_ != type && type_ != kOsAny)
110 return false;
111 return version_info_->Contains(version);
112 }
113
114 bool GpuBlacklist::OsInfo::IsValid() const {
115 return type_ != kOsUnknown && version_info_->IsValid();
116 }
117
118 GpuBlacklist::OsType GpuBlacklist::OsInfo::type() const {
119 return type_;
120 }
121
122 GpuBlacklist::GpuBlacklistEntry*
123 GpuBlacklist::GpuBlacklistEntry::GetGpuBlacklistEntryFromValue(
124 DictionaryValue* value) {
125 if (value == NULL)
126 return NULL;
127
128 GpuBlacklistEntry* entry = new GpuBlacklistEntry();
129
130 DictionaryValue* os_value = NULL;
131 if (value->GetDictionary("os", &os_value)) {
132 std::string os_type = "";
vangelis 2010/12/08 00:17:38 I think the default value for an std::string is th
Zhenyao Mo 2010/12/09 00:06:06 Done.
133 std::string os_version_op = "any";
134 std::string os_version_string = "";
135 std::string os_version_string2 = "";
136 os_value->GetString("type", &os_type);
137 DictionaryValue* os_version_value = NULL;
138 if (os_value->GetDictionary("version", &os_version_value)) {
139 os_version_value->GetString("op", &os_version_op);
140 os_version_value->GetString("number", &os_version_string);
141 os_version_value->GetString("number2", &os_version_string2);
142 }
143 if (!entry->SetOsInfo(os_type, os_version_op, os_version_string,
144 os_version_string2)) {
145 delete entry;
146 return NULL;
147 }
148 }
149
150 std::string vendor_id = "";
151 if (value->GetString("vendor_id", &vendor_id)) {
152 if (!entry->SetVendorId(vendor_id)) {
153 delete entry;
154 return NULL;
155 }
156 }
157
158 std::string device_id = "";
159 if (value->GetString("device_id", &device_id)) {
160 if (!entry->SetDeviceId(device_id)) {
161 delete entry;
162 return NULL;
163 }
164 }
165
166 DictionaryValue* driver_version_value = NULL;
167 if (value->GetDictionary("driver_version", &driver_version_value)) {
168 std::string driver_version_op = "any";
169 std::string driver_version_string = "";
170 std::string driver_version_string2 = "";
171 driver_version_value->GetString("op", &driver_version_op);
172 driver_version_value->GetString("number", &driver_version_string);
173 driver_version_value->GetString("number2", &driver_version_string2);
174 if (!entry->SetDriverVersionInfo(driver_version_op, driver_version_string,
175 driver_version_string2)) {
176 delete entry;
177 return NULL;
178 }
179 }
180
181 ListValue* blacklist_value = NULL;
182 if (!value->GetList("blacklist", &blacklist_value)) {
183 delete entry;
184 return NULL;
185 }
186 std::vector<std::string> blacklist;
187 for (size_t i = 0; i < blacklist_value->GetSize(); ++i) {
188 std::string feature = "";
189 if (blacklist_value->GetString(i, &feature)) {
190 blacklist.push_back(feature);
191 } else {
192 delete entry;
193 return NULL;
194 }
195 }
196 if (!entry->SetBlacklistedFeatures(blacklist)) {
197 delete entry;
198 return NULL;
199 }
200
201 return entry;
202 }
203
204 GpuBlacklist::GpuBlacklistEntry::GpuBlacklistEntry()
205 : vendor_id_(0),
206 device_id_(0) {
207 }
208
209 bool GpuBlacklist::GpuBlacklistEntry::SetOsInfo(
210 const std::string& os,
211 const std::string& version_op,
212 const std::string& version_string,
213 const std::string& version_string2) {
214 os_info_.reset(new OsInfo(os, version_op, version_string, version_string2));
215 return os_info_->IsValid();
216 }
217
218 bool GpuBlacklist::GpuBlacklistEntry::SetVendorId(
219 const std::string& vendor_id_string) {
220 vendor_id_ = 0;
221 return base::HexStringToInt(vendor_id_string,
222 reinterpret_cast<int*>(&vendor_id_));
223 }
224
225 bool GpuBlacklist::GpuBlacklistEntry::SetDeviceId(
226 const std::string& device_id_string) {
227 device_id_ = 0;
228 return base::HexStringToInt(device_id_string,
229 reinterpret_cast<int*>(&device_id_));
230 }
231
232 bool GpuBlacklist::GpuBlacklistEntry::SetDriverVersionInfo(
233 const std::string& version_op,
234 const std::string& version_string,
235 const std::string& version_string2) {
236 driver_version_info_.reset(
237 new VersionInfo(version_op, version_string, version_string2));
238 return driver_version_info_->IsValid();
239 }
240
241 bool GpuBlacklist::GpuBlacklistEntry::SetBlacklistedFeatures(
242 const std::vector<std::string>& blacklisted_features) {
243 size_t size = blacklisted_features.size();
244 if (size == 0)
245 return false;
246 bool accelerated_2d_canvas = false;
247 bool accelerated_compositing = false;
248 bool webgl = false;
249 for (size_t i = 0; i < size; ++i) {
250 GpuFeatureFlags::GpuFeatureType type =
251 GpuFeatureFlags::StringToGpuFeatureType(blacklisted_features[i]);
252 switch (type) {
253 case GpuFeatureFlags::kGpuFeatureAny:
254 if (size == 1) {
255 feature_flags_.reset(new GpuFeatureFlags());
256 feature_flags_->SetFlags(true, true, true);
257 return true;
258 }
259 return false;
260 case GpuFeatureFlags::kGpuFeatureAccelerated2dCanvas:
261 accelerated_2d_canvas = true;
262 break;
263 case GpuFeatureFlags::kGpuFeatureAcceleratedCompositing:
264 accelerated_compositing = true;
265 break;
266 case GpuFeatureFlags::kGpuFeatureWebgl:
267 webgl = true;
268 break;
269 default:
270 return false;
271 }
272 }
273 feature_flags_.reset(new GpuFeatureFlags());
274 feature_flags_->SetFlags(accelerated_2d_canvas,
275 accelerated_compositing,
276 webgl);
277 return true;
278 }
279
280 bool GpuBlacklist::GpuBlacklistEntry::Contains(
281 OsType os_type, const Version& os_version,
282 uint32 vendor_id, uint32 device_id,
283 const Version& driver_version) const {
284 DCHECK(os_type != kOsAny);
285 if (os_info_.get() != NULL && !os_info_->Contains(os_type, os_version))
286 return false;
287 if (vendor_id_ != 0 && vendor_id_ != vendor_id)
288 return false;
289 if (device_id_ != 0 && device_id_ != device_id)
290 return false;
291 if (driver_version_info_.get() == NULL)
292 return true;
293 return driver_version_info_->Contains(driver_version);
294 }
295
296 GpuBlacklist::OsType GpuBlacklist::GpuBlacklistEntry::GetOsType() const {
297 if (os_info_.get() == NULL)
298 return kOsUnknown;
299 return os_info_->type();
300 }
301
302 GpuFeatureFlags GpuBlacklist::GpuBlacklistEntry::GetGpuFeatureFlags() const {
303 return *feature_flags_;
304 }
305
306 GpuBlacklist::GpuBlacklist() {
307 }
308
309 GpuBlacklist::~GpuBlacklist() {
310 Clear();
311 }
312
313 bool GpuBlacklist::LoadGpuBlacklist(const std::string& json_context,
314 bool current_os_only) {
315 std::vector<GpuBlacklistEntry*> entries;
316 scoped_ptr<Value> root;
317 root.reset(base::JSONReader::Read(json_context, false));
318 if (root.get() == NULL || !root->IsType(Value::TYPE_DICTIONARY))
319 return false;
320
321 ListValue* list = NULL;
322 static_cast<DictionaryValue*>(root.get())->GetList("entries", &list);
323 if (list == NULL)
324 return false;
325
326 for (size_t i = 0; i < list->GetSize(); ++i) {
327 DictionaryValue* list_item = NULL;
328 bool valid = list->GetDictionary(i, &list_item);
329 if (!valid)
330 break;
331 GpuBlacklistEntry* entry =
332 GpuBlacklistEntry::GetGpuBlacklistEntryFromValue(list_item);
333 if (entry == NULL)
334 break;
335 entries.push_back(entry);
336 }
337
338 if (entries.size() < list->GetSize()) {
339 for (size_t i = 0; i < entries.size(); ++i)
340 delete entries[i];
341 return false;
342 }
343
344 Clear();
345 // Don't apply GPU blacklist for a non-registered OS.
346 OsType os_filter = GetOsType();
347 if (os_filter != kOsUnknown) {
348 for (size_t i = 0; i < entries.size(); ++i) {
349 OsType entry_os = entries[i]->GetOsType();
350 if (!current_os_only ||
351 entry_os == kOsAny || entry_os == os_filter)
352 blacklist_.push_back(entries[i]);
353 }
354 }
355 return true;
356 }
357
358 GpuFeatureFlags GpuBlacklist::DetermineGpuFeatureFlags(
359 GpuBlacklist::OsType os,
360 Version* os_version,
361 const GPUInfo& gpu_info) const {
362 GpuFeatureFlags flags;
363 if (os == kOsAny)
364 os = GetOsType();
365 scoped_ptr<Version> my_os_version;
366 if (os_version == NULL) {
367 std::string version_string;
368 #if defined(OS_MACOSX)
369 // Seems like base::SysInfo::OperatingSystemVersion() returns the wrong
370 // version in MacOsx.
371 int32 version_major, version_minor, version_bugfix;
372 base::SysInfo::OperatingSystemVersionNumbers(
373 &version_major, &version_minor, &version_bugfix);
374 version_string = base::StringPrintf("%d.%d.%d",
375 version_major,
376 version_minor,
377 version_bugfix);
378 #else
379 version_string = base::SysInfo::OperatingSystemVersion();
380 #endif
381 my_os_version.reset(Version::GetVersionFromString(version_string));
382 os_version = my_os_version.get();
383 }
384 for (size_t i = 0; i < blacklist_.size(); ++i) {
385 scoped_ptr<Version> driver_version(
386 Version::GetVersionFromString(gpu_info.driver_version()));
387 if (blacklist_[i]->Contains(os, *os_version,
388 gpu_info.vendor_id(), gpu_info.device_id(),
389 *driver_version)) {
390 flags.Combine(blacklist_[i]->GetGpuFeatureFlags());
391 }
392 }
393 return flags;
394 }
395
396 GpuBlacklist::OsType GpuBlacklist::StringToOsType(const std::string& os) {
397 if (os == "win")
398 return kOsWin;
399 else if (os == "macosx")
400 return kOsMacosx;
401 else if (os == "linux")
402 return kOsLinux;
403 else if (os == "any")
404 return kOsAny;
405 return kOsUnknown;
406 }
407
408 GpuBlacklist::OsType GpuBlacklist::GetOsType() {
409 #if defined(OS_WIN)
410 return kOsWin;
411 #elif defined(OS_LINUX)
412 return kOsLinux;
413 #elif defined(OS_MACOSX)
414 return kOsMacosx;
415 #else
416 return kOsUnknown;
417 #endif
418 }
419
420 void GpuBlacklist::Clear() {
421 for (size_t i = 0; i < blacklist_.size(); ++i)
422 delete blacklist_[i];
423 blacklist_.clear();
424 }
425
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698