Loading services/gpuservice/feature_override/Android.bp +4 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ cc_library_static { name: "libfeatureoverride", defaults: [ "libfeatureoverride_deps", "libvkjson_deps", ], srcs: [ ":feature_config_proto_definitions", Loading @@ -85,6 +86,9 @@ cc_library_static { cppflags: [ "-Wno-sign-compare", ], static_libs: [ "libvkjson", ], export_include_dirs: ["include"], proto: { type: "lite", Loading services/gpuservice/feature_override/FeatureOverrideParser.cpp +65 −5 Original line number Diff line number Diff line Loading @@ -23,8 +23,10 @@ #include <sys/stat.h> #include <vector> #include <android-base/macros.h> #include <graphicsenv/FeatureOverrides.h> #include <log/log.h> #include <vkjson.h> #include "feature_config.pb.h" Loading @@ -35,13 +37,53 @@ void resetFeatureOverrides(android::FeatureOverrides &featureOverrides) { featureOverrides.mPackageFeatures.clear(); } bool gpuVendorIdMatches(const VkJsonInstance &vkJsonInstance, const uint32_t &configVendorId) { if (vkJsonInstance.devices.empty()) { return false; } // Always match the TEST Vendor ID if (configVendorId == feature_override::GpuVendorID::VENDOR_ID_TEST) { return true; } // Always assume one GPU device. uint32_t vendorID = vkJsonInstance.devices.front().properties.vendorID; return vendorID == configVendorId; } bool conditionsMet(const VkJsonInstance &vkJsonInstance, const android::FeatureConfig &featureConfig) { bool gpuVendorIdMatch = false; if (featureConfig.mGpuVendorIDs.empty()) { gpuVendorIdMatch = true; } else { for (const auto &gpuVendorID: featureConfig.mGpuVendorIDs) { if (gpuVendorIdMatches(vkJsonInstance, gpuVendorID)) { gpuVendorIdMatch = true; break; } } } return gpuVendorIdMatch; } void initFeatureConfig(android::FeatureConfig &featureConfig, const feature_override::FeatureConfig &featureConfigProto) { featureConfig.mFeatureName = featureConfigProto.feature_name(); featureConfig.mEnabled = featureConfigProto.enabled(); for (const auto &gpuVendorIdProto: featureConfigProto.gpu_vendor_ids()) { featureConfig.mGpuVendorIDs.emplace_back(static_cast<uint32_t>(gpuVendorIdProto)); } } feature_override::FeatureOverrideProtos readFeatureConfigProtos(std::string configFilePath) { feature_override::FeatureOverrideProtos readFeatureConfigProtos(const std::string &configFilePath) { feature_override::FeatureOverrideProtos overridesProtos; std::ifstream protobufBinaryFile(configFilePath.c_str()); Loading Loading @@ -78,9 +120,15 @@ std::string FeatureOverrideParser::getFeatureOverrideFilePath() const { bool FeatureOverrideParser::shouldReloadFeatureOverrides() const { std::string configFilePath = getFeatureOverrideFilePath(); std::ifstream configFile(configFilePath); if (!configFile.good()) { return false; } struct stat fileStat{}; if (stat(getFeatureOverrideFilePath().c_str(), &fileStat) != 0) { ALOGE("Error getting file information for '%s': %s", getFeatureOverrideFilePath().c_str(), if (stat(configFilePath.c_str(), &fileStat) != 0) { ALOGE("Error getting file information for '%s': %s", configFilePath.c_str(), strerror(errno)); // stat'ing the file failed, so return false since reading it will also likely fail. return false; Loading @@ -100,13 +148,23 @@ void FeatureOverrideParser::parseFeatureOverrides() { // Clear out the stale values before adding the newly parsed data. resetFeatureOverrides(mFeatureOverrides); if (overridesProtos.global_features().empty() && overridesProtos.package_features().empty()) { // No overrides to parse. return; } const VkJsonInstance vkJsonInstance = VkJsonGetInstance(); // Global feature overrides. for (const auto &featureConfigProto: overridesProtos.global_features()) { FeatureConfig featureConfig; initFeatureConfig(featureConfig, featureConfigProto); if (conditionsMet(vkJsonInstance, featureConfig)) { mFeatureOverrides.mGlobalFeatures.emplace_back(featureConfig); } } // App-specific feature overrides. for (auto const &pkgConfigProto: overridesProtos.package_features()) { Loading @@ -122,8 +180,10 @@ void FeatureOverrideParser::parseFeatureOverrides() { FeatureConfig featureConfig; initFeatureConfig(featureConfig, featureConfigProto); if (conditionsMet(vkJsonInstance, featureConfig)) { featureConfigs.emplace_back(featureConfig); } } mFeatureOverrides.mPackageFeatures[packageName] = featureConfigs; } Loading services/gpuservice/feature_override/proto/feature_config.proto +29 −0 Original line number Diff line number Diff line Loading @@ -20,15 +20,44 @@ package feature_override; option optimize_for = LITE_RUNTIME; /** * GPU Vendor IDs. * Taken from: external/angle/src/libANGLE/renderer/driver_utils.h */ enum GpuVendorID { // Test ID matches every GPU Vendor ID. VENDOR_ID_TEST = 0; VENDOR_ID_AMD = 0x1002; VENDOR_ID_ARM = 0x13B5; // Broadcom devices won't use PCI, but this is their Vulkan vendor id. VENDOR_ID_BROADCOM = 0x14E4; VENDOR_ID_GOOGLE = 0x1AE0; VENDOR_ID_INTEL = 0x8086; VENDOR_ID_MESA = 0x10005; VENDOR_ID_MICROSOFT = 0x1414; VENDOR_ID_NVIDIA = 0x10DE; VENDOR_ID_POWERVR = 0x1010; // This is Qualcomm PCI Vendor ID. // Android doesn't have a PCI bus, but all we need is a unique id. VENDOR_ID_QUALCOMM = 0x5143; VENDOR_ID_SAMSUNG = 0x144D; VENDOR_ID_VIVANTE = 0x9999; VENDOR_ID_VMWARE = 0x15AD; VENDOR_ID_VIRTIO = 0x1AF4; } /** * Feature Configuration * feature_name: Feature name (see external/angle/include/platform/autogen/FeaturesVk_autogen.h). * enabled: Either enable or disable the feature. * gpu_vendor_ids: The GPU architectures this FeatureConfig applies to, if any. */ message FeatureConfig { string feature_name = 1; bool enabled = 2; repeated GpuVendorID gpu_vendor_ids = 3; } /** Loading services/gpuservice/tests/unittests/FeatureOverrideParserTest.cpp +252 −2 Original line number Diff line number Diff line Loading @@ -70,14 +70,14 @@ public: }; testing::AssertionResult validateFeatureConfigTestTxtpbSizes(FeatureOverrides overrides) { size_t expectedGlobalFeaturesSize = 1; size_t expectedGlobalFeaturesSize = 3; if (overrides.mGlobalFeatures.size() != expectedGlobalFeaturesSize) { return testing::AssertionFailure() << "overrides.mGlobalFeatures.size(): " << overrides.mGlobalFeatures.size() << ", expected: " << expectedGlobalFeaturesSize; } size_t expectedPackageFeaturesSize = 1; size_t expectedPackageFeaturesSize = 3; if (overrides.mPackageFeatures.size() != expectedPackageFeaturesSize) { return testing::AssertionFailure() << "overrides.mPackageFeatures.size(): " << overrides.mPackageFeatures.size() Loading Loading @@ -133,6 +133,96 @@ TEST_F(FeatureOverrideParserTest, globalOverrides1) { EXPECT_TRUE(validateGlobalOverrides1(overrides)); } testing::AssertionResult validateGlobalOverrides2(FeatureOverrides overrides) { const int kTestFeatureIndex = 1; const std::string expectedFeatureName = "globalOverrides2"; const FeatureConfig &cfg = overrides.mGlobalFeatures[kTestFeatureIndex]; if (cfg.mFeatureName != expectedFeatureName) { return testing::AssertionFailure() << "cfg.mFeatureName: " << cfg.mFeatureName << ", expected: " << expectedFeatureName; } bool expectedEnabled = true; if (cfg.mEnabled != expectedEnabled) { return testing::AssertionFailure() << "cfg.mEnabled: " << cfg.mEnabled << ", expected: " << expectedEnabled; } std::vector<uint32_t> expectedGpuVendorIDs = { 0, // GpuVendorID::VENDOR_ID_TEST 0x13B5, // GpuVendorID::VENDOR_ID_ARM }; if (cfg.mGpuVendorIDs.size() != expectedGpuVendorIDs.size()) { return testing::AssertionFailure() << "cfg.mGpuVendorIDs.size(): " << cfg.mGpuVendorIDs.size() << ", expected: " << expectedGpuVendorIDs.size(); } for (int i = 0; i < expectedGpuVendorIDs.size(); i++) { if (cfg.mGpuVendorIDs[i] != expectedGpuVendorIDs[i]) { std::stringstream msg; msg << "cfg.mGpuVendorIDs[" << i << "]: 0x" << std::hex << cfg.mGpuVendorIDs[i] << ", expected: 0x" << std::hex << expectedGpuVendorIDs[i]; return testing::AssertionFailure() << msg.str(); } } return testing::AssertionSuccess(); } TEST_F(FeatureOverrideParserTest, globalOverrides2) { FeatureOverrides overrides = mFeatureOverrideParser.getFeatureOverrides(); EXPECT_TRUE(validateGlobalOverrides2(overrides)); } testing::AssertionResult validateGlobalOverrides3(FeatureOverrides overrides) { const int kTestFeatureIndex = 2; const std::string expectedFeatureName = "globalOverrides3"; const FeatureConfig &cfg = overrides.mGlobalFeatures[kTestFeatureIndex]; if (cfg.mFeatureName != expectedFeatureName) { return testing::AssertionFailure() << "cfg.mFeatureName: " << cfg.mFeatureName << ", expected: " << expectedFeatureName; } bool expectedEnabled = true; if (cfg.mEnabled != expectedEnabled) { return testing::AssertionFailure() << "cfg.mEnabled: " << cfg.mEnabled << ", expected: " << expectedEnabled; } std::vector<uint32_t> expectedGpuVendorIDs = { 0, // GpuVendorID::VENDOR_ID_TEST 0x8086, // GpuVendorID::VENDOR_ID_INTEL }; if (cfg.mGpuVendorIDs.size() != expectedGpuVendorIDs.size()) { return testing::AssertionFailure() << "cfg.mGpuVendorIDs.size(): " << cfg.mGpuVendorIDs.size() << ", expected: " << expectedGpuVendorIDs.size(); } for (int i = 0; i < expectedGpuVendorIDs.size(); i++) { if (cfg.mGpuVendorIDs[i] != expectedGpuVendorIDs[i]) { std::stringstream msg; msg << "cfg.mGpuVendorIDs[" << i << "]: 0x" << std::hex << cfg.mGpuVendorIDs[i] << ", expected: 0x" << std::hex << expectedGpuVendorIDs[i]; return testing::AssertionFailure() << msg.str(); } } return testing::AssertionSuccess(); } TEST_F(FeatureOverrideParserTest, globalOverrides3) { FeatureOverrides overrides = mFeatureOverrideParser.getFeatureOverrides(); EXPECT_TRUE(validateGlobalOverrides3(overrides)); } testing::AssertionResult validatePackageOverrides1(FeatureOverrides overrides) { const std::string expectedTestPackageName = "com.gpuservice_unittest.packageOverrides1"; Loading @@ -155,6 +245,12 @@ testing::AssertionResult validatePackageOverrides1(FeatureOverrides overrides) { const std::string expectedFeatureName = "packageOverrides1"; const FeatureConfig &cfg = features[0]; if (cfg.mFeatureName != expectedFeatureName) { return testing::AssertionFailure() << "cfg.mFeatureName: " << cfg.mFeatureName << ", expected: " << expectedFeatureName; } bool expectedEnabled = true; if (cfg.mEnabled != expectedEnabled) { return testing::AssertionFailure() Loading Loading @@ -193,6 +289,160 @@ testing::AssertionResult validateForceFileRead(FeatureOverrides overrides) { return testing::AssertionSuccess(); } testing::AssertionResult validatePackageOverrides2(FeatureOverrides overrides) { const std::string expectedPackageName = "com.gpuservice_unittest.packageOverrides2"; if (!overrides.mPackageFeatures.count(expectedPackageName)) { return testing::AssertionFailure() << "overrides.mPackageFeatures missing expected package: " << expectedPackageName; } const std::vector<FeatureConfig>& features = overrides.mPackageFeatures[expectedPackageName]; size_t expectedFeaturesSize = 1; if (features.size() != expectedFeaturesSize) { return testing::AssertionFailure() << "features.size(): " << features.size() << ", expectedFeaturesSize: " << expectedFeaturesSize; } const std::string expectedFeatureName = "packageOverrides2"; const FeatureConfig &cfg = features[0]; if (cfg.mFeatureName != expectedFeatureName) { return testing::AssertionFailure() << "cfg.mFeatureName: " << cfg.mFeatureName << ", expected: " << expectedFeatureName; } bool expectedEnabled = false; if (cfg.mEnabled != expectedEnabled) { return testing::AssertionFailure() << "cfg.mEnabled: " << cfg.mEnabled << ", expected: " << expectedEnabled; } std::vector<uint32_t> expectedGpuVendorIDs = { 0, // GpuVendorID::VENDOR_ID_TEST 0x8086, // GpuVendorID::VENDOR_ID_INTEL }; if (cfg.mGpuVendorIDs.size() != expectedGpuVendorIDs.size()) { return testing::AssertionFailure() << "cfg.mGpuVendorIDs.size(): " << cfg.mGpuVendorIDs.size() << ", expected: " << expectedGpuVendorIDs.size(); } for (int i = 0; i < expectedGpuVendorIDs.size(); i++) { if (cfg.mGpuVendorIDs[i] != expectedGpuVendorIDs[i]) { std::stringstream msg; msg << "cfg.mGpuVendorIDs[" << i << "]: 0x" << std::hex << cfg.mGpuVendorIDs[i] << ", expected: 0x" << std::hex << expectedGpuVendorIDs[i]; return testing::AssertionFailure() << msg.str(); } } return testing::AssertionSuccess(); } TEST_F(FeatureOverrideParserTest, packageOverrides2) { FeatureOverrides overrides = mFeatureOverrideParser.getFeatureOverrides(); EXPECT_TRUE(validatePackageOverrides2(overrides)); } testing::AssertionResult validatePackageOverrides3(FeatureOverrides overrides) { const std::string expectedPackageName = "com.gpuservice_unittest.packageOverrides3"; if (!overrides.mPackageFeatures.count(expectedPackageName)) { return testing::AssertionFailure() << "overrides.mPackageFeatures missing expected package: " << expectedPackageName; } const std::vector<FeatureConfig>& features = overrides.mPackageFeatures[expectedPackageName]; size_t expectedFeaturesSize = 2; if (features.size() != expectedFeaturesSize) { return testing::AssertionFailure() << "features.size(): " << features.size() << ", expectedFeaturesSize: " << expectedFeaturesSize; } std::string expectedFeatureName = "packageOverrides3_1"; const FeatureConfig &cfg_1 = features[0]; if (cfg_1.mFeatureName != expectedFeatureName) { return testing::AssertionFailure() << "cfg.mFeatureName: " << cfg_1.mFeatureName << ", expected: " << expectedFeatureName; } bool expectedEnabled = false; if (cfg_1.mEnabled != expectedEnabled) { return testing::AssertionFailure() << "cfg.mEnabled: " << cfg_1.mEnabled << ", expected: " << expectedEnabled; } std::vector<uint32_t> expectedGpuVendorIDs = { 0, // GpuVendorID::VENDOR_ID_TEST 0x13B5, // GpuVendorID::VENDOR_ID_ARM }; if (cfg_1.mGpuVendorIDs.size() != expectedGpuVendorIDs.size()) { return testing::AssertionFailure() << "cfg.mGpuVendorIDs.size(): " << cfg_1.mGpuVendorIDs.size() << ", expected: " << expectedGpuVendorIDs.size(); } for (int i = 0; i < expectedGpuVendorIDs.size(); i++) { if (cfg_1.mGpuVendorIDs[i] != expectedGpuVendorIDs[i]) { std::stringstream msg; msg << "cfg.mGpuVendorIDs[" << i << "]: 0x" << std::hex << cfg_1.mGpuVendorIDs[i] << ", expected: 0x" << std::hex << expectedGpuVendorIDs[i]; return testing::AssertionFailure() << msg.str(); } } expectedFeatureName = "packageOverrides3_2"; const FeatureConfig &cfg_2 = features[1]; if (cfg_2.mFeatureName != expectedFeatureName) { return testing::AssertionFailure() << "cfg.mFeatureName: " << cfg_2.mFeatureName << ", expected: " << expectedFeatureName; } expectedEnabled = true; if (cfg_2.mEnabled != expectedEnabled) { return testing::AssertionFailure() << "cfg.mEnabled: " << cfg_2.mEnabled << ", expected: " << expectedEnabled; } expectedGpuVendorIDs = { 0, // GpuVendorID::VENDOR_ID_TEST 0x8086, // GpuVendorID::VENDOR_ID_INTEL }; if (cfg_2.mGpuVendorIDs.size() != expectedGpuVendorIDs.size()) { return testing::AssertionFailure() << "cfg.mGpuVendorIDs.size(): " << cfg_2.mGpuVendorIDs.size() << ", expected: " << expectedGpuVendorIDs.size(); } for (int i = 0; i < expectedGpuVendorIDs.size(); i++) { if (cfg_2.mGpuVendorIDs[i] != expectedGpuVendorIDs[i]) { std::stringstream msg; msg << "cfg.mGpuVendorIDs[" << i << "]: 0x" << std::hex << cfg_2.mGpuVendorIDs[i] << ", expected: 0x" << std::hex << expectedGpuVendorIDs[i]; return testing::AssertionFailure() << msg.str(); } } return testing::AssertionSuccess(); } TEST_F(FeatureOverrideParserTest, packageOverrides3) { FeatureOverrides overrides = mFeatureOverrideParser.getFeatureOverrides(); EXPECT_TRUE(validatePackageOverrides3(overrides)); } TEST_F(FeatureOverrideParserTest, forceFileRead) { FeatureOverrides overrides = mFeatureOverrideParser.getFeatureOverrides(); Loading services/gpuservice/tests/unittests/data/feature_config_test.txtpb +50 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,22 @@ global_features [ { feature_name: "globalOverrides1" enabled: False }, { feature_name: "globalOverrides2" enabled: True gpu_vendor_ids: [ VENDOR_ID_TEST, # Match every GPU Vendor ID, so the feature isn't dropped when parsed. VENDOR_ID_ARM ] }, { feature_name: "globalOverrides3" enabled: True gpu_vendor_ids: [ VENDOR_ID_TEST, # Match every GPU Vendor ID, so the feature isn't dropped when parsed. VENDOR_ID_INTEL ] } ] Loading @@ -36,5 +52,39 @@ package_features [ enabled: True } ] }, { package_name: "com.gpuservice_unittest.packageOverrides2" feature_configs: [ { feature_name: "packageOverrides2" enabled: False gpu_vendor_ids: [ VENDOR_ID_TEST, # Match every GPU Vendor ID, so the feature isn't dropped when parsed. VENDOR_ID_INTEL ] } ] }, { package_name: "com.gpuservice_unittest.packageOverrides3" feature_configs: [ { feature_name: "packageOverrides3_1" enabled: False gpu_vendor_ids: [ VENDOR_ID_TEST, # Match every GPU Vendor ID, so the feature isn't dropped when parsed. VENDOR_ID_ARM ] }, { feature_name: "packageOverrides3_2" enabled: True gpu_vendor_ids: [ VENDOR_ID_TEST, # Match every GPU Vendor ID, so the feature isn't dropped when parsed. VENDOR_ID_INTEL ] } ] } ] Loading
services/gpuservice/feature_override/Android.bp +4 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ cc_library_static { name: "libfeatureoverride", defaults: [ "libfeatureoverride_deps", "libvkjson_deps", ], srcs: [ ":feature_config_proto_definitions", Loading @@ -85,6 +86,9 @@ cc_library_static { cppflags: [ "-Wno-sign-compare", ], static_libs: [ "libvkjson", ], export_include_dirs: ["include"], proto: { type: "lite", Loading
services/gpuservice/feature_override/FeatureOverrideParser.cpp +65 −5 Original line number Diff line number Diff line Loading @@ -23,8 +23,10 @@ #include <sys/stat.h> #include <vector> #include <android-base/macros.h> #include <graphicsenv/FeatureOverrides.h> #include <log/log.h> #include <vkjson.h> #include "feature_config.pb.h" Loading @@ -35,13 +37,53 @@ void resetFeatureOverrides(android::FeatureOverrides &featureOverrides) { featureOverrides.mPackageFeatures.clear(); } bool gpuVendorIdMatches(const VkJsonInstance &vkJsonInstance, const uint32_t &configVendorId) { if (vkJsonInstance.devices.empty()) { return false; } // Always match the TEST Vendor ID if (configVendorId == feature_override::GpuVendorID::VENDOR_ID_TEST) { return true; } // Always assume one GPU device. uint32_t vendorID = vkJsonInstance.devices.front().properties.vendorID; return vendorID == configVendorId; } bool conditionsMet(const VkJsonInstance &vkJsonInstance, const android::FeatureConfig &featureConfig) { bool gpuVendorIdMatch = false; if (featureConfig.mGpuVendorIDs.empty()) { gpuVendorIdMatch = true; } else { for (const auto &gpuVendorID: featureConfig.mGpuVendorIDs) { if (gpuVendorIdMatches(vkJsonInstance, gpuVendorID)) { gpuVendorIdMatch = true; break; } } } return gpuVendorIdMatch; } void initFeatureConfig(android::FeatureConfig &featureConfig, const feature_override::FeatureConfig &featureConfigProto) { featureConfig.mFeatureName = featureConfigProto.feature_name(); featureConfig.mEnabled = featureConfigProto.enabled(); for (const auto &gpuVendorIdProto: featureConfigProto.gpu_vendor_ids()) { featureConfig.mGpuVendorIDs.emplace_back(static_cast<uint32_t>(gpuVendorIdProto)); } } feature_override::FeatureOverrideProtos readFeatureConfigProtos(std::string configFilePath) { feature_override::FeatureOverrideProtos readFeatureConfigProtos(const std::string &configFilePath) { feature_override::FeatureOverrideProtos overridesProtos; std::ifstream protobufBinaryFile(configFilePath.c_str()); Loading Loading @@ -78,9 +120,15 @@ std::string FeatureOverrideParser::getFeatureOverrideFilePath() const { bool FeatureOverrideParser::shouldReloadFeatureOverrides() const { std::string configFilePath = getFeatureOverrideFilePath(); std::ifstream configFile(configFilePath); if (!configFile.good()) { return false; } struct stat fileStat{}; if (stat(getFeatureOverrideFilePath().c_str(), &fileStat) != 0) { ALOGE("Error getting file information for '%s': %s", getFeatureOverrideFilePath().c_str(), if (stat(configFilePath.c_str(), &fileStat) != 0) { ALOGE("Error getting file information for '%s': %s", configFilePath.c_str(), strerror(errno)); // stat'ing the file failed, so return false since reading it will also likely fail. return false; Loading @@ -100,13 +148,23 @@ void FeatureOverrideParser::parseFeatureOverrides() { // Clear out the stale values before adding the newly parsed data. resetFeatureOverrides(mFeatureOverrides); if (overridesProtos.global_features().empty() && overridesProtos.package_features().empty()) { // No overrides to parse. return; } const VkJsonInstance vkJsonInstance = VkJsonGetInstance(); // Global feature overrides. for (const auto &featureConfigProto: overridesProtos.global_features()) { FeatureConfig featureConfig; initFeatureConfig(featureConfig, featureConfigProto); if (conditionsMet(vkJsonInstance, featureConfig)) { mFeatureOverrides.mGlobalFeatures.emplace_back(featureConfig); } } // App-specific feature overrides. for (auto const &pkgConfigProto: overridesProtos.package_features()) { Loading @@ -122,8 +180,10 @@ void FeatureOverrideParser::parseFeatureOverrides() { FeatureConfig featureConfig; initFeatureConfig(featureConfig, featureConfigProto); if (conditionsMet(vkJsonInstance, featureConfig)) { featureConfigs.emplace_back(featureConfig); } } mFeatureOverrides.mPackageFeatures[packageName] = featureConfigs; } Loading
services/gpuservice/feature_override/proto/feature_config.proto +29 −0 Original line number Diff line number Diff line Loading @@ -20,15 +20,44 @@ package feature_override; option optimize_for = LITE_RUNTIME; /** * GPU Vendor IDs. * Taken from: external/angle/src/libANGLE/renderer/driver_utils.h */ enum GpuVendorID { // Test ID matches every GPU Vendor ID. VENDOR_ID_TEST = 0; VENDOR_ID_AMD = 0x1002; VENDOR_ID_ARM = 0x13B5; // Broadcom devices won't use PCI, but this is their Vulkan vendor id. VENDOR_ID_BROADCOM = 0x14E4; VENDOR_ID_GOOGLE = 0x1AE0; VENDOR_ID_INTEL = 0x8086; VENDOR_ID_MESA = 0x10005; VENDOR_ID_MICROSOFT = 0x1414; VENDOR_ID_NVIDIA = 0x10DE; VENDOR_ID_POWERVR = 0x1010; // This is Qualcomm PCI Vendor ID. // Android doesn't have a PCI bus, but all we need is a unique id. VENDOR_ID_QUALCOMM = 0x5143; VENDOR_ID_SAMSUNG = 0x144D; VENDOR_ID_VIVANTE = 0x9999; VENDOR_ID_VMWARE = 0x15AD; VENDOR_ID_VIRTIO = 0x1AF4; } /** * Feature Configuration * feature_name: Feature name (see external/angle/include/platform/autogen/FeaturesVk_autogen.h). * enabled: Either enable or disable the feature. * gpu_vendor_ids: The GPU architectures this FeatureConfig applies to, if any. */ message FeatureConfig { string feature_name = 1; bool enabled = 2; repeated GpuVendorID gpu_vendor_ids = 3; } /** Loading
services/gpuservice/tests/unittests/FeatureOverrideParserTest.cpp +252 −2 Original line number Diff line number Diff line Loading @@ -70,14 +70,14 @@ public: }; testing::AssertionResult validateFeatureConfigTestTxtpbSizes(FeatureOverrides overrides) { size_t expectedGlobalFeaturesSize = 1; size_t expectedGlobalFeaturesSize = 3; if (overrides.mGlobalFeatures.size() != expectedGlobalFeaturesSize) { return testing::AssertionFailure() << "overrides.mGlobalFeatures.size(): " << overrides.mGlobalFeatures.size() << ", expected: " << expectedGlobalFeaturesSize; } size_t expectedPackageFeaturesSize = 1; size_t expectedPackageFeaturesSize = 3; if (overrides.mPackageFeatures.size() != expectedPackageFeaturesSize) { return testing::AssertionFailure() << "overrides.mPackageFeatures.size(): " << overrides.mPackageFeatures.size() Loading Loading @@ -133,6 +133,96 @@ TEST_F(FeatureOverrideParserTest, globalOverrides1) { EXPECT_TRUE(validateGlobalOverrides1(overrides)); } testing::AssertionResult validateGlobalOverrides2(FeatureOverrides overrides) { const int kTestFeatureIndex = 1; const std::string expectedFeatureName = "globalOverrides2"; const FeatureConfig &cfg = overrides.mGlobalFeatures[kTestFeatureIndex]; if (cfg.mFeatureName != expectedFeatureName) { return testing::AssertionFailure() << "cfg.mFeatureName: " << cfg.mFeatureName << ", expected: " << expectedFeatureName; } bool expectedEnabled = true; if (cfg.mEnabled != expectedEnabled) { return testing::AssertionFailure() << "cfg.mEnabled: " << cfg.mEnabled << ", expected: " << expectedEnabled; } std::vector<uint32_t> expectedGpuVendorIDs = { 0, // GpuVendorID::VENDOR_ID_TEST 0x13B5, // GpuVendorID::VENDOR_ID_ARM }; if (cfg.mGpuVendorIDs.size() != expectedGpuVendorIDs.size()) { return testing::AssertionFailure() << "cfg.mGpuVendorIDs.size(): " << cfg.mGpuVendorIDs.size() << ", expected: " << expectedGpuVendorIDs.size(); } for (int i = 0; i < expectedGpuVendorIDs.size(); i++) { if (cfg.mGpuVendorIDs[i] != expectedGpuVendorIDs[i]) { std::stringstream msg; msg << "cfg.mGpuVendorIDs[" << i << "]: 0x" << std::hex << cfg.mGpuVendorIDs[i] << ", expected: 0x" << std::hex << expectedGpuVendorIDs[i]; return testing::AssertionFailure() << msg.str(); } } return testing::AssertionSuccess(); } TEST_F(FeatureOverrideParserTest, globalOverrides2) { FeatureOverrides overrides = mFeatureOverrideParser.getFeatureOverrides(); EXPECT_TRUE(validateGlobalOverrides2(overrides)); } testing::AssertionResult validateGlobalOverrides3(FeatureOverrides overrides) { const int kTestFeatureIndex = 2; const std::string expectedFeatureName = "globalOverrides3"; const FeatureConfig &cfg = overrides.mGlobalFeatures[kTestFeatureIndex]; if (cfg.mFeatureName != expectedFeatureName) { return testing::AssertionFailure() << "cfg.mFeatureName: " << cfg.mFeatureName << ", expected: " << expectedFeatureName; } bool expectedEnabled = true; if (cfg.mEnabled != expectedEnabled) { return testing::AssertionFailure() << "cfg.mEnabled: " << cfg.mEnabled << ", expected: " << expectedEnabled; } std::vector<uint32_t> expectedGpuVendorIDs = { 0, // GpuVendorID::VENDOR_ID_TEST 0x8086, // GpuVendorID::VENDOR_ID_INTEL }; if (cfg.mGpuVendorIDs.size() != expectedGpuVendorIDs.size()) { return testing::AssertionFailure() << "cfg.mGpuVendorIDs.size(): " << cfg.mGpuVendorIDs.size() << ", expected: " << expectedGpuVendorIDs.size(); } for (int i = 0; i < expectedGpuVendorIDs.size(); i++) { if (cfg.mGpuVendorIDs[i] != expectedGpuVendorIDs[i]) { std::stringstream msg; msg << "cfg.mGpuVendorIDs[" << i << "]: 0x" << std::hex << cfg.mGpuVendorIDs[i] << ", expected: 0x" << std::hex << expectedGpuVendorIDs[i]; return testing::AssertionFailure() << msg.str(); } } return testing::AssertionSuccess(); } TEST_F(FeatureOverrideParserTest, globalOverrides3) { FeatureOverrides overrides = mFeatureOverrideParser.getFeatureOverrides(); EXPECT_TRUE(validateGlobalOverrides3(overrides)); } testing::AssertionResult validatePackageOverrides1(FeatureOverrides overrides) { const std::string expectedTestPackageName = "com.gpuservice_unittest.packageOverrides1"; Loading @@ -155,6 +245,12 @@ testing::AssertionResult validatePackageOverrides1(FeatureOverrides overrides) { const std::string expectedFeatureName = "packageOverrides1"; const FeatureConfig &cfg = features[0]; if (cfg.mFeatureName != expectedFeatureName) { return testing::AssertionFailure() << "cfg.mFeatureName: " << cfg.mFeatureName << ", expected: " << expectedFeatureName; } bool expectedEnabled = true; if (cfg.mEnabled != expectedEnabled) { return testing::AssertionFailure() Loading Loading @@ -193,6 +289,160 @@ testing::AssertionResult validateForceFileRead(FeatureOverrides overrides) { return testing::AssertionSuccess(); } testing::AssertionResult validatePackageOverrides2(FeatureOverrides overrides) { const std::string expectedPackageName = "com.gpuservice_unittest.packageOverrides2"; if (!overrides.mPackageFeatures.count(expectedPackageName)) { return testing::AssertionFailure() << "overrides.mPackageFeatures missing expected package: " << expectedPackageName; } const std::vector<FeatureConfig>& features = overrides.mPackageFeatures[expectedPackageName]; size_t expectedFeaturesSize = 1; if (features.size() != expectedFeaturesSize) { return testing::AssertionFailure() << "features.size(): " << features.size() << ", expectedFeaturesSize: " << expectedFeaturesSize; } const std::string expectedFeatureName = "packageOverrides2"; const FeatureConfig &cfg = features[0]; if (cfg.mFeatureName != expectedFeatureName) { return testing::AssertionFailure() << "cfg.mFeatureName: " << cfg.mFeatureName << ", expected: " << expectedFeatureName; } bool expectedEnabled = false; if (cfg.mEnabled != expectedEnabled) { return testing::AssertionFailure() << "cfg.mEnabled: " << cfg.mEnabled << ", expected: " << expectedEnabled; } std::vector<uint32_t> expectedGpuVendorIDs = { 0, // GpuVendorID::VENDOR_ID_TEST 0x8086, // GpuVendorID::VENDOR_ID_INTEL }; if (cfg.mGpuVendorIDs.size() != expectedGpuVendorIDs.size()) { return testing::AssertionFailure() << "cfg.mGpuVendorIDs.size(): " << cfg.mGpuVendorIDs.size() << ", expected: " << expectedGpuVendorIDs.size(); } for (int i = 0; i < expectedGpuVendorIDs.size(); i++) { if (cfg.mGpuVendorIDs[i] != expectedGpuVendorIDs[i]) { std::stringstream msg; msg << "cfg.mGpuVendorIDs[" << i << "]: 0x" << std::hex << cfg.mGpuVendorIDs[i] << ", expected: 0x" << std::hex << expectedGpuVendorIDs[i]; return testing::AssertionFailure() << msg.str(); } } return testing::AssertionSuccess(); } TEST_F(FeatureOverrideParserTest, packageOverrides2) { FeatureOverrides overrides = mFeatureOverrideParser.getFeatureOverrides(); EXPECT_TRUE(validatePackageOverrides2(overrides)); } testing::AssertionResult validatePackageOverrides3(FeatureOverrides overrides) { const std::string expectedPackageName = "com.gpuservice_unittest.packageOverrides3"; if (!overrides.mPackageFeatures.count(expectedPackageName)) { return testing::AssertionFailure() << "overrides.mPackageFeatures missing expected package: " << expectedPackageName; } const std::vector<FeatureConfig>& features = overrides.mPackageFeatures[expectedPackageName]; size_t expectedFeaturesSize = 2; if (features.size() != expectedFeaturesSize) { return testing::AssertionFailure() << "features.size(): " << features.size() << ", expectedFeaturesSize: " << expectedFeaturesSize; } std::string expectedFeatureName = "packageOverrides3_1"; const FeatureConfig &cfg_1 = features[0]; if (cfg_1.mFeatureName != expectedFeatureName) { return testing::AssertionFailure() << "cfg.mFeatureName: " << cfg_1.mFeatureName << ", expected: " << expectedFeatureName; } bool expectedEnabled = false; if (cfg_1.mEnabled != expectedEnabled) { return testing::AssertionFailure() << "cfg.mEnabled: " << cfg_1.mEnabled << ", expected: " << expectedEnabled; } std::vector<uint32_t> expectedGpuVendorIDs = { 0, // GpuVendorID::VENDOR_ID_TEST 0x13B5, // GpuVendorID::VENDOR_ID_ARM }; if (cfg_1.mGpuVendorIDs.size() != expectedGpuVendorIDs.size()) { return testing::AssertionFailure() << "cfg.mGpuVendorIDs.size(): " << cfg_1.mGpuVendorIDs.size() << ", expected: " << expectedGpuVendorIDs.size(); } for (int i = 0; i < expectedGpuVendorIDs.size(); i++) { if (cfg_1.mGpuVendorIDs[i] != expectedGpuVendorIDs[i]) { std::stringstream msg; msg << "cfg.mGpuVendorIDs[" << i << "]: 0x" << std::hex << cfg_1.mGpuVendorIDs[i] << ", expected: 0x" << std::hex << expectedGpuVendorIDs[i]; return testing::AssertionFailure() << msg.str(); } } expectedFeatureName = "packageOverrides3_2"; const FeatureConfig &cfg_2 = features[1]; if (cfg_2.mFeatureName != expectedFeatureName) { return testing::AssertionFailure() << "cfg.mFeatureName: " << cfg_2.mFeatureName << ", expected: " << expectedFeatureName; } expectedEnabled = true; if (cfg_2.mEnabled != expectedEnabled) { return testing::AssertionFailure() << "cfg.mEnabled: " << cfg_2.mEnabled << ", expected: " << expectedEnabled; } expectedGpuVendorIDs = { 0, // GpuVendorID::VENDOR_ID_TEST 0x8086, // GpuVendorID::VENDOR_ID_INTEL }; if (cfg_2.mGpuVendorIDs.size() != expectedGpuVendorIDs.size()) { return testing::AssertionFailure() << "cfg.mGpuVendorIDs.size(): " << cfg_2.mGpuVendorIDs.size() << ", expected: " << expectedGpuVendorIDs.size(); } for (int i = 0; i < expectedGpuVendorIDs.size(); i++) { if (cfg_2.mGpuVendorIDs[i] != expectedGpuVendorIDs[i]) { std::stringstream msg; msg << "cfg.mGpuVendorIDs[" << i << "]: 0x" << std::hex << cfg_2.mGpuVendorIDs[i] << ", expected: 0x" << std::hex << expectedGpuVendorIDs[i]; return testing::AssertionFailure() << msg.str(); } } return testing::AssertionSuccess(); } TEST_F(FeatureOverrideParserTest, packageOverrides3) { FeatureOverrides overrides = mFeatureOverrideParser.getFeatureOverrides(); EXPECT_TRUE(validatePackageOverrides3(overrides)); } TEST_F(FeatureOverrideParserTest, forceFileRead) { FeatureOverrides overrides = mFeatureOverrideParser.getFeatureOverrides(); Loading
services/gpuservice/tests/unittests/data/feature_config_test.txtpb +50 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,22 @@ global_features [ { feature_name: "globalOverrides1" enabled: False }, { feature_name: "globalOverrides2" enabled: True gpu_vendor_ids: [ VENDOR_ID_TEST, # Match every GPU Vendor ID, so the feature isn't dropped when parsed. VENDOR_ID_ARM ] }, { feature_name: "globalOverrides3" enabled: True gpu_vendor_ids: [ VENDOR_ID_TEST, # Match every GPU Vendor ID, so the feature isn't dropped when parsed. VENDOR_ID_INTEL ] } ] Loading @@ -36,5 +52,39 @@ package_features [ enabled: True } ] }, { package_name: "com.gpuservice_unittest.packageOverrides2" feature_configs: [ { feature_name: "packageOverrides2" enabled: False gpu_vendor_ids: [ VENDOR_ID_TEST, # Match every GPU Vendor ID, so the feature isn't dropped when parsed. VENDOR_ID_INTEL ] } ] }, { package_name: "com.gpuservice_unittest.packageOverrides3" feature_configs: [ { feature_name: "packageOverrides3_1" enabled: False gpu_vendor_ids: [ VENDOR_ID_TEST, # Match every GPU Vendor ID, so the feature isn't dropped when parsed. VENDOR_ID_ARM ] }, { feature_name: "packageOverrides3_2" enabled: True gpu_vendor_ids: [ VENDOR_ID_TEST, # Match every GPU Vendor ID, so the feature isn't dropped when parsed. VENDOR_ID_INTEL ] } ] } ]