android: frontend: Add support for GPU driver selection.
parent
4c38220a64
commit
b0f8aef057
@ -0,0 +1,130 @@
|
||||
package org.yuzu.yuzu_emu.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
|
||||
import org.yuzu.yuzu_emu.NativeLibrary;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
public class GpuDriverHelper {
|
||||
private static final String META_JSON_FILENAME = "meta.json";
|
||||
private static final String DRIVER_INTERNAL_FILENAME = "gpu_driver.zip";
|
||||
private static String fileRedirectionPath;
|
||||
private static String driverInstallationPath;
|
||||
private static String hookLibPath;
|
||||
|
||||
private static void unzip(String zipFilePath, String destDir) throws IOException {
|
||||
File dir = new File(destDir);
|
||||
|
||||
// Create output directory if it doesn't exist
|
||||
if (!dir.exists()) dir.mkdirs();
|
||||
|
||||
// Unpack the files.
|
||||
ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFilePath));
|
||||
byte[] buffer = new byte[1024];
|
||||
ZipEntry ze = zis.getNextEntry();
|
||||
while (ze != null) {
|
||||
String fileName = ze.getName();
|
||||
File newFile = new File(destDir + fileName);
|
||||
newFile.getParentFile().mkdirs();
|
||||
FileOutputStream fos = new FileOutputStream(newFile);
|
||||
int len;
|
||||
while ((len = zis.read(buffer)) > 0) {
|
||||
fos.write(buffer, 0, len);
|
||||
}
|
||||
fos.close();
|
||||
zis.closeEntry();
|
||||
ze = zis.getNextEntry();
|
||||
}
|
||||
zis.closeEntry();
|
||||
}
|
||||
|
||||
public static void initializeDriverParameters(Context context) {
|
||||
try {
|
||||
// Initialize the file redirection directory.
|
||||
fileRedirectionPath = context.getExternalFilesDir(null).getCanonicalPath() + "/gpu/vk_file_redirect/";
|
||||
|
||||
// Initialize the driver installation directory.
|
||||
driverInstallationPath = context.getFilesDir().getCanonicalPath() + "/gpu_driver/";
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
// Initialize directories.
|
||||
initializeDirectories();
|
||||
|
||||
// Initialize hook libraries directory.
|
||||
hookLibPath = context.getApplicationInfo().nativeLibraryDir + "/";
|
||||
|
||||
// Initialize GPU driver.
|
||||
NativeLibrary.InitializeGpuDriver(hookLibPath, driverInstallationPath, getCustomDriverLibraryName(), fileRedirectionPath);
|
||||
}
|
||||
|
||||
public static void installDefaultDriver(Context context) {
|
||||
// Removing the installed driver will result in the backend using the default system driver.
|
||||
File driverInstallationDir = new File(driverInstallationPath);
|
||||
deleteRecursive(driverInstallationDir);
|
||||
initializeDriverParameters(context);
|
||||
}
|
||||
|
||||
public static void installCustomDriver(Context context, Uri driverPathUri) {
|
||||
// Revert to system default in the event the specified driver is bad.
|
||||
installDefaultDriver(context);
|
||||
|
||||
// Ensure we have directories.
|
||||
initializeDirectories();
|
||||
|
||||
// Copy the zip file URI into our private storage.
|
||||
FileUtil.copyUriToInternalStorage(context, driverPathUri, driverInstallationPath, DRIVER_INTERNAL_FILENAME);
|
||||
|
||||
// Unzip the driver.
|
||||
try {
|
||||
unzip(driverInstallationPath + DRIVER_INTERNAL_FILENAME, driverInstallationPath);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
// Initialize the driver parameters.
|
||||
initializeDriverParameters(context);
|
||||
}
|
||||
|
||||
public static String getCustomDriverName() {
|
||||
// Parse the custom driver metadata to retrieve the name.
|
||||
GpuDriverMetadata metadata = new GpuDriverMetadata(driverInstallationPath + META_JSON_FILENAME);
|
||||
return metadata.name;
|
||||
}
|
||||
|
||||
private static String getCustomDriverLibraryName() {
|
||||
// Parse the custom driver metadata to retrieve the library name.
|
||||
GpuDriverMetadata metadata = new GpuDriverMetadata(driverInstallationPath + META_JSON_FILENAME);
|
||||
return metadata.libraryName;
|
||||
}
|
||||
|
||||
private static void initializeDirectories() {
|
||||
// Ensure the file redirection directory exists.
|
||||
File fileRedirectionDir = new File(fileRedirectionPath);
|
||||
if (!fileRedirectionDir.exists()) {
|
||||
fileRedirectionDir.mkdirs();
|
||||
}
|
||||
// Ensure the driver installation directory exists.
|
||||
File driverInstallationDir = new File(driverInstallationPath);
|
||||
if (!driverInstallationDir.exists()) {
|
||||
driverInstallationDir.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
private static void deleteRecursive(File fileOrDirectory) {
|
||||
if (fileOrDirectory.isDirectory()) {
|
||||
for (File child : fileOrDirectory.listFiles()) {
|
||||
deleteRecursive(child);
|
||||
}
|
||||
}
|
||||
fileOrDirectory.delete();
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package org.yuzu.yuzu_emu.utils;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class GpuDriverMetadata {
|
||||
|
||||
public String name;
|
||||
public String description;
|
||||
public String author;
|
||||
public String vendor;
|
||||
public String driverVersion;
|
||||
public int minApi;
|
||||
public String libraryName;
|
||||
|
||||
public GpuDriverMetadata(String metadataFilePath) {
|
||||
try {
|
||||
JSONObject json = new JSONObject(getStringFromFile(metadataFilePath));
|
||||
name = json.getString("name");
|
||||
description = json.getString("description");
|
||||
author = json.getString("author");
|
||||
vendor = json.getString("vendor");
|
||||
driverVersion = json.getString("driverVersion");
|
||||
minApi = json.getInt("minApi");
|
||||
libraryName = json.getString("libraryName");
|
||||
} catch (JSONException e) {
|
||||
// JSON is malformed, ignore and treat as unsupported metadata.
|
||||
} catch (IOException e) {
|
||||
// File is inaccessible, ignore and treat as unsupported metadata.
|
||||
}
|
||||
}
|
||||
|
||||
private static String getStringFromFile(String filePath) throws IOException {
|
||||
Path path = Paths.get(filePath);
|
||||
byte[] bytes = Files.readAllBytes(path);
|
||||
return new String(bytes, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue