| // 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 <unordered_map> |
| #include <vector> |
| |
| #include "base/memory/raw_ptr.h" |
| #include "base/values.h" |
| #include "gpu/config/gpu_info.h" |
| #include "gpu/gpu_export.h" |
| |
| namespace gpu { |
| struct GpuControlListData; |
| struct GPUInfo; |
| |
| class GPU_EXPORT GpuControlList { |
| public: |
| typedef std::unordered_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 |
| }; |
| |
| enum VersionSchema { |
| // All digits are meaningful when distinguishing versions. |
| kVersionSchemaCommon, |
| // The version format of Intel graphics driver is AA.BB.CCC.DDDD. |
| // DDDD(old schema) or CCC.DDDD(new schema) is the build number. |
| // That is, indicates the actual driver number. |
| kVersionSchemaIntelDriver, |
| // The version format of Nvidia drivers is XX.XX.XXXA.AAAA where the X's |
| // can be any digits, and the A's are the actual version. The workaround |
| // list specifies them as AAA.AA to match how Nvidia publishes them. |
| kVersionSchemaNvidiaDriver, |
| }; |
| |
| enum SupportedOrNot { |
| kSupported, |
| kUnsupported, |
| kDontCare, |
| }; |
| |
| struct GPU_EXPORT Version { |
| NumericOp op; |
| VersionStyle style; |
| VersionSchema schema; |
| 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; |
| |
| 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; |
| Version direct_rendering_version; |
| Version gpu_count; |
| SupportedOrNot hardware_overlay; |
| |
| uint32_t test_group; |
| |
| SupportedOrNot subpixel_font_rendering; |
| |
| // 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 Device { |
| uint32_t device_id; |
| uint32_t revision = 0u; |
| }; |
| |
| struct GPU_EXPORT Conditions { |
| OsType os_type; |
| Version os_version; |
| uint32_t vendor_id; |
| size_t device_size; |
| const Device* devices; |
| MultiGpuCategory multi_gpu_category; |
| MultiGpuStyle multi_gpu_style; |
| const DriverInfo* driver_info; |
| const GLStrings* gl_strings; |
| const MachineModelInfo* machine_model_info; |
| size_t intel_gpu_series_list_size; |
| const IntelGpuSeriesType* intel_gpu_series_list; |
| Version intel_gpu_generation; |
| 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 blocklisting |
| // 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 blocklisting |
| // decision. It should only be checked if Contains() returns true. |
| bool NeedsMoreInfo(const GPUInfo& gpu_info, bool consider_exceptions) const; |
| |
| void GetFeatureNames(base::Value& 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::Value& 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; |
| } |
| |
| protected: |
| // Return false if an entry index goes beyond |total_entries|. |
| static bool AreEntryIndicesValid(const std::vector<uint32_t>& entry_indices, |
| size_t total_entries); |
| |
| private: |
| friend class GpuControlListEntryTest; |
| friend class VersionInfoTest; |
| |
| // Gets the current OS type. |
| static OsType GetOsType(); |
| |
| size_t entry_count_; |
| raw_ptr<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; |
| raw_ptr<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_ |