cellGem: Fix deadlock when cellGemUpdateStart is called before cellCamera delivers images

This commit is contained in:
Megamouse 2026-03-04 08:37:26 +01:00
parent 86b2773c28
commit 3750fb2c1f

View File

@ -1616,6 +1616,7 @@ public:
} }
m_tracker.set_image_data(m_camera_info.buffer.get_ptr(), m_camera_info.bytesize, m_camera_info.width, m_camera_info.height, m_camera_info.format); m_tracker.set_image_data(m_camera_info.buffer.get_ptr(), m_camera_info.bytesize, m_camera_info.width, m_camera_info.height, m_camera_info.format);
m_framenumber++; // using framenumber instead of timestamp since the timestamp could be identical
return true; return true;
} }
@ -1648,6 +1649,7 @@ public:
} }
auto& gem = g_fxo->get<gem_config>(); auto& gem = g_fxo->get<gem_config>();
u64 last_framenumber = 0;
while (thread_ctrl::state() != thread_state::aborting) while (thread_ctrl::state() != thread_state::aborting)
{ {
@ -1663,6 +1665,13 @@ public:
} }
} }
if (std::exchange(last_framenumber, m_framenumber.load()) == last_framenumber)
{
cellGem.warning("Tracker woke up without new frame. Skipping processing (framenumber=%d)", last_framenumber);
tracker_done();
continue;
}
m_busy.release(true); m_busy.release(true);
// Update PS Move LED colors // Update PS Move LED colors
@ -1754,6 +1763,7 @@ public:
private: private:
atomic_t<u32> m_wake_up_tracker = 0; atomic_t<u32> m_wake_up_tracker = 0;
atomic_t<u32> m_tracker_done = 0; atomic_t<u32> m_tracker_done = 0;
atomic_t<u64> m_framenumber = 0;
atomic_t<bool> m_busy = false; atomic_t<bool> m_busy = false;
ps_move_tracker<false> m_tracker{}; ps_move_tracker<false> m_tracker{};
CellCameraInfoEx m_camera_info{}; CellCameraInfoEx m_camera_info{};
@ -3876,13 +3886,15 @@ error_code cellGemUpdateStart(vm::cptr<void> camera_frame, u64 timestamp)
gem.camera_frame = camera_frame.addr(); gem.camera_frame = camera_frame.addr();
if (!tracker.set_image(gem.camera_frame)) const bool image_set = tracker.set_image(gem.camera_frame);
tracker.wake_up_tracker();
if (!image_set)
{ {
return not_an_error(CELL_GEM_NO_VIDEO); return not_an_error(CELL_GEM_NO_VIDEO);
} }
tracker.wake_up_tracker();
return CELL_OK; return CELL_OK;
} }