|  | // 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, | 
|  | kOsFuchsia, | 
|  | 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<int32_t> MakeDecision(OsType os, | 
|  | const std::string& os_version, | 
|  | const GPUInfo& gpu_info); | 
|  |  | 
|  | // 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(); | 
|  |  | 
|  | // 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; | 
|  | // Similar to the previous function, but instead of using the active entries | 
|  | // from the last MakeDecision() call, which may not happen at all, entries | 
|  | // are provided. | 
|  | // 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; | 
|  | } | 
|  |  | 
|  | private: | 
|  | friend class GpuControlListEntryTest; | 
|  | friend class VersionInfoTest; | 
|  |  | 
|  | // Gets the current OS type. | 
|  | static OsType GetOsType(); | 
|  |  | 
|  | 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 | 
|  |  | 
|  | #endif  // GPU_CONFIG_GPU_CONTROL_LIST_H_ |