diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt | 52 | ||||
-rw-r--r-- | src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameIconUtils.kt | 7 | ||||
-rw-r--r-- | src/audio_core/sink/cubeb_sink.cpp | 2 | ||||
-rw-r--r-- | src/audio_core/sink/sdl2_sink.cpp | 2 | ||||
-rw-r--r-- | src/audio_core/sink/sink_stream.cpp | 12 | ||||
-rw-r--r-- | src/audio_core/sink/sink_stream.h | 6 | ||||
-rw-r--r-- | src/core/arm/arm_interface.cpp | 16 | ||||
-rw-r--r-- | src/core/core_timing.cpp | 2 | ||||
-rw-r--r-- | src/core/core_timing.h | 2 |
9 files changed, 64 insertions, 37 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt index 0c82cdba8..2ef638559 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt @@ -22,12 +22,16 @@ import androidx.core.graphics.drawable.toBitmap import androidx.core.graphics.drawable.toDrawable import androidx.documentfile.provider.DocumentFile import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope import androidx.navigation.findNavController import androidx.preference.PreferenceManager import androidx.recyclerview.widget.AsyncDifferConfig import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import org.yuzu.yuzu_emu.HomeNavigationDirections import org.yuzu.yuzu_emu.R import org.yuzu.yuzu_emu.YuzuApplication @@ -92,28 +96,34 @@ class GameAdapter(private val activity: AppCompatActivity) : data = Uri.parse(holder.game.path) } - val layerDrawable = ResourcesCompat.getDrawable( - YuzuApplication.appContext.resources, - R.drawable.shortcut, - null - ) as LayerDrawable - layerDrawable.setDrawableByLayerId( - R.id.shortcut_foreground, - GameIconUtils.getGameIcon(holder.game).toDrawable(YuzuApplication.appContext.resources) - ) - val inset = YuzuApplication.appContext.resources - .getDimensionPixelSize(R.dimen.icon_inset) - layerDrawable.setLayerInset(1, inset, inset, inset, inset) - val shortcut = ShortcutInfoCompat.Builder(YuzuApplication.appContext, holder.game.path) - .setShortLabel(holder.game.title) - .setIcon( - IconCompat.createWithAdaptiveBitmap( - layerDrawable.toBitmap(config = Bitmap.Config.ARGB_8888) + activity.lifecycleScope.launch { + withContext(Dispatchers.IO) { + val layerDrawable = ResourcesCompat.getDrawable( + YuzuApplication.appContext.resources, + R.drawable.shortcut, + null + ) as LayerDrawable + layerDrawable.setDrawableByLayerId( + R.id.shortcut_foreground, + GameIconUtils.getGameIcon(activity, holder.game) + .toDrawable(YuzuApplication.appContext.resources) ) - ) - .setIntent(openIntent) - .build() - ShortcutManagerCompat.pushDynamicShortcut(YuzuApplication.appContext, shortcut) + val inset = YuzuApplication.appContext.resources + .getDimensionPixelSize(R.dimen.icon_inset) + layerDrawable.setLayerInset(1, inset, inset, inset, inset) + val shortcut = + ShortcutInfoCompat.Builder(YuzuApplication.appContext, holder.game.path) + .setShortLabel(holder.game.title) + .setIcon( + IconCompat.createWithAdaptiveBitmap( + layerDrawable.toBitmap(config = Bitmap.Config.ARGB_8888) + ) + ) + .setIntent(openIntent) + .build() + ShortcutManagerCompat.pushDynamicShortcut(YuzuApplication.appContext, shortcut) + } + } val action = HomeNavigationDirections.actionGlobalEmulationActivity(holder.game) view.findNavController().navigate(action) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameIconUtils.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameIconUtils.kt index 654d62f52..2e9b0beb8 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameIconUtils.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameIconUtils.kt @@ -8,9 +8,9 @@ import android.graphics.BitmapFactory import android.widget.ImageView import androidx.core.graphics.drawable.toBitmap import androidx.core.graphics.drawable.toDrawable +import androidx.lifecycle.LifecycleOwner import coil.ImageLoader import coil.decode.DataSource -import coil.executeBlocking import coil.fetch.DrawableResult import coil.fetch.FetchResult import coil.fetch.Fetcher @@ -76,12 +76,13 @@ object GameIconUtils { imageLoader.enqueue(request) } - fun getGameIcon(game: Game): Bitmap { + suspend fun getGameIcon(lifecycleOwner: LifecycleOwner, game: Game): Bitmap { val request = ImageRequest.Builder(YuzuApplication.appContext) .data(game) + .lifecycle(lifecycleOwner) .error(R.drawable.default_icon) .build() - return imageLoader.executeBlocking(request) + return imageLoader.execute(request) .drawable!!.toBitmap(config = Bitmap.Config.ARGB_8888) } } diff --git a/src/audio_core/sink/cubeb_sink.cpp b/src/audio_core/sink/cubeb_sink.cpp index bbb598bc5..51a23fe15 100644 --- a/src/audio_core/sink/cubeb_sink.cpp +++ b/src/audio_core/sink/cubeb_sink.cpp @@ -146,7 +146,7 @@ public: return; } - paused = true; + SignalPause(); if (cubeb_stream_stop(stream_backend) != CUBEB_OK) { LOG_CRITICAL(Audio_Sink, "Error stopping cubeb stream"); } diff --git a/src/audio_core/sink/sdl2_sink.cpp b/src/audio_core/sink/sdl2_sink.cpp index 7b89151de..96e0efce2 100644 --- a/src/audio_core/sink/sdl2_sink.cpp +++ b/src/audio_core/sink/sdl2_sink.cpp @@ -111,7 +111,7 @@ public: if (device == 0 || paused) { return; } - paused = true; + SignalPause(); SDL_PauseAudioDevice(device, 1); } diff --git a/src/audio_core/sink/sink_stream.cpp b/src/audio_core/sink/sink_stream.cpp index d66d04fae..2a09db599 100644 --- a/src/audio_core/sink/sink_stream.cpp +++ b/src/audio_core/sink/sink_stream.cpp @@ -282,11 +282,19 @@ u64 SinkStream::GetExpectedPlayedSampleCount() { void SinkStream::WaitFreeSpace(std::stop_token stop_token) { std::unique_lock lk{release_mutex}; release_cv.wait_for(lk, std::chrono::milliseconds(5), - [this]() { return queued_buffers < max_queue_size; }); + [this]() { return paused || queued_buffers < max_queue_size; }); if (queued_buffers > max_queue_size + 3) { Common::CondvarWait(release_cv, lk, stop_token, - [this] { return queued_buffers < max_queue_size; }); + [this] { return paused || queued_buffers < max_queue_size; }); } } +void SinkStream::SignalPause() { + { + std::scoped_lock lk{release_mutex}; + paused = true; + } + release_cv.notify_one(); +} + } // namespace AudioCore::Sink diff --git a/src/audio_core/sink/sink_stream.h b/src/audio_core/sink/sink_stream.h index 6a4996ca3..f2ccd19b8 100644 --- a/src/audio_core/sink/sink_stream.h +++ b/src/audio_core/sink/sink_stream.h @@ -214,6 +214,12 @@ public: void WaitFreeSpace(std::stop_token stop_token); protected: + /** + * Unblocks the ADSP if the stream is paused. + */ + void SignalPause(); + +protected: /// Core system Core::System& system; /// Type of this stream diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp index 5e27dde58..558fba5bd 100644 --- a/src/core/arm/arm_interface.cpp +++ b/src/core/arm/arm_interface.cpp @@ -153,6 +153,14 @@ void ARM_Interface::Run() { Kernel::KThread* current_thread{Kernel::GetCurrentThreadPointer(system.Kernel())}; HaltReason hr{}; + // If the thread is scheduled for termination, exit the thread. + if (current_thread->HasDpc()) { + if (current_thread->IsTerminationRequested()) { + current_thread->Exit(); + UNREACHABLE(); + } + } + // Notify the debugger and go to sleep if a step was performed // and this thread has been scheduled again. if (current_thread->GetStepState() == StepState::StepPerformed) { @@ -174,14 +182,6 @@ void ARM_Interface::Run() { } system.ExitCPUProfile(); - // If the thread is scheduled for termination, exit the thread. - if (current_thread->HasDpc()) { - if (current_thread->IsTerminationRequested()) { - current_thread->Exit(); - UNREACHABLE(); - } - } - // Notify the debugger and go to sleep if a breakpoint was hit, // or if the thread is unable to continue for any reason. if (True(hr & HaltReason::InstructionBreakpoint) || True(hr & HaltReason::PrefetchAbort)) { diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index e671b270f..d6b5abc68 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp @@ -76,6 +76,7 @@ void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) { } void CoreTiming::ClearPendingEvents() { + std::scoped_lock lock{basic_lock}; event_queue.clear(); } @@ -113,6 +114,7 @@ bool CoreTiming::IsRunning() const { } bool CoreTiming::HasPendingEvents() const { + std::scoped_lock lock{basic_lock}; return !(wait_set && event_queue.empty()); } diff --git a/src/core/core_timing.h b/src/core/core_timing.h index 26a8b93a7..21548f0a9 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h @@ -161,7 +161,7 @@ private: std::shared_ptr<EventType> ev_lost; Common::Event event{}; Common::Event pause_event{}; - std::mutex basic_lock; + mutable std::mutex basic_lock; std::mutex advance_lock; std::unique_ptr<std::jthread> timer_thread; std::atomic<bool> paused{}; |