mirror of https://github.com/RPCS3/rpcs3.git
cellCamera: Fixes
- Fix regression from #4676 - Refactoring of event queue management stuff - Some accuracy fixes
This commit is contained in:
parent
69af607491
commit
1625f4bcc9
|
@ -245,70 +245,6 @@ static s32 check_camera_info(const CellCameraInfoEx& info)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return CELL_OK;
|
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)
|
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.
|
// 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;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,23 +393,17 @@ s32 cellCameraOpenEx(s32 dev_num, vm::ptr<CellCameraInfoEx> info)
|
||||||
return CELL_CAMERA_ERROR_DEVICE_NOT_FOUND;
|
return CELL_CAMERA_ERROR_DEVICE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto g_camera = fxm::get<camera_thread>();
|
s32 status;
|
||||||
|
if ((status = cellCameraSetAttribute(dev_num, CELL_CAMERA_READMODE, info->read_mode, 0)) != CELL_OK)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
if (info->read_mode == CELL_CAMERA_READ_DIRECT)
|
||||||
status = cellCameraSetAttribute(dev_num, CELL_CAMERA_GAMEPID, 0, 0); // yup, that's what libGem does
|
|
||||||
if (status != CELL_OK)
|
|
||||||
{
|
{
|
||||||
return status;
|
if ((status = cellCameraSetAttribute(dev_num, CELL_CAMERA_GAMEPID, status, 0)) != CELL_OK)
|
||||||
|
{
|
||||||
|
return status;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!check_dev_num)
|
if (!check_dev_num)
|
||||||
|
@ -476,7 +411,8 @@ s32 cellCameraOpenEx(s32 dev_num, vm::ptr<CellCameraInfoEx> info)
|
||||||
return CELL_CAMERA_ERROR_PARAM;
|
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)
|
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);
|
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)
|
if (info->read_mode == CELL_CAMERA_READ_FUNCCALL && !info->buffer)
|
||||||
{
|
{
|
||||||
info->buffer = vm::cast(vm::alloc(vbuf_size, vm::memory_location_t::main));
|
info->buffer = vm::cast(vm::alloc(vbuf_size, vm::memory_location_t::main));
|
||||||
|
@ -635,12 +573,15 @@ s32 cellCameraIsAttached(s32 dev_num)
|
||||||
|
|
||||||
bool is_attached = g_camera->is_attached;
|
bool is_attached = g_camera->is_attached;
|
||||||
|
|
||||||
// "attach" camera here
|
if (g_cfg.io.camera == camera_handler::fake)
|
||||||
// normally should be attached immediately after event queue is registered, but just to be sure
|
|
||||||
if (!is_attached)
|
|
||||||
{
|
{
|
||||||
g_camera->send_attach_state(true);
|
// "attach" camera here
|
||||||
is_attached = g_camera->is_attached;
|
// normally should be attached immediately after event queue is registered, but just to be sure
|
||||||
|
if (!is_attached)
|
||||||
|
{
|
||||||
|
g_camera->send_attach_state(true);
|
||||||
|
is_attached = g_camera->is_attached;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 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;
|
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);
|
semaphore_lock lock(g_camera->mutex);
|
||||||
|
|
||||||
if (!g_camera->is_attached)
|
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;
|
return CELL_CAMERA_ERROR_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
semaphore_lock lock(g_camera->mutex);
|
// actually compares <= 0x63 which is equivalent
|
||||||
|
if (attrib < CELL_CAMERA_FORMATCAP && !g_camera->is_open)
|
||||||
if (!g_camera->is_open)
|
|
||||||
{
|
{
|
||||||
return CELL_CAMERA_ERROR_NOT_OPEN;
|
return CELL_CAMERA_ERROR_NOT_OPEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attrib == CELL_CAMERA_READMODE)
|
g_camera->set_attr(attrib, arg1, arg2);
|
||||||
{
|
|
||||||
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 };
|
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -817,8 +753,8 @@ s32 cellCameraGetBufferSize(s32 dev_num, vm::ptr<CellCameraInfoEx> info)
|
||||||
return CELL_CAMERA_ERROR_DEVICE_NOT_FOUND;
|
return CELL_CAMERA_ERROR_DEVICE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 status = set_and_send_read_mode(dev_num, info->read_mode);
|
s32 status;
|
||||||
if (status != CELL_OK)
|
if ((status = cellCameraSetAttribute(dev_num, CELL_CAMERA_READMODE, info->read_mode, 0)) != CELL_OK)
|
||||||
{
|
{
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -826,7 +762,6 @@ s32 cellCameraGetBufferSize(s32 dev_num, vm::ptr<CellCameraInfoEx> info)
|
||||||
semaphore_lock lock(g_camera->mutex);
|
semaphore_lock lock(g_camera->mutex);
|
||||||
|
|
||||||
info->bytesize = get_video_buffer_size(g_camera->info);
|
info->bytesize = get_video_buffer_size(g_camera->info);
|
||||||
|
|
||||||
g_camera->info = *info;
|
g_camera->info = *info;
|
||||||
|
|
||||||
return info->bytesize;
|
return info->bytesize;
|
||||||
|
@ -864,8 +799,6 @@ s32 cellCameraGetBufferInfoEx(s32 dev_num, vm::ptr<CellCameraInfoEx> info)
|
||||||
return CELL_CAMERA_ERROR_PARAM;
|
return CELL_CAMERA_ERROR_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
semaphore_lock lock(g_camera->mutex);
|
|
||||||
|
|
||||||
if (!g_camera->is_open)
|
if (!g_camera->is_open)
|
||||||
{
|
{
|
||||||
return CELL_CAMERA_ERROR_NOT_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;
|
return CELL_CAMERA_ERROR_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
semaphore_lock lock(g_camera->mutex);
|
||||||
*info = g_camera->info;
|
*info = g_camera->info;
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
|
@ -928,8 +862,6 @@ s32 cellCameraReset(s32 dev_num)
|
||||||
return CELL_CAMERA_ERROR_NOT_INIT;
|
return CELL_CAMERA_ERROR_NOT_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
semaphore_lock lock(g_camera->mutex);
|
|
||||||
|
|
||||||
if (!g_camera->is_open)
|
if (!g_camera->is_open)
|
||||||
{
|
{
|
||||||
return CELL_CAMERA_ERROR_NOT_OPEN;
|
return CELL_CAMERA_ERROR_NOT_OPEN;
|
||||||
|
@ -1092,8 +1024,6 @@ s32 cellCameraStop(s32 dev_num)
|
||||||
return CELL_CAMERA_ERROR_NOT_INIT;
|
return CELL_CAMERA_ERROR_NOT_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
semaphore_lock lock(g_camera->mutex);
|
|
||||||
|
|
||||||
if (!g_camera->is_open)
|
if (!g_camera->is_open)
|
||||||
{
|
{
|
||||||
return CELL_CAMERA_ERROR_NOT_OPEN;
|
return CELL_CAMERA_ERROR_NOT_OPEN;
|
||||||
|
@ -1110,6 +1040,8 @@ s32 cellCameraStop(s32 dev_num)
|
||||||
}
|
}
|
||||||
|
|
||||||
g_camera->is_streaming = false;
|
g_camera->is_streaming = false;
|
||||||
|
|
||||||
|
semaphore_lock lock(g_camera->mutex);
|
||||||
g_camera->timer.Stop();
|
g_camera->timer.Stop();
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
|
@ -1124,11 +1056,14 @@ s32 cellCameraSetNotifyEventQueue(u64 key)
|
||||||
return CELL_OK;
|
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;
|
return CELL_CAMERA_ERROR_NOT_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_camera->add_queue(key, 0, 0);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1141,11 +1076,14 @@ s32 cellCameraRemoveNotifyEventQueue(u64 key)
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!remove_queue(key))
|
const auto g_camera = fxm::get<camera_thread>();
|
||||||
|
if (!g_camera)
|
||||||
{
|
{
|
||||||
return CELL_CAMERA_ERROR_NOT_INIT;
|
return CELL_CAMERA_ERROR_NOT_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_camera->remove_queue(key);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1158,11 +1096,14 @@ s32 cellCameraSetNotifyEventQueue2(u64 key, u64 source, u64 flag)
|
||||||
return CELL_OK;
|
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;
|
return CELL_CAMERA_ERROR_NOT_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_camera->add_queue(key, source, flag);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1211,6 +1152,8 @@ DECLARE(ppu_module_manager::cellCamera)("cellCamera", []()
|
||||||
REG_FUNC(cellCamera, cellCameraRemoveNotifyEventQueue2);
|
REG_FUNC(cellCamera, cellCameraRemoveNotifyEventQueue2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// camera_thread members
|
||||||
|
|
||||||
void camera_thread::on_task()
|
void camera_thread::on_task()
|
||||||
{
|
{
|
||||||
while (fxm::check<camera_thread>() && !Emu.IsStopped())
|
while (fxm::check<camera_thread>() && !Emu.IsStopped())
|
||||||
|
@ -1311,3 +1254,42 @@ void camera_thread::send_attach_state(bool attached)
|
||||||
is_attached = 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:
|
public:
|
||||||
void on_init(const std::shared_ptr<void>&) override;
|
void on_init(const std::shared_ptr<void>&) override;
|
||||||
void send_attach_state(bool attached);
|
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;
|
std::map<u64, notify_event_data> notify_data_map;
|
||||||
|
|
||||||
|
@ -374,10 +389,10 @@ public:
|
||||||
semaphore<> mutex_notify_data_map;
|
semaphore<> mutex_notify_data_map;
|
||||||
Timer timer;
|
Timer timer;
|
||||||
|
|
||||||
atomic_t<u8> read_mode;
|
atomic_t<u8> read_mode{0};
|
||||||
atomic_t<bool> is_streaming;
|
atomic_t<bool> is_streaming{false};
|
||||||
atomic_t<bool> is_attached;
|
atomic_t<bool> is_attached{false};
|
||||||
atomic_t<bool> is_open;
|
atomic_t<bool> is_open{false};
|
||||||
|
|
||||||
CellCameraInfoEx info;
|
CellCameraInfoEx info;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue