Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(apple): support disabling metal validation #2373

Merged
merged 13 commits into from
Jan 28, 2025
19 changes: 19 additions & 0 deletions docs/ios.metalAPIValidation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
The API Validation layer checks for code that calls the Metal API incorrectly,
including errors in creating resources, encoding Metal commands, and performing
other common tasks.

> [!NOTE]
>
> The API validation layer has a small, but measureable, impact on CPU
> performance.

For more details, read Apple's documentation on
[Validating your app’s Metal API usage](https://developer.apple.com/documentation/xcode/validating-your-apps-metal-api-usage/).

<details>
<summary>History</summary>
Saadnajmi marked this conversation as resolved.
Show resolved Hide resolved

- [[4.1.0](https://github.com/microsoft/react-native-test-app/releases/tag/4.1.0)]
Added

</details>
7 changes: 2 additions & 5 deletions ios/test_app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,8 @@ def make_project!(xcodeproj, project_root, target_platform, options)
FileUtils.mkdir_p(destination)
FileUtils.cp_r(xcodeproj_src, destination)
name, display_name, version, single_app = app_config(project_root)
unless name.nil?
xcschemes_path = File.join(xcodeproj_dst, 'xcshareddata', 'xcschemes')
FileUtils.cp(File.join(xcschemes_path, 'ReactTestApp.xcscheme'),
File.join(xcschemes_path, "#{name}.xcscheme"))
end
xcschemes_path = File.join(xcodeproj_dst, 'xcshareddata', 'xcschemes')
configure_xcschemes!(xcschemes_path, project_root, target_platform, name)

# Link source files
%w[ReactTestApp ReactTestAppTests ReactTestAppUITests].each do |file|
Expand Down
24 changes: 24 additions & 0 deletions ios/xcode.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require 'rexml/document'

IPHONEOS_DEPLOYMENT_TARGET = 'IPHONEOS_DEPLOYMENT_TARGET'.freeze
MACOSX_DEPLOYMENT_TARGET = 'MACOSX_DEPLOYMENT_TARGET'.freeze
XROS_DEPLOYMENT_TARGET = 'XROS_DEPLOYMENT_TARGET'.freeze
Expand All @@ -20,3 +22,25 @@ def override_build_settings!(build_settings, overrides)
build_settings[setting] = value
end
end

def configure_xcschemes!(xcschemes_path, project_root, target_platform, name)
xcscheme = File.join(xcschemes_path, 'ReactTestApp.xcscheme')
metal_api_validation = platform_config('metalAPIValidation', project_root, target_platform)

# Oddly enough, to disable Metal API validation, we need to add `enableGPUValidationMode = "1"`
# to the xcscheme Launch Action.
if metal_api_validation == false
xcscheme_content = File.read(xcscheme)
doc = REXML::Document.new(xcscheme_content)
doc.root.elements['LaunchAction'].attributes['enableGPUValidationMode'] = '1'

File.open(xcscheme, 'w') do |file|
doc.write(file, 3)
end
end

return if name.nil?

# Make a copy of the ReactTestApp.xcscheme file with the app name for convenience.
FileUtils.cp(xcscheme, File.join(xcschemes_path, "#{name}.xcscheme"))
end
5 changes: 5 additions & 0 deletions schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@
"markdownDescription": "Sets the\n<a href='https://help.apple.com/xcode/mac/current/#/dev23aab79b4'>development\nteam</a> that the app should be assigned to.\n\nThis is the same as setting `DEVELOPMENT_TEAM` in Xcode.\n\n<details>\n<summary>History</summary>\n\n- [[0.9.7](https://github.com/microsoft/react-native-test-app/releases/tag/0.9.7)]\n Added\n\n</details>",
"type": "string"
},
"metalAPIValidation": {
"description": "The API Validation layer checks for code that calls the Metal API incorrectly, including errors in creating resources, encoding Metal commands, and performing other common tasks.",
"markdownDescription": "The API Validation layer checks for code that calls the Metal API incorrectly,\nincluding errors in creating resources, encoding Metal commands, and performing\nother common tasks.\n\n> [!NOTE]\n>\n> The API validation layer has a small, but measureable, impact on CPU\n> performance.\n\nFor more details, read Apple's documentation on\n[Validating your app’s Metal API usage](https://developer.apple.com/documentation/xcode/validating-your-apps-metal-api-usage/).\n\n<details>\n<summary>History</summary>\n\n- [[4.1.0](https://github.com/microsoft/react-native-test-app/releases/tag/4.1.0)]\n Added\n\n</details>",
"type": "boolean"
},
"privacyManifest": {
"description": "The privacy manifest is a property list that records the information regarding the types of data collected and the required reasons APIs your app or third-party SDK use.",
"markdownDescription": "The privacy manifest is a property list that records the information regarding\nthe types of data collected and the required reasons APIs your app or\nthird-party SDK use.\n\n- The types of data collected by your app or third-party SDK must be provided on\n all platforms.\n- The required reasons APIs your app or third-party SDK uses must be provided on\n iOS, iPadOS, tvOS, visionOS, and watchOS.\n\nBy default, a `PrivacyInfo.xcprivacy` is always generated with the following\nvalues:\n\n<!-- prettier-ignore-start -->\n```json\n{\n \"NSPrivacyTracking\": false,\n \"NSPrivacyTrackingDomains\": [],\n \"NSPrivacyCollectedDataTypes\": [],\n \"NSPrivacyAccessedAPITypes\": [\n {\n \"NSPrivacyAccessedAPIType\":\n \"NSPrivacyAccessedAPICategoryFileTimestamp\",\n \"NSPrivacyAccessedAPITypeReasons\": [\"C617.1\"]\n },\n {\n \"NSPrivacyAccessedAPIType\":\n \"NSPrivacyAccessedAPICategorySystemBootTime\",\n \"NSPrivacyAccessedAPITypeReasons\": [\"35F9.1\"]\n },\n {\n \"NSPrivacyAccessedAPIType\":\n \"NSPrivacyAccessedAPICategoryUserDefaults\",\n \"NSPrivacyAccessedAPITypeReasons\": [\"CA92.1\"]\n }\n ]\n}\n```\n<!-- prettier-ignore-end -->\n\nFor more details, read Apple's documentation on\n[Privacy manifest files](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files).\n\n<details>\n<summary>History</summary>\n\n- [[3.6.0](https://github.com/microsoft/react-native-test-app/releases/tag/3.6.0)]\n Added\n\n</details>",
Expand Down
1 change: 1 addition & 0 deletions scripts/internal/generate-schema.mts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export async function readDocumentation(): Promise<Partial<Docs>> {
"ios.icons",
"ios.icons.primaryIcon",
"ios.icons.alternateIcons",
"ios.metalAPIValidation",
"ios.privacyManifest",
"macos.applicationCategoryType",
"macos.humanReadableCopyright",
Expand Down
5 changes: 5 additions & 0 deletions scripts/schema.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ export function generateSchema(docs = {}) {
markdownDescription: docs["ios.developmentTeam"],
type: "string",
},
metalAPIValidation: {
description: extractBrief(docs["ios.metalAPIValidation"]),
markdownDescription: docs["ios.metalAPIValidation"],
type: "boolean",
},
privacyManifest: {
description: extractBrief(docs["ios.privacyManifest"]),
markdownDescription: docs["ios.privacyManifest"],
Expand Down
1 change: 1 addition & 0 deletions scripts/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ export type Docs = {
"ios.icons": string;
"ios.icons.primaryIcon": string;
"ios.icons.alternateIcons": string;
"ios.metalAPIValidation": string;
"ios.privacyManifest": string;
"macos.applicationCategoryType": string;
"macos.humanReadableCopyright": string;
Expand Down
Loading