- Added new strings for installation reset prompts and messages in strings.xml.

- Created InstallReset.kt to handle the removal of game files, built games, and mod packs while preserving user data.
- Implemented unit tests for InstallReset to ensure correct functionality and file handling.
- Updated RetroRewindPackTest to include new test cases for update and deletion order.
- Enhanced Vulkan interop and OpenXR integration to support new thread scheduling hints for Android.
- Improved error handling and logging for GPU submission failures in Vulkan backend.
This commit is contained in:
iChris4 committed 2026-09-19 00:08:58 +02:00
1 parent d4a3f0b350
commit 7f2113dbc5
22 files changed
+583 -94

No files matched your search

+3
View File
@@ -261,6 +261,9 @@ void aurora_store_pipeline_caches();
// Allows the pipeline compiler to store the caches itself, rate-limited, whenever a first-use
// burst completes. Off by default; enable it while a stall is acceptable, such as in menus.
void aurora_set_pipeline_cache_idle_store(bool allowed);
// The Linux thread id of Aurora's frame worker, or 0 before it runs and where there is none.
// Android's OpenXR runtime takes it as a scheduling hint (XR_KHR_android_thread_settings).
uint32_t aurora_get_frame_worker_native_thread_id(void);
// Absolute schedule for the next sealed frame, on steady_clock: baseNanos anchors the group and
// intervalNanos is the period, so slot k of N+1 fires at base + k*interval/(N+1). Zeros clear it.
void aurora_set_present_schedule(uint64_t baseNanos, uint64_t intervalNanos);
+7 -4
View File
@@ -78,11 +78,14 @@ typedef struct {
/**
* Fired when Aurora either finishes or abandons the stereo sink. `success`
* guarantees that the copies were submitted and that every release entry is
* valid. The callback runs on Aurora's frame worker while its queue-submit
* mutex is held: it may record and submit work on the OpenXR side's own Vulkan
* queue, but must not wait for the GPU or re-enter Aurora.
* valid. Otherwise `gpuWorkQueued` says whether the copies may have reached
* Dawn's queue before the failure (the shared buffers may then be written with
* no fence to wait on) or nothing was recorded at all. The callback runs on
* Aurora's frame worker while its queue-submit mutex is held: it may record and
* submit work on the OpenXR side's own Vulkan queue, but must not wait for the
* GPU or re-enter Aurora.
*/
typedef void (*AuroraVulkanStereoSubmittedCallback)(uint64_t frameToken, bool success,
typedef void (*AuroraVulkanStereoSubmittedCallback)(uint64_t frameToken, bool success, bool gpuWorkQueued,
const AuroraVulkanStereoRelease* releases,
uint32_t releaseCount, void* userdata);
+11
View File
@@ -27,6 +27,9 @@
#ifdef AURORA_ENABLE_GX
#include "gfx/pipeline_cache.hpp"
#endif
#if defined(__ANDROID__)
#include <unistd.h>
#endif
#include "system_info.hpp"
#include "tracy/Tracy.hpp"
@@ -294,6 +297,8 @@ struct FrameWorkerState {
};
FrameWorkerState g_frameWorker;
// The worker's Linux thread id, published for the host's scheduling hints (Android).
std::atomic<uint32_t> g_frameWorkerNativeThreadId{0};
bool frame_worker_requested() noexcept {
#ifdef AURORA_ENABLE_GX
@@ -343,6 +348,9 @@ void frame_worker_main() noexcept {
std::lock_guard lock(g_frameWorker.mutex);
g_frameWorker.threadId = std::this_thread::get_id();
}
#if defined(__ANDROID__)
g_frameWorkerNativeThreadId.store(static_cast<uint32_t>(gettid()), std::memory_order_release);
#endif
#ifdef AURORA_ENABLE_GX
// Owned by the worker for its whole lifetime so the sealed pass vector and
@@ -2524,6 +2532,9 @@ void aurora_set_pipeline_cache_idle_store(bool allowed) {
(void)allowed;
#endif
}
uint32_t aurora_get_frame_worker_native_thread_id(void) {
return aurora::g_frameWorkerNativeThreadId.load(std::memory_order_acquire);
}
void aurora_set_present_schedule(uint64_t baseNanos, uint64_t intervalNanos) {
aurora::g_presentScheduleBaseNanos.store(baseNanos, std::memory_order_release);
aurora::g_presentScheduleIntervalNanos.store(intervalNanos, std::memory_order_release);
+10 -8
View File
@@ -192,7 +192,8 @@ public:
m_encoded = true;
return true;
}
PublishAndClearFrameLocked(frame.frameToken, false);
// Nothing was recorded, so the shared buffers are untouched.
PublishAndClearFrameLocked(frame.frameToken, false, false);
return false;
}
@@ -203,7 +204,7 @@ public:
}
std::array<AuroraVulkanStereoRelease, AURORA_VULKAN_STEREO_MAX_TARGETS> releases{};
const bool success = EndAccessLocked(releases);
NotifyLocked(frame.frameToken, success, releases);
NotifyLocked(frame.frameToken, success, true, releases);
ClearFrameLocked();
}
@@ -213,14 +214,15 @@ public:
return;
}
const uint64_t token = m_frameToken;
const bool encoded = m_encoded;
std::array<AuroraVulkanStereoRelease, AURORA_VULKAN_STEREO_MAX_TARGETS> releases{};
if (m_encoded) {
if (encoded) {
EndAccessLocked(releases);
for (auto& release : releases) {
close_fd(release.releaseFenceFd);
}
}
PublishAndClearFrameLocked(token, false);
PublishAndClearFrameLocked(token, false, encoded);
}
bool CancelBeforeEncode(uint64_t token) noexcept {
@@ -484,20 +486,20 @@ private:
m_encoded = false;
}
void PublishAndClearFrameLocked(uint64_t token, bool success) noexcept {
void PublishAndClearFrameLocked(uint64_t token, bool success, bool gpuWorkQueued) noexcept {
std::array<AuroraVulkanStereoRelease, AURORA_VULKAN_STEREO_MAX_TARGETS> releases{};
for (auto& release : releases) {
release = {.releaseFenceFd = -1, .releasedImageLayout = VK_IMAGE_LAYOUT_UNDEFINED};
}
NotifyLocked(token, success, releases);
NotifyLocked(token, success, gpuWorkQueued, releases);
ClearFrameLocked();
}
void NotifyLocked(uint64_t token, bool success,
void NotifyLocked(uint64_t token, bool success, bool gpuWorkQueued,
const std::array<AuroraVulkanStereoRelease, AURORA_VULKAN_STEREO_MAX_TARGETS>&
releases) noexcept {
if (m_callback != nullptr) {
m_callback(token, success, releases.data(), m_targetCount, m_userdata);
m_callback(token, success, gpuWorkQueued, releases.data(), m_targetCount, m_userdata);
} else {
for (auto release : releases) {
close_fd(release.releaseFenceFd);