diff --git a/src/android/app/src/main/java/io/github/lime3ds/android/activities/EmulationActivity.kt b/src/android/app/src/main/java/io/github/lime3ds/android/activities/EmulationActivity.kt index ffb4b7f6e..30ccc552d 100644 --- a/src/android/app/src/main/java/io/github/lime3ds/android/activities/EmulationActivity.kt +++ b/src/android/app/src/main/java/io/github/lime3ds/android/activities/EmulationActivity.kt @@ -85,10 +85,6 @@ class EmulationActivity : AppCompatActivity() { windowManager.defaultDisplay.rotation ) - // Start a foreground service to prevent the app from getting killed in the background - foregroundService = Intent(this, ForegroundService::class.java) - startForegroundService(foregroundService) - EmulationLifecycleUtil.addShutdownHook(hook = { this.finish() }) } @@ -112,7 +108,6 @@ class EmulationActivity : AppCompatActivity() { override fun onDestroy() { EmulationLifecycleUtil.clear() - stopForegroundService(this) super.onDestroy() } 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 436442acd..e847cdb2b 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 @@ -27,7 +27,11 @@ static void UpdateLandscapeScreenLayout() { IDCache::GetNativeLibraryClass(), IDCache::GetLandscapeScreenLayout())); } -void EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) { +bool EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) { + if (render_window == surface) { + return false; + } + render_window = surface; window_info.type = Frontend::WindowSystemType::Android; @@ -35,6 +39,8 @@ void EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) { StopPresenting(); OnFramebufferSizeChanged(); + + return true; } bool EmuWindow_Android::OnTouchEvent(int x, int y, bool pressed) { 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 64ead5c7f..4266fd1bb 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 @@ -17,7 +17,7 @@ public: ~EmuWindow_Android(); /// Called by the onSurfaceChanges() method to change the surface - void OnSurfaceChanged(ANativeWindow* surface); + bool OnSurfaceChanged(ANativeWindow* surface); /// Handles touch event that occur.(Touched or released) bool OnTouchEvent(int x, int y, bool pressed); diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index afba7be6a..4010a1b81 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp @@ -289,12 +289,13 @@ void Java_io_github_lime3ds_android_NativeLibrary_surfaceChanged(JNIEnv* env, jobject surf) { s_surf = ANativeWindow_fromSurface(env, surf); + bool notify = false; if (window) { - window->OnSurfaceChanged(s_surf); + notify = window->OnSurfaceChanged(s_surf); } auto& system = Core::System::GetInstance(); - if (system.IsPoweredOn()) { + if (notify && system.IsPoweredOn()) { system.GPU().Renderer().NotifySurfaceChanged(); } diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 9668aed69..05468777e 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -82,7 +82,7 @@ constexpr std::array SHADOW_BINDINGS = {{ PipelineCache::PipelineCache(const Instance& instance_, Scheduler& scheduler_, RenderpassCache& renderpass_cache_, DescriptorPool& pool_) : instance{instance_}, scheduler{scheduler_}, renderpass_cache{renderpass_cache_}, pool{pool_}, - num_worker_threads{std::max(std::thread::hardware_concurrency(), 2U)}, + num_worker_threads{std::max(std::thread::hardware_concurrency() >> 1, 2U)}, workers{num_worker_threads, "Pipeline workers"}, descriptor_set_providers{DescriptorSetProvider{instance, pool, BUFFER_BINDINGS}, DescriptorSetProvider{instance, pool, TEXTURE_BINDINGS}, diff --git a/src/video_core/renderer_vulkan/vk_present_window.cpp b/src/video_core/renderer_vulkan/vk_present_window.cpp index 273b20e8e..5f096ad4b 100644 --- a/src/video_core/renderer_vulkan/vk_present_window.cpp +++ b/src/video_core/renderer_vulkan/vk_present_window.cpp @@ -473,7 +473,7 @@ void PresentWindow::CopyToSwapchain(Frame* frame) { .pSignalSemaphores = &present_ready, }; - std::scoped_lock submit_lock{scheduler.submit_mutex}; + std::scoped_lock submit_lock{scheduler.submit_mutex, recreate_surface_mutex}; try { graphics_queue.submit(submit_info, frame->present_done); diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp index 5e725be1e..4fe70bfe0 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.cpp +++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp @@ -78,9 +78,13 @@ void Swapchain::Create(u32 width_, u32 height_, vk::SurfaceKHR surface_) { } bool Swapchain::AcquireNextImage() { + if (needs_recreation) { + return false; + } + MICROPROFILE_SCOPE(Vulkan_Acquire); - vk::Device device = instance.GetDevice(); - vk::Result result = + const vk::Device device = instance.GetDevice(); + const vk::Result result = device.acquireNextImageKHR(swapchain, std::numeric_limits::max(), image_acquired[frame_index], VK_NULL_HANDLE, &image_index); @@ -102,10 +106,6 @@ bool Swapchain::AcquireNextImage() { } void Swapchain::Present() { - if (needs_recreation) { - return; - } - const vk::PresentInfoKHR present_info = { .waitSemaphoreCount = 1, .pWaitSemaphores = &present_ready[image_index], @@ -119,6 +119,10 @@ void Swapchain::Present() { [[maybe_unused]] vk::Result result = instance.GetPresentQueue().presentKHR(present_info); } catch (vk::OutOfDateKHRError&) { needs_recreation = true; + return; + } catch (vk::SurfaceLostKHRError&) { + needs_recreation = true; + return; } catch (const vk::SystemError& err) { LOG_CRITICAL(Render_Vulkan, "Swapchain presentation failed {}", err.what()); UNREACHABLE();