mirror of
https://github.com/ARMSX2/ARMSX3.git
synced 2026-08-24 16:58:52 -07:00
Stop the save-data list aborting where there is no media backend
overlay_audio.cpp already accounts for a platform with no video source; the same ensure() was left in overlay_video.cpp. Android's make_video_source returns nullptr, and overlay_save_dialog builds a video_view for EVERY entry on all three of its paths, so opening a save list aborted as soon as there was one save to draw. It presents as the save menu never opening -- reported against Ratchet & Clank: Tools of Destruction and Devil May Cry 4, and against Web of Shadows, which stalls only once a save exists to be listed. Bundling the overlay icons was necessary but not sufficient: the dialog still could not survive drawing. The still image is what an entry needs; the animated ICON1.PAM is the part no backend here can supply. Also dumps SPU thread pc and block hash alongside the PPU dump when frames stop, which is what named the SPURS kernels as idle rather than spinning in guest code.
This commit is contained in:
@@ -43,7 +43,25 @@ namespace rsx
|
||||
{
|
||||
if (video_path.empty()) return;
|
||||
|
||||
m_video_source = ensure(Emu.GetCallbacks().make_video_source());
|
||||
// Same platform reality overlay_audio.cpp already accounts for: Android has no media
|
||||
// backend, so make_video_source returns nullptr and ensure() aborted the process.
|
||||
//
|
||||
// This one is reached from the SAVE DATA LIST -- overlay_save_dialog.cpp builds a
|
||||
// video_view for every entry, on all three paths -- so opening a load menu killed the
|
||||
// emulator as soon as there was one save to draw. It presents as "the save menu never
|
||||
// opens": reported against Ratchet & Clank: Tools of Destruction, Devil May Cry 4, and
|
||||
// Web of Shadows, which stalls only AFTER its first save exists to be listed.
|
||||
//
|
||||
// The still image is what the entry actually needs; the animated ICON1.PAM is the part
|
||||
// no backend can supply.
|
||||
m_video_source = Emu.GetCallbacks().make_video_source();
|
||||
|
||||
if (!m_video_source)
|
||||
{
|
||||
rsx_log.notice("Overlay video unavailable: no video source on this platform");
|
||||
return;
|
||||
}
|
||||
|
||||
m_video_source->set_update_callback([this]()
|
||||
{
|
||||
if (m_video_active)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/Cell/PPUThread.h"
|
||||
#include "Emu/Cell/SPUThread.h"
|
||||
#include "Emu/Cell/timers.hpp"
|
||||
#include "Emu/Cell/lv2/sys_event.h"
|
||||
#include "Emu/Cell/lv2/sys_time.h"
|
||||
@@ -1380,6 +1381,26 @@ namespace rsx
|
||||
}, idm::unlocked);
|
||||
|
||||
rsx_log.error("Guest PPU threads while no frame has completed:%s", out);
|
||||
|
||||
// The SPU half. A hang where every PPU is asleep and the SPUs are burning user time is
|
||||
// the SPUs spinning in guest code, and nothing said WHICH code: /proc gives a tick count,
|
||||
// a CPU profile gives a JIT address that resolves to nothing. The PC plus the block hash
|
||||
// name the guest block, which is the only thing that identifies the loop.
|
||||
std::string spus;
|
||||
|
||||
idm::select<named_thread<spu_thread>>([&spus](u32 /*id*/, spu_thread& spu)
|
||||
{
|
||||
const auto func = spu.current_func;
|
||||
|
||||
fmt::append(spus, "\n SPU 0x%07x '%s': state=%s pc=0x%05x block=0x%016llx func='%s'",
|
||||
spu.lv2_id, *spu.spu_tname.load(), spu.state.load(), spu.pc,
|
||||
static_cast<u64>(spu.block_hash), func ? func : "");
|
||||
}, idm::unlocked);
|
||||
|
||||
if (!spus.empty())
|
||||
{
|
||||
rsx_log.error("Guest SPU threads at the same moment:%s", spus);
|
||||
}
|
||||
}
|
||||
|
||||
void thread::do_local_task(FIFO::state state)
|
||||
|
||||
Reference in New Issue
Block a user