blob: 608b51bed3a7d9b7a2f3342e323e2f6ba5dc8fd8 [file] [log] [blame]
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stddef.h>
#include <set>
#include <string>
#include <vector>
#include "base/containers/hash_tables.h"
#include "base/values.h"
#include "gpu/gpu_export.h"
namespace gpu {
struct GpuControlListData;
struct GPUInfo;
class GPU_EXPORT GpuControlList {
typedef base::hash_map<int, std::string> FeatureMap;
enum OsType {
enum OsFilter {
// In loading, ignore all entries that belong to other OS.
// In loading, keep all entries. This is for testing only.
enum NumericOp {
kBetween, // <= * <=
kEQ, // =
kLT, // <
kLE, // <=
kGT, // >
kGE, // >=
kUnknown // Indicates the data is invalid.
enum MultiGpuStyle {
enum MultiGpuCategory {
// This entry applies if this is the primary GPU on the system.
// This entry applies if this is a secondary GPU on the system.
// This entry applies if this is the active GPU on the system.
// This entry applies if this is any of the GPUs on the system.
enum GLType {
kGLTypeGL, // This is default on MacOSX, Linux, ChromeOS
kGLTypeGLES, // This is default on Android
kGLTypeANGLE, // This is default on Windows
enum VersionStyle {
enum class GpuSeriesType {
// Intel 6th gen
// Intel 7th gen
kIntelValleyView, // BayTrail
// Intel 8th gen
kIntelCherryView, // Braswell
// Intel 9th gen
// Please also update |gpu_series_map| in
struct GPU_EXPORT Version {
NumericOp op;
VersionStyle style;
const char* value1;
const char* value2;
bool IsSpecified() const { return op != kUnknown; }
bool Contains(const std::string& version_string, char splitter) const;
bool Contains(const std::string& version_string) const {
return Contains(version_string, '.');
// Compare two version strings.
// Return 1 if version > version_ref,
// 0 if version = version_ref,
// -1 if version < version_ref.
// Note that we only compare as many segments as both versions contain.
// For example: Compare("10.3.1", "10.3") returns 0,
// Compare("10.3", "10.3.1") returns 0.
// If "version_style" is Lexical, the first segment is compared
// numerically, all other segments are compared lexically.
// Lexical is used for AMD Linux driver versions only.
static int Compare(const std::vector<std::string>& version,
const std::vector<std::string>& version_ref,
VersionStyle version_style);
struct GPU_EXPORT DriverInfo {
const char* driver_vendor;
Version driver_version;
Version driver_date;
bool Contains(const GPUInfo& gpu_info) const;
struct GPU_EXPORT GLStrings {
const char* gl_vendor;
const char* gl_renderer;
const char* gl_extensions;
const char* gl_version;
bool Contains(const GPUInfo& gpu_info) const;
struct GPU_EXPORT MachineModelInfo {
size_t machine_model_name_size;
const char* const* machine_model_names;
Version machine_model_version;
bool Contains(const GPUInfo& gpu_info) const;
struct GPU_EXPORT More {
// These are just part of Entry fields that are less common.
// Putting them to a separate struct to save Entry data size.
GLType gl_type;
Version gl_version;
Version pixel_shader_version;
bool in_process_gpu;
uint32_t gl_reset_notification_strategy;
bool direct_rendering;
Version gpu_count;
uint32_t test_group;
// Return true if GL_VERSION string does not fit the entry info
// on GL type and GL version.
bool GLVersionInfoMismatch(const std::string& gl_version_string) const;
bool Contains(const GPUInfo& gpu_info) const;
// Return the default GL type, depending on the OS.
// See GLType declaration.
static GLType GetDefaultGLType();
struct GPU_EXPORT Conditions {
OsType os_type;
Version os_version;
uint32_t vendor_id;
size_t device_id_size;
const uint32_t* device_ids;
MultiGpuCategory multi_gpu_category;
MultiGpuStyle multi_gpu_style;
const DriverInfo* driver_info;
const GLStrings* gl_strings;
const MachineModelInfo* machine_model_info;
size_t gpu_series_list_size;
const GpuSeriesType* gpu_series_list;
const More* more;
bool Contains(OsType os_type,
const std::string& os_version,
const GPUInfo& gpu_info) const;
// Determines whether we needs more gpu info to make the blacklisting
// decision. It should only be checked if Contains() returns true.
bool NeedsMoreInfo(const GPUInfo& gpu_info) const;
struct GPU_EXPORT Entry {
uint32_t id;
const char* description;
size_t feature_size;
const int* features;
size_t disabled_extension_size;
const char* const* disabled_extensions;
size_t disabled_webgl_extension_size;
const char* const* disabled_webgl_extensions;
size_t cr_bug_size;
const uint32_t* cr_bugs;
Conditions conditions;
size_t exception_size;
const Conditions* exceptions;
bool Contains(OsType os_type,
const std::string& os_version,
const GPUInfo& gpu_info) const;
bool AppliesToTestGroup(uint32_t target_test_group) const;
// Determines whether we needs more gpu info to make the blacklisting
// decision. It should only be checked if Contains() returns true.
bool NeedsMoreInfo(const GPUInfo& gpu_info, bool consider_exceptions) const;
void GetFeatureNames(base::ListValue* feature_names,
const FeatureMap& feature_map) const;
// Logs a control list match for this rule in the list identified by
// |control_list_logging_name|.
void LogControlListMatch(
const std::string& control_list_logging_name) const;
explicit GpuControlList(const GpuControlListData& data);
virtual ~GpuControlList();
// Collects system information and combines them with gpu_info and control
// list information to decide which entries are applied to the current
// system and returns the union of features specified in each entry.
// If os is kOsAny, use the current OS; if os_version is empty, use the
// current OS version.
std::set<int32_t> MakeDecision(OsType os,
const std::string& os_version,
const GPUInfo& gpu_info);
// Same as the above function, but instead of using the entries with no
// "test_group" specified or "test_group" = 0, using the entries with
// "test_group" = |target_test_group|.
std::set<int32_t> MakeDecision(OsType os,
const std::string& os_version,
const GPUInfo& gpu_info,
uint32_t target_test_group);
// Return the active entry indices from the last MakeDecision() call.
const std::vector<uint32_t>& GetActiveEntries() const;
// Return corresponding entry IDs from entry indices.
std::vector<uint32_t> GetEntryIDsFromIndices(
const std::vector<uint32_t>& entry_indices) const;
// Collects all disabled extensions.
std::vector<std::string> GetDisabledExtensions();
// Collects all disabled WebGL extensions.
std::vector<std::string> GetDisabledWebGLExtensions();
// Returns the description and bugs from active entries provided.
// Each problems has:
// {
// "description": "Your GPU is too old",
// "crBugs": [1234],
// }
// The use case is we compute the entries from GPU process and send them to
// browser process, and call GetReasons() in browser process.
void GetReasons(base::ListValue* problem_list,
const std::string& tag,
const std::vector<uint32_t>& entries) const;
// Return the largest entry id. This is used for histogramming.
uint32_t max_entry_id() const;
// Check if we need more gpu info to make the decisions.
// This is computed from the last MakeDecision() call.
// If yes, we should create a gl context and do a full gpu info collection.
bool needs_more_info() const { return needs_more_info_; }
// Returns the number of entries. This is only for tests.
size_t num_entries() const;
// Register a feature to FeatureMap.
void AddSupportedFeature(const std::string& feature_name, int feature_id);
// Enables logging of control list decisions.
void EnableControlListLogging(const std::string& control_list_logging_name) {
control_list_logging_enabled_ = true;
control_list_logging_name_ = control_list_logging_name;
// Return false if an entry index goes beyond |total_entries|.
static bool AreEntryIndicesValid(const std::vector<uint32_t>& entry_indices,
size_t total_entries);
friend class GpuControlListEntryTest;
friend class VersionInfoTest;
// Gets the current OS type.
static OsType GetOsType();
static GpuSeriesType GetGpuSeriesType(uint32_t vendor_id, uint32_t device_id);
size_t entry_count_;
const Entry* entries_;
// This records all the entries that are appliable to the current user
// machine. It is updated everytime MakeDecision() is called and is used
// later by GetDecisionEntries().
std::vector<uint32_t> active_entries_;
uint32_t max_entry_id_;
bool needs_more_info_;
// The features a GpuControlList recognizes and handles.
FeatureMap feature_map_;
bool control_list_logging_enabled_;
std::string control_list_logging_name_;
struct GPU_EXPORT GpuControlListData {
size_t entry_count;
const GpuControlList::Entry* entries;
GpuControlListData() : entry_count(0u), entries(nullptr) {}
GpuControlListData(size_t a_entry_count,
const GpuControlList::Entry* a_entries)
: entry_count(a_entry_count), entries(a_entries) {}
} // namespace gpu