summaryrefslogtreecommitdiff
path: root/src/android
diff options
context:
space:
mode:
authorGravatar bunnei2023-02-18 23:42:07 -0800
committerGravatar bunnei2023-06-03 00:05:31 -0700
commit4c38220a644f8292f4915eaabb2f80d3d0badab0 (patch)
treed6a2291e26e3723ec0e3124f9bb117487dd3966c /src/android
parentcore: frontend: Refactor GraphicsContext to its own module. (diff)
downloadyuzu-4c38220a644f8292f4915eaabb2f80d3d0badab0.tar.gz
yuzu-4c38220a644f8292f4915eaabb2f80d3d0badab0.tar.xz
yuzu-4c38220a644f8292f4915eaabb2f80d3d0badab0.zip
android: native: Add support for custom Vulkan driver loading.
Diffstat (limited to 'src/android')
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.java2
-rw-r--r--src/android/app/src/main/jni/CMakeLists.txt2
-rw-r--r--src/android/app/src/main/jni/emu_window/emu_window.cpp39
-rw-r--r--src/android/app/src/main/jni/emu_window/emu_window.h41
-rw-r--r--src/android/app/src/main/jni/native.cpp64
-rw-r--r--src/android/app/src/main/jni/native.h5
6 files changed, 109 insertions, 44 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.java
index a0f6c1f7b..e56196310 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.java
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.java
@@ -181,6 +181,8 @@ public final class NativeLibrary {
181 181
182 public static native void SetAppDirectory(String directory); 182 public static native void SetAppDirectory(String directory);
183 183
184 public static native void SetGpuDriverParameters(String hookLibDir, String customDriverDir, String customDriverName, String fileRedirectDir);
185
184 public static native boolean ReloadKeys(); 186 public static native boolean ReloadKeys();
185 187
186 // Create the config.ini file. 188 // Create the config.ini file.
diff --git a/src/android/app/src/main/jni/CMakeLists.txt b/src/android/app/src/main/jni/CMakeLists.txt
index e5c9d57f2..f80c166f4 100644
--- a/src/android/app/src/main/jni/CMakeLists.txt
+++ b/src/android/app/src/main/jni/CMakeLists.txt
@@ -13,6 +13,6 @@ add_library(yuzu-android SHARED
13set_property(TARGET yuzu-android PROPERTY IMPORTED_LOCATION ${FFmpeg_LIBRARY_DIR}) 13set_property(TARGET yuzu-android PROPERTY IMPORTED_LOCATION ${FFmpeg_LIBRARY_DIR})
14 14
15target_link_libraries(yuzu-android PRIVATE audio_core common core input_common) 15target_link_libraries(yuzu-android PRIVATE audio_core common core input_common)
16target_link_libraries(yuzu-android PRIVATE android camera2ndk EGL glad inih jnigraphics log) 16target_link_libraries(yuzu-android PRIVATE android camera2ndk EGL glad inih jnigraphics adrenotools log)
17 17
18set(CPACK_PACKAGE_EXECUTABLES ${CPACK_PACKAGE_EXECUTABLES} yuzu-android) 18set(CPACK_PACKAGE_EXECUTABLES ${CPACK_PACKAGE_EXECUTABLES} yuzu-android)
diff --git a/src/android/app/src/main/jni/emu_window/emu_window.cpp b/src/android/app/src/main/jni/emu_window/emu_window.cpp
index 2beba6804..ad17cf129 100644
--- a/src/android/app/src/main/jni/emu_window/emu_window.cpp
+++ b/src/android/app/src/main/jni/emu_window/emu_window.cpp
@@ -7,61 +7,62 @@
7#include "jni/emu_window/emu_window.h" 7#include "jni/emu_window/emu_window.h"
8 8
9void EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) { 9void EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) {
10 render_window = surface; 10 m_render_window = surface;
11} 11}
12 12
13void EmuWindow_Android::OnTouchPressed(int id, float x, float y) { 13void EmuWindow_Android::OnTouchPressed(int id, float x, float y) {
14 const auto [touch_x, touch_y] = MapToTouchScreen(x, y); 14 const auto [touch_x, touch_y] = MapToTouchScreen(x, y);
15 input_subsystem->GetTouchScreen()->TouchPressed(touch_x, touch_y, id); 15 m_input_subsystem->GetTouchScreen()->TouchPressed(touch_x, touch_y, id);
16} 16}
17 17
18void EmuWindow_Android::OnTouchMoved(int id, float x, float y) { 18void EmuWindow_Android::OnTouchMoved(int id, float x, float y) {
19 const auto [touch_x, touch_y] = MapToTouchScreen(x, y); 19 const auto [touch_x, touch_y] = MapToTouchScreen(x, y);
20 input_subsystem->GetTouchScreen()->TouchMoved(touch_x, touch_y, id); 20 m_input_subsystem->GetTouchScreen()->TouchMoved(touch_x, touch_y, id);
21} 21}
22 22
23void EmuWindow_Android::OnTouchReleased(int id) { 23void EmuWindow_Android::OnTouchReleased(int id) {
24 input_subsystem->GetTouchScreen()->TouchReleased(id); 24 m_input_subsystem->GetTouchScreen()->TouchReleased(id);
25} 25}
26 26
27void EmuWindow_Android::OnGamepadButtonEvent(int player_index, int button_id, bool pressed) { 27void EmuWindow_Android::OnGamepadButtonEvent(int player_index, int button_id, bool pressed) {
28 input_subsystem->GetVirtualGamepad()->SetButtonState(player_index, button_id, pressed); 28 m_input_subsystem->GetVirtualGamepad()->SetButtonState(player_index, button_id, pressed);
29} 29}
30 30
31void EmuWindow_Android::OnGamepadJoystickEvent(int player_index, int stick_id, float x, float y) { 31void EmuWindow_Android::OnGamepadJoystickEvent(int player_index, int stick_id, float x, float y) {
32 input_subsystem->GetVirtualGamepad()->SetStickPosition(player_index, stick_id, x, y); 32 m_input_subsystem->GetVirtualGamepad()->SetStickPosition(player_index, stick_id, x, y);
33} 33}
34 34
35void EmuWindow_Android::OnGamepadMotionEvent(int player_index, u64 delta_timestamp, float gyro_x, 35void EmuWindow_Android::OnGamepadMotionEvent(int player_index, u64 delta_timestamp, float gyro_x,
36 float gyro_y, float gyro_z, float accel_x, 36 float gyro_y, float gyro_z, float accel_x,
37 float accel_y, float accel_z) { 37 float accel_y, float accel_z) {
38 input_subsystem->GetVirtualGamepad()->SetMotionState(player_index, delta_timestamp, gyro_x, 38 m_input_subsystem->GetVirtualGamepad()->SetMotionState(
39 gyro_y, gyro_z, accel_x, accel_y, accel_z); 39 player_index, delta_timestamp, gyro_x, gyro_y, gyro_z, accel_x, accel_y, accel_z);
40} 40}
41 41
42EmuWindow_Android::EmuWindow_Android(InputCommon::InputSubsystem* input_subsystem_, 42EmuWindow_Android::EmuWindow_Android(InputCommon::InputSubsystem* input_subsystem,
43 ANativeWindow* surface_) 43 ANativeWindow* surface,
44 : input_subsystem{input_subsystem_} { 44 std::shared_ptr<Common::DynamicLibrary> driver_library)
45 : m_input_subsystem{input_subsystem}, m_driver_library{driver_library} {
45 LOG_INFO(Frontend, "initializing"); 46 LOG_INFO(Frontend, "initializing");
46 47
47 if (!surface_) { 48 if (!surface) {
48 LOG_CRITICAL(Frontend, "surface is nullptr"); 49 LOG_CRITICAL(Frontend, "surface is nullptr");
49 return; 50 return;
50 } 51 }
51 52
52 window_width = ANativeWindow_getWidth(surface_); 53 m_window_width = ANativeWindow_getWidth(surface);
53 window_height = ANativeWindow_getHeight(surface_); 54 m_window_height = ANativeWindow_getHeight(surface);
54 55
55 // Ensures that we emulate with the correct aspect ratio. 56 // Ensures that we emulate with the correct aspect ratio.
56 UpdateCurrentFramebufferLayout(window_width, window_height); 57 UpdateCurrentFramebufferLayout(m_window_width, m_window_height);
57 58
58 host_window = surface_; 59 m_host_window = surface;
59 window_info.type = Core::Frontend::WindowSystemType::Android; 60 window_info.type = Core::Frontend::WindowSystemType::Android;
60 window_info.render_surface = reinterpret_cast<void*>(host_window); 61 window_info.render_surface = reinterpret_cast<void*>(m_host_window);
61 62
62 input_subsystem->Initialize(); 63 m_input_subsystem->Initialize();
63} 64}
64 65
65EmuWindow_Android::~EmuWindow_Android() { 66EmuWindow_Android::~EmuWindow_Android() {
66 input_subsystem->Shutdown(); 67 m_input_subsystem->Shutdown();
67} 68}
diff --git a/src/android/app/src/main/jni/emu_window/emu_window.h b/src/android/app/src/main/jni/emu_window/emu_window.h
index 544924caa..1c1edf62c 100644
--- a/src/android/app/src/main/jni/emu_window/emu_window.h
+++ b/src/android/app/src/main/jni/emu_window/emu_window.h
@@ -1,21 +1,34 @@
1#pragma once 1#pragma once
2 2
3#include <memory>
4
3#include "core/frontend/emu_window.h" 5#include "core/frontend/emu_window.h"
6#include "core/frontend/graphics_context.h"
4#include "input_common/main.h" 7#include "input_common/main.h"
5 8
6struct ANativeWindow; 9struct ANativeWindow;
7 10
8class SharedContext_Android : public Core::Frontend::GraphicsContext { 11class GraphicsContext_Android final : public Core::Frontend::GraphicsContext {
9public: 12public:
10 SharedContext_Android() = default; 13 explicit GraphicsContext_Android(std::shared_ptr<Common::DynamicLibrary> driver_library)
11 ~SharedContext_Android() = default; 14 : m_driver_library{driver_library} {}
12 void MakeCurrent() override {} 15
13 void DoneCurrent() override {} 16 ~GraphicsContext_Android() = default;
17
18 std::shared_ptr<Common::DynamicLibrary> GetDriverLibrary() override {
19 return m_driver_library;
20 }
21
22private:
23 std::shared_ptr<Common::DynamicLibrary> m_driver_library;
14}; 24};
15 25
16class EmuWindow_Android : public Core::Frontend::EmuWindow { 26class EmuWindow_Android final : public Core::Frontend::EmuWindow {
27
17public: 28public:
18 EmuWindow_Android(InputCommon::InputSubsystem* input_subsystem_, ANativeWindow* surface_); 29 EmuWindow_Android(InputCommon::InputSubsystem* input_subsystem, ANativeWindow* surface,
30 std::shared_ptr<Common::DynamicLibrary> driver_library);
31
19 ~EmuWindow_Android(); 32 ~EmuWindow_Android();
20 33
21 void OnSurfaceChanged(ANativeWindow* surface); 34 void OnSurfaceChanged(ANativeWindow* surface);
@@ -29,18 +42,20 @@ public:
29 void OnFrameDisplayed() override {} 42 void OnFrameDisplayed() override {}
30 43
31 std::unique_ptr<Core::Frontend::GraphicsContext> CreateSharedContext() const override { 44 std::unique_ptr<Core::Frontend::GraphicsContext> CreateSharedContext() const override {
32 return {std::make_unique<SharedContext_Android>()}; 45 return {std::make_unique<GraphicsContext_Android>(m_driver_library)};
33 } 46 }
34 bool IsShown() const override { 47 bool IsShown() const override {
35 return true; 48 return true;
36 }; 49 };
37 50
38private: 51private:
39 InputCommon::InputSubsystem* input_subsystem{}; 52 InputCommon::InputSubsystem* m_input_subsystem{};
53
54 ANativeWindow* m_render_window{};
55 ANativeWindow* m_host_window{};
40 56
41 ANativeWindow* render_window{}; 57 float m_window_width{};
42 ANativeWindow* host_window{}; 58 float m_window_height{};
43 59
44 float window_width{}; 60 std::shared_ptr<Common::DynamicLibrary> m_driver_library;
45 float window_height{};
46}; 61};
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp
index 0a2a65721..a8f3d135e 100644
--- a/src/android/app/src/main/jni/native.cpp
+++ b/src/android/app/src/main/jni/native.cpp
@@ -5,11 +5,15 @@
5#include <locale> 5#include <locale>
6#include <string> 6#include <string>
7#include <string_view> 7#include <string_view>
8#include <dlfcn.h>
9
10#include <adrenotools/driver.h>
8 11
9#include <android/api-level.h> 12#include <android/api-level.h>
10#include <android/native_window_jni.h> 13#include <android/native_window_jni.h>
11 14
12#include "common/detached_tasks.h" 15#include "common/detached_tasks.h"
16#include "common/dynamic_library.h"
13#include "common/fs/path_util.h" 17#include "common/fs/path_util.h"
14#include "common/logging/backend.h" 18#include "common/logging/backend.h"
15#include "common/logging/log.h" 19#include "common/logging/log.h"
@@ -70,6 +74,29 @@ public:
70 m_native_window = m_native_window_; 74 m_native_window = m_native_window_;
71 } 75 }
72 76
77 void InitializeGpuDriver(const std::string& hook_lib_dir, const std::string& custom_driver_dir,
78 const std::string& custom_driver_name,
79 const std::string& file_redirect_dir) {
80 void* handle{};
81
82 // Try to load a custom driver.
83 if (custom_driver_name.size()) {
84 handle = adrenotools_open_libvulkan(
85 RTLD_NOW, ADRENOTOOLS_DRIVER_CUSTOM | ADRENOTOOLS_DRIVER_FILE_REDIRECT, nullptr,
86 hook_lib_dir.c_str(), custom_driver_dir.c_str(), custom_driver_name.c_str(),
87 file_redirect_dir.c_str(), nullptr);
88 }
89
90 // Try to load the system driver.
91 if (!handle) {
92 handle = adrenotools_open_libvulkan(RTLD_NOW, ADRENOTOOLS_DRIVER_FILE_REDIRECT, nullptr,
93 hook_lib_dir.c_str(), nullptr, nullptr,
94 file_redirect_dir.c_str(), nullptr);
95 }
96
97 m_vulkan_library = std::make_shared<Common::DynamicLibrary>(handle);
98 }
99
73 bool IsRunning() const { 100 bool IsRunning() const {
74 std::scoped_lock lock(m_mutex); 101 std::scoped_lock lock(m_mutex);
75 return m_is_running; 102 return m_is_running;
@@ -94,7 +121,8 @@ public:
94 Config{}; 121 Config{};
95 122
96 // Create the render window. 123 // Create the render window.
97 m_window = std::make_unique<EmuWindow_Android>(&m_input_subsystem, m_native_window); 124 m_window = std::make_unique<EmuWindow_Android>(&m_input_subsystem, m_native_window,
125 m_vulkan_library);
98 126
99 // Initialize system. 127 // Initialize system.
100 m_system.SetShuttingDown(false); 128 m_system.SetShuttingDown(false);
@@ -242,6 +270,9 @@ private:
242 Core::SystemResultStatus m_load_result{Core::SystemResultStatus::ErrorNotInitialized}; 270 Core::SystemResultStatus m_load_result{Core::SystemResultStatus::ErrorNotInitialized};
243 bool m_is_running{}; 271 bool m_is_running{};
244 272
273 // GPU driver parameters
274 std::shared_ptr<Common::DynamicLibrary> m_vulkan_library;
275
245 // Synchronization 276 // Synchronization
246 std::condition_variable_any m_cv; 277 std::condition_variable_any m_cv;
247 mutable std::mutex m_perf_stats_mutex; 278 mutable std::mutex m_perf_stats_mutex;
@@ -327,6 +358,14 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_SetAppDirectory(JNIEnv* env,
327 Common::FS::SetAppDirectory(GetJString(env, j_directory)); 358 Common::FS::SetAppDirectory(GetJString(env, j_directory));
328} 359}
329 360
361void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_InitializeGpuDriver(
362 JNIEnv* env, [[maybe_unused]] jclass clazz, jstring hook_lib_dir, jstring custom_driver_dir,
363 jstring custom_driver_name, jstring file_redirect_dir) {
364 EmulationSession::GetInstance().InitializeGpuDriver(
365 GetJString(env, hook_lib_dir), GetJString(env, custom_driver_dir),
366 GetJString(env, custom_driver_name), GetJString(env, file_redirect_dir));
367}
368
330jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_ReloadKeys(JNIEnv* env, 369jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_ReloadKeys(JNIEnv* env,
331 [[maybe_unused]] jclass clazz) { 370 [[maybe_unused]] jclass clazz) {
332 Core::Crypto::KeyManager::Instance().ReloadKeys(); 371 Core::Crypto::KeyManager::Instance().ReloadKeys();
@@ -363,7 +402,8 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadButtonEvent([[maybe_unus
363 [[maybe_unused]] jint j_device, 402 [[maybe_unused]] jint j_device,
364 jint j_button, jint action) { 403 jint j_button, jint action) {
365 if (EmulationSession::GetInstance().IsRunning()) { 404 if (EmulationSession::GetInstance().IsRunning()) {
366 EmulationSession::GetInstance().Window().OnGamepadButtonEvent(j_device,j_button, action != 0); 405 EmulationSession::GetInstance().Window().OnGamepadButtonEvent(j_device, j_button,
406 action != 0);
367 } 407 }
368 return static_cast<jboolean>(true); 408 return static_cast<jboolean>(true);
369} 409}
@@ -373,31 +413,33 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadJoystickEvent([[maybe_un
373 jint j_device, jint stick_id, 413 jint j_device, jint stick_id,
374 jfloat x, jfloat y) { 414 jfloat x, jfloat y) {
375 if (EmulationSession::GetInstance().IsRunning()) { 415 if (EmulationSession::GetInstance().IsRunning()) {
376 EmulationSession::GetInstance().Window().OnGamepadJoystickEvent(j_device,stick_id, x, y); 416 EmulationSession::GetInstance().Window().OnGamepadJoystickEvent(j_device, stick_id, x, y);
377 } 417 }
378 return static_cast<jboolean>(true); 418 return static_cast<jboolean>(true);
379} 419}
380 420
381jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadMotionEvent([[maybe_unused]] JNIEnv* env, 421jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadMotionEvent(
382 [[maybe_unused]] jclass clazz, jint j_device,jlong delta_timestamp, jfloat gyro_x, jfloat gyro_y, 422 [[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint j_device,
383 jfloat gyro_z, jfloat accel_x, jfloat accel_y, jfloat accel_z){ 423 jlong delta_timestamp, jfloat gyro_x, jfloat gyro_y, jfloat gyro_z, jfloat accel_x,
424 jfloat accel_y, jfloat accel_z) {
384 if (EmulationSession::GetInstance().IsRunning()) { 425 if (EmulationSession::GetInstance().IsRunning()) {
385 EmulationSession::GetInstance().Window().OnGamepadMotionEvent(j_device,delta_timestamp, gyro_x, gyro_y,gyro_z,accel_x,accel_y,accel_z); 426 EmulationSession::GetInstance().Window().OnGamepadMotionEvent(
427 j_device, delta_timestamp, gyro_x, gyro_y, gyro_z, accel_x, accel_y, accel_z);
386 } 428 }
387 return static_cast<jboolean>(true); 429 return static_cast<jboolean>(true);
388} 430}
389 431
390void Java_org_yuzu_yuzu_1emu_NativeLibrary_onTouchPressed([[maybe_unused]] JNIEnv* env, 432void Java_org_yuzu_yuzu_1emu_NativeLibrary_onTouchPressed([[maybe_unused]] JNIEnv* env,
391 [[maybe_unused]] jclass clazz, jint id, jfloat x, 433 [[maybe_unused]] jclass clazz, jint id,
392 jfloat y) { 434 jfloat x, jfloat y) {
393 if (EmulationSession::GetInstance().IsRunning()) { 435 if (EmulationSession::GetInstance().IsRunning()) {
394 EmulationSession::GetInstance().Window().OnTouchPressed(id, x, y); 436 EmulationSession::GetInstance().Window().OnTouchPressed(id, x, y);
395 } 437 }
396} 438}
397 439
398void Java_org_yuzu_yuzu_1emu_NativeLibrary_onTouchMoved([[maybe_unused]] JNIEnv* env, 440void Java_org_yuzu_yuzu_1emu_NativeLibrary_onTouchMoved([[maybe_unused]] JNIEnv* env,
399 [[maybe_unused]] jclass clazz, jint id, jfloat x, 441 [[maybe_unused]] jclass clazz, jint id,
400 jfloat y) { 442 jfloat x, jfloat y) {
401 if (EmulationSession::GetInstance().IsRunning()) { 443 if (EmulationSession::GetInstance().IsRunning()) {
402 EmulationSession::GetInstance().Window().OnTouchMoved(id, x, y); 444 EmulationSession::GetInstance().Window().OnTouchMoved(id, x, y);
403 } 445 }
diff --git a/src/android/app/src/main/jni/native.h b/src/android/app/src/main/jni/native.h
index bbc783aa8..f799560e4 100644
--- a/src/android/app/src/main/jni/native.h
+++ b/src/android/app/src/main/jni/native.h
@@ -71,6 +71,11 @@ JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_SetAppDirectory(JNI
71 jclass clazz, 71 jclass clazz,
72 jstring j_directory); 72 jstring j_directory);
73 73
74JNIEXPORT void JNICALL
75Java_org_yuzu_yuzu_1emu_NativeLibrary_Java_org_yuzu_yuzu_1emu_NativeLibrary_InitializeGpuDriver(
76 JNIEnv* env, jclass clazz, jstring hook_lib_dir, jstring custom_driver_dir,
77 jstring custom_driver_name, jstring file_redirect_dir);
78
74JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_ReloadKeys(JNIEnv* env, 79JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_ReloadKeys(JNIEnv* env,
75 jclass clazz); 80 jclass clazz);
76 81