Skip to content

Commit 6340221

Browse files
committed
gpuservice: Add GPU Vendor ID support to FeatureConfig proto
Add GPU vendor ID support to the FeatureConfig protobuf, to allow making feature override decisions based on the GPU vendor of the device. For example, restricting a particular feature override to Intel or ARM GPU devices. Bug: 372694741 Test: atest gpuservice_unittest Test: cmd gpu featureOverrides Test: atest android.boottime.BootTimeTest#testSuccessiveBoots Flag: com.android.graphics.graphicsenv.flags.feature_overrides Change-Id: I6b141ed725db2736ffa523bb50006c609a1e49a1
1 parent c93479c commit 6340221

5 files changed

Lines changed: 400 additions & 7 deletions

File tree

services/gpuservice/feature_override/Android.bp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ cc_library_static {
6969
name: "libfeatureoverride",
7070
defaults: [
7171
"libfeatureoverride_deps",
72+
"libvkjson_deps",
7273
],
7374
srcs: [
7475
":feature_config_proto_definitions",
@@ -85,6 +86,9 @@ cc_library_static {
8586
cppflags: [
8687
"-Wno-sign-compare",
8788
],
89+
static_libs: [
90+
"libvkjson",
91+
],
8892
export_include_dirs: ["include"],
8993
proto: {
9094
type: "lite",

services/gpuservice/feature_override/FeatureOverrideParser.cpp

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@
2323
#include <sys/stat.h>
2424
#include <vector>
2525

26+
#include <android-base/macros.h>
2627
#include <graphicsenv/FeatureOverrides.h>
2728
#include <log/log.h>
29+
#include <vkjson.h>
2830

2931
#include "feature_config.pb.h"
3032

@@ -35,13 +37,53 @@ void resetFeatureOverrides(android::FeatureOverrides &featureOverrides) {
3537
featureOverrides.mPackageFeatures.clear();
3638
}
3739

40+
bool
41+
gpuVendorIdMatches(const VkJsonInstance &vkJsonInstance,
42+
const uint32_t &configVendorId) {
43+
if (vkJsonInstance.devices.empty()) {
44+
return false;
45+
}
46+
47+
// Always match the TEST Vendor ID
48+
if (configVendorId == feature_override::GpuVendorID::VENDOR_ID_TEST) {
49+
return true;
50+
}
51+
52+
// Always assume one GPU device.
53+
uint32_t vendorID = vkJsonInstance.devices.front().properties.vendorID;
54+
55+
return vendorID == configVendorId;
56+
}
57+
58+
bool
59+
conditionsMet(const VkJsonInstance &vkJsonInstance,
60+
const android::FeatureConfig &featureConfig) {
61+
bool gpuVendorIdMatch = false;
62+
63+
if (featureConfig.mGpuVendorIDs.empty()) {
64+
gpuVendorIdMatch = true;
65+
} else {
66+
for (const auto &gpuVendorID: featureConfig.mGpuVendorIDs) {
67+
if (gpuVendorIdMatches(vkJsonInstance, gpuVendorID)) {
68+
gpuVendorIdMatch = true;
69+
break;
70+
}
71+
}
72+
}
73+
74+
return gpuVendorIdMatch;
75+
}
76+
3877
void initFeatureConfig(android::FeatureConfig &featureConfig,
3978
const feature_override::FeatureConfig &featureConfigProto) {
4079
featureConfig.mFeatureName = featureConfigProto.feature_name();
4180
featureConfig.mEnabled = featureConfigProto.enabled();
81+
for (const auto &gpuVendorIdProto: featureConfigProto.gpu_vendor_ids()) {
82+
featureConfig.mGpuVendorIDs.emplace_back(static_cast<uint32_t>(gpuVendorIdProto));
83+
}
4284
}
4385

44-
feature_override::FeatureOverrideProtos readFeatureConfigProtos(std::string configFilePath) {
86+
feature_override::FeatureOverrideProtos readFeatureConfigProtos(const std::string &configFilePath) {
4587
feature_override::FeatureOverrideProtos overridesProtos;
4688

4789
std::ifstream protobufBinaryFile(configFilePath.c_str());
@@ -78,9 +120,15 @@ std::string FeatureOverrideParser::getFeatureOverrideFilePath() const {
78120

79121
bool FeatureOverrideParser::shouldReloadFeatureOverrides() const {
80122
std::string configFilePath = getFeatureOverrideFilePath();
123+
124+
std::ifstream configFile(configFilePath);
125+
if (!configFile.good()) {
126+
return false;
127+
}
128+
81129
struct stat fileStat{};
82-
if (stat(getFeatureOverrideFilePath().c_str(), &fileStat) != 0) {
83-
ALOGE("Error getting file information for '%s': %s", getFeatureOverrideFilePath().c_str(),
130+
if (stat(configFilePath.c_str(), &fileStat) != 0) {
131+
ALOGE("Error getting file information for '%s': %s", configFilePath.c_str(),
84132
strerror(errno));
85133
// stat'ing the file failed, so return false since reading it will also likely fail.
86134
return false;
@@ -100,12 +148,22 @@ void FeatureOverrideParser::parseFeatureOverrides() {
100148
// Clear out the stale values before adding the newly parsed data.
101149
resetFeatureOverrides(mFeatureOverrides);
102150

151+
if (overridesProtos.global_features().empty() &&
152+
overridesProtos.package_features().empty()) {
153+
// No overrides to parse.
154+
return;
155+
}
156+
157+
const VkJsonInstance vkJsonInstance = VkJsonGetInstance();
158+
103159
// Global feature overrides.
104160
for (const auto &featureConfigProto: overridesProtos.global_features()) {
105161
FeatureConfig featureConfig;
106162
initFeatureConfig(featureConfig, featureConfigProto);
107163

108-
mFeatureOverrides.mGlobalFeatures.emplace_back(featureConfig);
164+
if (conditionsMet(vkJsonInstance, featureConfig)) {
165+
mFeatureOverrides.mGlobalFeatures.emplace_back(featureConfig);
166+
}
109167
}
110168

111169
// App-specific feature overrides.
@@ -122,7 +180,9 @@ void FeatureOverrideParser::parseFeatureOverrides() {
122180
FeatureConfig featureConfig;
123181
initFeatureConfig(featureConfig, featureConfigProto);
124182

125-
featureConfigs.emplace_back(featureConfig);
183+
if (conditionsMet(vkJsonInstance, featureConfig)) {
184+
featureConfigs.emplace_back(featureConfig);
185+
}
126186
}
127187

128188
mFeatureOverrides.mPackageFeatures[packageName] = featureConfigs;

services/gpuservice/feature_override/proto/feature_config.proto

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,44 @@ package feature_override;
2020

2121
option optimize_for = LITE_RUNTIME;
2222

23+
/**
24+
* GPU Vendor IDs.
25+
* Taken from: external/angle/src/libANGLE/renderer/driver_utils.h
26+
*/
27+
enum GpuVendorID
28+
{
29+
// Test ID matches every GPU Vendor ID.
30+
VENDOR_ID_TEST = 0;
31+
VENDOR_ID_AMD = 0x1002;
32+
VENDOR_ID_ARM = 0x13B5;
33+
// Broadcom devices won't use PCI, but this is their Vulkan vendor id.
34+
VENDOR_ID_BROADCOM = 0x14E4;
35+
VENDOR_ID_GOOGLE = 0x1AE0;
36+
VENDOR_ID_INTEL = 0x8086;
37+
VENDOR_ID_MESA = 0x10005;
38+
VENDOR_ID_MICROSOFT = 0x1414;
39+
VENDOR_ID_NVIDIA = 0x10DE;
40+
VENDOR_ID_POWERVR = 0x1010;
41+
// This is Qualcomm PCI Vendor ID.
42+
// Android doesn't have a PCI bus, but all we need is a unique id.
43+
VENDOR_ID_QUALCOMM = 0x5143;
44+
VENDOR_ID_SAMSUNG = 0x144D;
45+
VENDOR_ID_VIVANTE = 0x9999;
46+
VENDOR_ID_VMWARE = 0x15AD;
47+
VENDOR_ID_VIRTIO = 0x1AF4;
48+
}
49+
2350
/**
2451
* Feature Configuration
2552
* feature_name: Feature name (see external/angle/include/platform/autogen/FeaturesVk_autogen.h).
2653
* enabled: Either enable or disable the feature.
54+
* gpu_vendor_ids: The GPU architectures this FeatureConfig applies to, if any.
2755
*/
2856
message FeatureConfig
2957
{
3058
string feature_name = 1;
3159
bool enabled = 2;
60+
repeated GpuVendorID gpu_vendor_ids = 3;
3261
}
3362

3463
/**

0 commit comments

Comments
 (0)