mirror of
https://github.com/RPCS3/rpcs3
synced 2024-11-02 11:45:30 +00:00
cellCamera: Fixes
- Fix regression from #4676 - Refactoring of event queue management stuff - Some accuracy fixes
This commit is contained in:
parent
69af607491
commit
1625f4bcc9
2 changed files with 111 additions and 114 deletions
|
@ -245,70 +245,6 @@ static s32 check_camera_info(const CellCameraInfoEx& info)
|
|||
break;
|
||||
}
|
||||
return CELL_OK;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Sets up notify event queue supplied and immediately sends an ATTACH event to it
|
||||
* \param key Event queue key to add
|
||||
* \param source Event source port
|
||||
* \param flag Event flag (CELL_CAMERA_EFLAG_*)
|
||||
* \return True on success, false if camera_thead hasn't been initialized
|
||||
*/
|
||||
bool add_queue_and_send_attach(u64 key, u64 source, u64 flag)
|
||||
{
|
||||
const auto g_camera = fxm::get<camera_thread>();
|
||||
|
||||
if (!g_camera)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
semaphore_lock lock(g_camera->mutex);
|
||||
{
|
||||
semaphore_lock lock_data_map(g_camera->mutex_notify_data_map);
|
||||
|
||||
g_camera->notify_data_map[key] = { source, flag };
|
||||
}
|
||||
|
||||
// send ATTACH event - HACKY
|
||||
g_camera->send_attach_state(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Unsets/removes event queue specified
|
||||
* \param key Event queue key to remove
|
||||
* \return True on success, false if camera_thead hasn't been initialized
|
||||
*/
|
||||
bool remove_queue(u64 key)
|
||||
{
|
||||
const auto g_camera = fxm::get<camera_thread>();
|
||||
|
||||
if (!g_camera)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
semaphore_lock lock(g_camera->mutex);
|
||||
{
|
||||
semaphore_lock lock_data_map(g_camera->mutex_notify_data_map);
|
||||
|
||||
g_camera->notify_data_map.erase(key);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sets read mode attribute (used for deciding how image data is passed to games)
|
||||
* Also sends it to the camera thread
|
||||
* NOTE: thread-safe (uses camera_thread::mutex)
|
||||
* \param dev_num Device number (always 0)
|
||||
* \param read_mode is CELL_CAMERA_READ_DIRECT or else CELL_CAMERA_READ_FUNCCALL
|
||||
* \return CELL error code or CELL_OK
|
||||
*/
|
||||
s32 set_and_send_read_mode(s32 dev_num, const s32 read_mode)
|
||||
{
|
||||
return cellCameraSetAttribute(dev_num, CELL_CAMERA_READMODE, read_mode, 0);
|
||||
}
|
||||
|
||||
std::pair<u32, u32> get_video_resolution(const CellCameraInfoEx& info)
|
||||
|
@ -403,6 +339,11 @@ s32 cellCameraInit()
|
|||
|
||||
// TODO: Some other default attributes? Need to check the actual behaviour on a real PS3.
|
||||
|
||||
if (g_cfg.io.camera == camera_handler::fake)
|
||||
{
|
||||
g_camera->is_attached = true;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
@ -452,31 +393,26 @@ s32 cellCameraOpenEx(s32 dev_num, vm::ptr<CellCameraInfoEx> info)
|
|||
return CELL_CAMERA_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
const auto g_camera = fxm::get<camera_thread>();
|
||||
|
||||
if (!g_camera)
|
||||
{
|
||||
return CELL_CAMERA_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
s32 status = set_and_send_read_mode(dev_num, info->read_mode);
|
||||
if (status != CELL_OK)
|
||||
s32 status;
|
||||
if ((status = cellCameraSetAttribute(dev_num, CELL_CAMERA_READMODE, info->read_mode, 0)) != CELL_OK)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
status = cellCameraSetAttribute(dev_num, CELL_CAMERA_GAMEPID, 0, 0); // yup, that's what libGem does
|
||||
if (status != CELL_OK)
|
||||
if (info->read_mode == CELL_CAMERA_READ_DIRECT)
|
||||
{
|
||||
if ((status = cellCameraSetAttribute(dev_num, CELL_CAMERA_GAMEPID, status, 0)) != CELL_OK)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
if (!check_dev_num)
|
||||
{
|
||||
return CELL_CAMERA_ERROR_PARAM;
|
||||
}
|
||||
|
||||
semaphore_lock lock(g_camera->mutex);
|
||||
const auto g_camera = fxm::get<camera_thread>();
|
||||
// we know g_camera is valid here (cellCameraSetAttribute above checks for it)
|
||||
|
||||
if (g_camera->is_open)
|
||||
{
|
||||
|
@ -493,6 +429,8 @@ s32 cellCameraOpenEx(s32 dev_num, vm::ptr<CellCameraInfoEx> info)
|
|||
|
||||
const auto vbuf_size = get_video_buffer_size(*info);
|
||||
|
||||
semaphore_lock lock(g_camera->mutex);
|
||||
|
||||
if (info->read_mode == CELL_CAMERA_READ_FUNCCALL && !info->buffer)
|
||||
{
|
||||
info->buffer = vm::cast(vm::alloc(vbuf_size, vm::memory_location_t::main));
|
||||
|
@ -635,6 +573,8 @@ s32 cellCameraIsAttached(s32 dev_num)
|
|||
|
||||
bool is_attached = g_camera->is_attached;
|
||||
|
||||
if (g_cfg.io.camera == camera_handler::fake)
|
||||
{
|
||||
// "attach" camera here
|
||||
// normally should be attached immediately after event queue is registered, but just to be sure
|
||||
if (!is_attached)
|
||||
|
@ -642,6 +582,7 @@ s32 cellCameraIsAttached(s32 dev_num)
|
|||
g_camera->send_attach_state(true);
|
||||
is_attached = g_camera->is_attached;
|
||||
}
|
||||
}
|
||||
|
||||
return is_attached;
|
||||
}
|
||||
|
@ -710,6 +651,12 @@ s32 cellCameraGetAttribute(s32 dev_num, s32 attrib, vm::ptr<u32> arg1, vm::ptr<u
|
|||
return CELL_CAMERA_ERROR_PARAM;
|
||||
}
|
||||
|
||||
// actually compares <= 0x63 which is equivalent
|
||||
if (attrib < CELL_CAMERA_FORMATCAP && !g_camera->is_open)
|
||||
{
|
||||
return CELL_CAMERA_ERROR_NOT_OPEN;
|
||||
}
|
||||
|
||||
semaphore_lock lock(g_camera->mutex);
|
||||
|
||||
if (!g_camera->is_attached)
|
||||
|
@ -751,24 +698,13 @@ s32 cellCameraSetAttribute(s32 dev_num, s32 attrib, u32 arg1, u32 arg2)
|
|||
return CELL_CAMERA_ERROR_PARAM;
|
||||
}
|
||||
|
||||
semaphore_lock lock(g_camera->mutex);
|
||||
|
||||
if (!g_camera->is_open)
|
||||
// actually compares <= 0x63 which is equivalent
|
||||
if (attrib < CELL_CAMERA_FORMATCAP && !g_camera->is_open)
|
||||
{
|
||||
return CELL_CAMERA_ERROR_NOT_OPEN;
|
||||
}
|
||||
|
||||
if (attrib == CELL_CAMERA_READMODE)
|
||||
{
|
||||
if (arg1 != CELL_CAMERA_READ_FUNCCALL && arg1 != CELL_CAMERA_READ_DIRECT)
|
||||
{
|
||||
LOG_WARNING(HLE, "Unknown read mode set: %d", arg1);
|
||||
arg1 = CELL_CAMERA_READ_FUNCCALL;
|
||||
}
|
||||
g_camera->read_mode.exchange(arg1);
|
||||
}
|
||||
|
||||
g_camera->attr[attrib] = { arg1, arg2 };
|
||||
g_camera->set_attr(attrib, arg1, arg2);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -817,8 +753,8 @@ s32 cellCameraGetBufferSize(s32 dev_num, vm::ptr<CellCameraInfoEx> info)
|
|||
return CELL_CAMERA_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
u32 status = set_and_send_read_mode(dev_num, info->read_mode);
|
||||
if (status != CELL_OK)
|
||||
s32 status;
|
||||
if ((status = cellCameraSetAttribute(dev_num, CELL_CAMERA_READMODE, info->read_mode, 0)) != CELL_OK)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
@ -826,7 +762,6 @@ s32 cellCameraGetBufferSize(s32 dev_num, vm::ptr<CellCameraInfoEx> info)
|
|||
semaphore_lock lock(g_camera->mutex);
|
||||
|
||||
info->bytesize = get_video_buffer_size(g_camera->info);
|
||||
|
||||
g_camera->info = *info;
|
||||
|
||||
return info->bytesize;
|
||||
|
@ -864,8 +799,6 @@ s32 cellCameraGetBufferInfoEx(s32 dev_num, vm::ptr<CellCameraInfoEx> info)
|
|||
return CELL_CAMERA_ERROR_PARAM;
|
||||
}
|
||||
|
||||
semaphore_lock lock(g_camera->mutex);
|
||||
|
||||
if (!g_camera->is_open)
|
||||
{
|
||||
return CELL_CAMERA_ERROR_NOT_OPEN;
|
||||
|
@ -876,6 +809,7 @@ s32 cellCameraGetBufferInfoEx(s32 dev_num, vm::ptr<CellCameraInfoEx> info)
|
|||
return CELL_CAMERA_ERROR_PARAM;
|
||||
}
|
||||
|
||||
semaphore_lock lock(g_camera->mutex);
|
||||
*info = g_camera->info;
|
||||
|
||||
return CELL_OK;
|
||||
|
@ -928,8 +862,6 @@ s32 cellCameraReset(s32 dev_num)
|
|||
return CELL_CAMERA_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
semaphore_lock lock(g_camera->mutex);
|
||||
|
||||
if (!g_camera->is_open)
|
||||
{
|
||||
return CELL_CAMERA_ERROR_NOT_OPEN;
|
||||
|
@ -1092,8 +1024,6 @@ s32 cellCameraStop(s32 dev_num)
|
|||
return CELL_CAMERA_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
semaphore_lock lock(g_camera->mutex);
|
||||
|
||||
if (!g_camera->is_open)
|
||||
{
|
||||
return CELL_CAMERA_ERROR_NOT_OPEN;
|
||||
|
@ -1110,6 +1040,8 @@ s32 cellCameraStop(s32 dev_num)
|
|||
}
|
||||
|
||||
g_camera->is_streaming = false;
|
||||
|
||||
semaphore_lock lock(g_camera->mutex);
|
||||
g_camera->timer.Stop();
|
||||
|
||||
return CELL_OK;
|
||||
|
@ -1124,11 +1056,14 @@ s32 cellCameraSetNotifyEventQueue(u64 key)
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
if (!add_queue_and_send_attach(key, 0, 0))
|
||||
const auto g_camera = fxm::get<camera_thread>();
|
||||
if (!g_camera)
|
||||
{
|
||||
return CELL_CAMERA_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
g_camera->add_queue(key, 0, 0);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
@ -1141,11 +1076,14 @@ s32 cellCameraRemoveNotifyEventQueue(u64 key)
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
if (!remove_queue(key))
|
||||
const auto g_camera = fxm::get<camera_thread>();
|
||||
if (!g_camera)
|
||||
{
|
||||
return CELL_CAMERA_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
g_camera->remove_queue(key);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
@ -1158,11 +1096,14 @@ s32 cellCameraSetNotifyEventQueue2(u64 key, u64 source, u64 flag)
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
if (!add_queue_and_send_attach(key, source, flag))
|
||||
const auto g_camera = fxm::get<camera_thread>();
|
||||
if (!g_camera)
|
||||
{
|
||||
return CELL_CAMERA_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
g_camera->add_queue(key, source, flag);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
@ -1211,6 +1152,8 @@ DECLARE(ppu_module_manager::cellCamera)("cellCamera", []()
|
|||
REG_FUNC(cellCamera, cellCameraRemoveNotifyEventQueue2);
|
||||
});
|
||||
|
||||
// camera_thread members
|
||||
|
||||
void camera_thread::on_task()
|
||||
{
|
||||
while (fxm::check<camera_thread>() && !Emu.IsStopped())
|
||||
|
@ -1311,3 +1254,42 @@ void camera_thread::send_attach_state(bool attached)
|
|||
is_attached = attached;
|
||||
}
|
||||
}
|
||||
|
||||
void camera_thread::set_attr(s32 attrib, u32 arg1, u32 arg2)
|
||||
{
|
||||
if (attrib == CELL_CAMERA_READMODE)
|
||||
{
|
||||
if (arg1 != CELL_CAMERA_READ_FUNCCALL && arg1 != CELL_CAMERA_READ_DIRECT)
|
||||
{
|
||||
LOG_WARNING(HLE, "Unknown read mode set: %d", arg1);
|
||||
arg1 = CELL_CAMERA_READ_FUNCCALL;
|
||||
}
|
||||
read_mode.exchange(arg1);
|
||||
}
|
||||
|
||||
semaphore_lock lock(mutex);
|
||||
attr[attrib] = {arg1, arg2};
|
||||
}
|
||||
|
||||
void camera_thread::add_queue(u64 key, u64 source, u64 flag)
|
||||
{
|
||||
semaphore_lock lock(mutex);
|
||||
{
|
||||
semaphore_lock lock_data_map(mutex_notify_data_map);
|
||||
|
||||
notify_data_map[key] = { source, flag };
|
||||
}
|
||||
|
||||
// send ATTACH event - HACKY
|
||||
send_attach_state(true);
|
||||
}
|
||||
|
||||
void camera_thread::remove_queue(u64 key)
|
||||
{
|
||||
semaphore_lock lock(mutex);
|
||||
{
|
||||
semaphore_lock lock_data_map(mutex_notify_data_map);
|
||||
|
||||
notify_data_map.erase(key);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -367,6 +367,21 @@ private:
|
|||
public:
|
||||
void on_init(const std::shared_ptr<void>&) override;
|
||||
void send_attach_state(bool attached);
|
||||
void set_attr(s32 attrib, u32 arg1, u32 arg2);
|
||||
|
||||
/**
|
||||
* \brief Sets up notify event queue supplied and immediately sends an ATTACH event to it
|
||||
* \param key Event queue key to add
|
||||
* \param source Event source port
|
||||
* \param flag Event flag (CELL_CAMERA_EFLAG_*)
|
||||
*/
|
||||
void add_queue(u64 key, u64 source, u64 flag);
|
||||
|
||||
/**
|
||||
* \brief Unsets/removes event queue specified
|
||||
* \param key Event queue key to remove
|
||||
*/
|
||||
void remove_queue(u64 key);
|
||||
|
||||
std::map<u64, notify_event_data> notify_data_map;
|
||||
|
||||
|
@ -374,10 +389,10 @@ public:
|
|||
semaphore<> mutex_notify_data_map;
|
||||
Timer timer;
|
||||
|
||||
atomic_t<u8> read_mode;
|
||||
atomic_t<bool> is_streaming;
|
||||
atomic_t<bool> is_attached;
|
||||
atomic_t<bool> is_open;
|
||||
atomic_t<u8> read_mode{0};
|
||||
atomic_t<bool> is_streaming{false};
|
||||
atomic_t<bool> is_attached{false};
|
||||
atomic_t<bool> is_open{false};
|
||||
|
||||
CellCameraInfoEx info;
|
||||
|
||||
|
|
Loading…
Reference in a new issue