blob: 21c5b6ee8eb762fa553dd1241e3ad8aacf63e17e [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.
#ifndef GPU_CONFIG_GPU_CONTROL_LIST_H_
#define GPU_CONFIG_GPU_CONTROL_LIST_H_
#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 {
public:
typedef base::hash_map<int, std::string> FeatureMap;
enum OsType { kOsLinux, kOsMacosx, kOsWin, kOsChromeOS, kOsAndroid, kOsAny };
enum OsFilter {
// In loading, ignore all entries that belong to other OS.
kCurrentOsOnly,
// In loading, keep all entries. This is for testing only.
kAllOs
};
enum NumericOp {
kBetween, // <= * <=
kEQ, // =
kLT, // <
kLE, // <=
kGT, // >
kGE, // >=
kAny,
kUnknown // Indicates the data is invalid.
};
enum MultiGpuStyle {
kMultiGpuStyleOptimus,
kMultiGpuStyleAMDSwitchable,
kMultiGpuStyleAMDSwitchableIntegrated,
kMultiGpuStyleAMDSwitchableDiscrete,
kMultiGpuStyleNone
};
enum MultiGpuCategory {
// This entry applies if this is the primary GPU on the system.
kMultiGpuCategoryPrimary,
// This entry applies if this is a secondary GPU on the system.
kMultiGpuCategorySecondary,
// This entry applies if this is the active GPU on the system.
kMultiGpuCategoryActive,
// This entry applies if this is any of the GPUs on the system.
kMultiGpuCategoryAny,
kMultiGpuCategoryNone
};
enum GLType {
kGLTypeGL, // This is default on MacOSX, Linux, ChromeOS
kGLTypeGLES, // This is default on Android
kGLTypeANGLE, // This is default on Windows
kGLTypeNone
};
enum VersionStyle {
kVersionStyleNumerical,
kVersionStyleLexical,
kVersionStyleUnknown
};
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;
// 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;
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 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;
// 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<int> MakeDecision(OsType os,
const std::string& os_version,
const GPUInfo& gpu_info);
// Collects the active entries from the last MakeDecision() call.
void GetDecisionEntries(std::vector<uint32_t>* entry_ids) const;
// Collects all disabled extensions.
std::vector<std::string> GetDisabledExtensions();
// Returns the description and bugs from active entries from the last
// MakeDecision() call.
//
// Each problems has:
// {
// "description": "Your GPU is too old",
// "crBugs": [1234],
// }
void GetReasons(base::ListValue* problem_list, const std::string& tag) const;
// Return the largest entry id. This is used for histogramming.
uint32_t max_entry_id() const;
// Returns the version of the control list.
std::string version() 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;
}
private:
friend class GpuControlListEntryTest;
friend class VersionInfoTest;
// Gets the current OS type.
static OsType GetOsType();
std::string version_;
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<size_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 {
const char* version;
size_t entry_count;
const GpuControlList::Entry* entries;
GpuControlListData() : version(nullptr), entry_count(0u), entries(nullptr) {}
GpuControlListData(const char* a_version,
size_t a_entry_count,
const GpuControlList::Entry* a_entries)
: version(a_version), entry_count(a_entry_count), entries(a_entries) {}
};
} // namespace gpu
#endif // GPU_CONFIG_GPU_CONTROL_LIST_H_