1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-13 13:31:48 +00:00

Improve vulkan capability detection on Android

- Add runtime check and abort when the device doesn't meet the requirements for vulkan support
- Add filters to the AndroidManifest when exporting with a vulkan renderer
This commit is contained in:
Fredia Huya-Kouadio
2023-02-05 17:16:13 -08:00
parent b0598dcdb7
commit 034fd15b8a
4 changed files with 48 additions and 2 deletions

View File

@@ -252,6 +252,7 @@ static const char *APK_ASSETS_DIRECTORY = "res://android/build/assets";
static const char *AAB_ASSETS_DIRECTORY = "res://android/build/assetPacks/installTime/src/main/assets"; static const char *AAB_ASSETS_DIRECTORY = "res://android/build/assetPacks/installTime/src/main/assets";
static const int DEFAULT_MIN_SDK_VERSION = 21; // Should match the value in 'platform/android/java/app/config.gradle#minSdk' static const int DEFAULT_MIN_SDK_VERSION = 21; // Should match the value in 'platform/android/java/app/config.gradle#minSdk'
static const int VULKAN_MIN_SDK_VERSION = 24;
static const int DEFAULT_TARGET_SDK_VERSION = 32; // Should match the value in 'platform/android/java/app/config.gradle#targetSdk' static const int DEFAULT_TARGET_SDK_VERSION = 32; // Should match the value in 'platform/android/java/app/config.gradle#targetSdk'
#ifndef ANDROID_ENABLED #ifndef ANDROID_ENABLED
@@ -1056,6 +1057,15 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p
Vector<bool> feature_required_list; Vector<bool> feature_required_list;
Vector<int> feature_versions; Vector<int> feature_versions;
String current_renderer = GLOBAL_GET("rendering/renderer/rendering_method.mobile");
bool has_vulkan = current_renderer == "forward_plus" || current_renderer == "mobile";
if (has_vulkan) {
// Require vulkan hardware level 1 support
feature_names.push_back("android.hardware.vulkan.level");
feature_required_list.push_back(true);
feature_versions.push_back(1);
}
if (feature_names.size() > 0) { if (feature_names.size() > 0) {
ofs += 24; // skip over end tag ofs += 24; // skip over end tag
@@ -2373,6 +2383,19 @@ bool EditorExportPlatformAndroid::has_valid_project_configuration(const Ref<Edit
err += "\n"; err += "\n";
} }
String current_renderer = GLOBAL_GET("rendering/renderer/rendering_method.mobile");
bool uses_vulkan = current_renderer == "forward_plus" || current_renderer == "mobile";
if (current_renderer == "forward_plus") {
// Warning only, so don't override `valid`.
err += vformat(TTR("The \"%s\" renderer is designed for Desktop devices, and is not suitable for Android devices."), current_renderer);
err += "\n";
}
if (uses_vulkan && min_sdk_int < VULKAN_MIN_SDK_VERSION) {
// Warning only, so don't override `valid`.
err += vformat(TTR("\"Min SDK\" should be greater or equal to %d for the \"%s\" renderer."), VULKAN_MIN_SDK_VERSION, current_renderer);
err += "\n";
}
r_error = err; r_error = err;
return valid; return valid;
} }

View File

@@ -273,6 +273,12 @@ String _get_xr_features_tag(const Ref<EditorExportPreset> &p_preset) {
manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"com.oculus.feature.PASSTHROUGH\" android:required=\"true\" />\n"; manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"com.oculus.feature.PASSTHROUGH\" android:required=\"true\" />\n";
} }
} }
String current_renderer = GLOBAL_GET("rendering/renderer/rendering_method.mobile");
bool has_vulkan = current_renderer == "forward_plus" || current_renderer == "mobile";
if (has_vulkan) {
manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"android.hardware.vulkan.level\" android:required=\"true\" android:version=\"1\" />\n";
}
return manifest_xr_features; return manifest_xr_features;
} }

View File

@@ -14,6 +14,7 @@
<string name="text_button_cancel_verify">Cancel Verification</string> <string name="text_button_cancel_verify">Cancel Verification</string>
<string name="text_error_title">Error!</string> <string name="text_error_title">Error!</string>
<string name="error_engine_setup_message">Unable to setup the Godot Engine! Aborting…</string> <string name="error_engine_setup_message">Unable to setup the Godot Engine! Aborting…</string>
<string name="error_missing_vulkan_requirements_message">This device does not meet the requirements for Vulkan support! Aborting…</string>
<!-- APK Expansion Strings --> <!-- APK Expansion Strings -->

View File

@@ -258,13 +258,13 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
*/ */
@Keep @Keep
private boolean onVideoInit() { private boolean onVideoInit() {
final Activity activity = getActivity(); final Activity activity = requireActivity();
containerLayout = new FrameLayout(activity); containerLayout = new FrameLayout(activity);
containerLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); containerLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
// GodotEditText layout // GodotEditText layout
GodotEditText editText = new GodotEditText(activity); GodotEditText editText = new GodotEditText(activity);
editText.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, editText.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
(int)getResources().getDimension(R.dimen.text_edit_height))); (int)getResources().getDimension(R.dimen.text_edit_height)));
// ...add to FrameLayout // ...add to FrameLayout
containerLayout.addView(editText); containerLayout.addView(editText);
@@ -279,6 +279,11 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
if (renderer.equals("gl_compatibility")) { if (renderer.equals("gl_compatibility")) {
mRenderView = new GodotGLRenderView(activity, this, xrMode, use_debug_opengl); mRenderView = new GodotGLRenderView(activity, this, xrMode, use_debug_opengl);
} else { } else {
if (!meetsVulkanRequirements(activity.getPackageManager())) {
Log.e(TAG, "Missing requirements for vulkan support! Aborting...");
alert(R.string.error_missing_vulkan_requirements_message, R.string.text_error_title, this::forceQuit);
return false;
}
mRenderView = new GodotVulkanRenderView(activity, this); mRenderView = new GodotVulkanRenderView(activity, this);
} }
@@ -317,6 +322,17 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
return true; return true;
} }
/**
* Returns true if the device meets the base requirements for Vulkan support, false otherwise.
*/
private boolean meetsVulkanRequirements(@Nullable PackageManager packageManager) {
if (packageManager == null) {
return false;
}
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && packageManager.hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_LEVEL, 1);
}
public void setKeepScreenOn(final boolean p_enabled) { public void setKeepScreenOn(final boolean p_enabled) {
runOnUiThread(() -> { runOnUiThread(() -> {
if (p_enabled) { if (p_enabled) {