Simplify IS-Driver-related code

This commit is contained in:
Lorenzooone 2024-11-08 04:10:25 +01:00
parent dccc50036c
commit e8e2ef5354
9 changed files with 26 additions and 172 deletions

View File

@ -42,10 +42,6 @@ struct isn_async_callback_data {
int status_value;
bool is_data_ready;
int internal_index;
isn_async_callback_data** cb_queue;
int* queue_elems;
bool* one_transfer_active;
isn_async_callback_data* cb_active_transfer;
};
struct is_nitro_usb_device {
@ -92,8 +88,5 @@ void CloseAsyncRead(is_nitro_device_handlers* handlers, isn_async_callback_data*
void SetupISNitroAsyncThread(is_nitro_device_handlers* handlers, void* user_data, std::thread* thread_ptr, bool* keep_going, ConsumerMutex* is_data_ready);
void EndISNitroAsyncThread(is_nitro_device_handlers* handlers, void* user_data, std::thread* thread_ptr, bool* keep_going, ConsumerMutex* is_data_ready);
void SleepBetweenTransfers(is_nitro_device_handlers* handlers, float ms);
void SleepUntilOneFree(is_nitro_device_handlers* handlers, SharedConsumerMutex* mutex);
void SleepUntilFree(is_nitro_device_handlers* handlers, SharedConsumerMutex* mutex, int index);
#endif

View File

@ -17,8 +17,5 @@ void is_nitro_is_driver_cancel_callback(isn_async_callback_data* cb_data);
void is_nitro_is_driver_start_thread(std::thread* thread_ptr, bool* usb_thread_run, ISNitroCaptureReceivedData* is_nitro_capture_recv_data, is_nitro_device_handlers* handlers, ConsumerMutex* AsyncMutexPtr);
void is_nitro_is_driver_close_thread(std::thread* thread_ptr, bool* usb_thread_run, ISNitroCaptureReceivedData* is_nitro_capture_recv_data);
void is_nitro_is_driver_sleep_between_transfers(float ms);
void is_nitro_is_driver_sleep_until_one_free(SharedConsumerMutex* mutex);
void is_nitro_is_driver_sleep_until_free(SharedConsumerMutex* mutex, int index);
#endif

View File

@ -5,12 +5,6 @@
#include "capture_structs.hpp"
#include "usb_is_nitro_communications.hpp"
void is_nitro_libusb_start_thread(std::thread* thread_ptr, bool* usb_thread_run);
void is_nitro_libusb_close_thread(std::thread* thread_ptr, bool* usb_thread_run);
void is_nitro_libusb_sleep_between_transfers(float ms);
void is_nitro_libusb_sleep_until_one_free(SharedConsumerMutex* mutex);
void is_nitro_libusb_sleep_until_free(SharedConsumerMutex* mutex, int index);
void is_nitro_libusb_list_devices(std::vector<CaptureDevice>& devices_list, bool* no_access_elems, bool* not_supported_elems, int* curr_serial_extra_id_is_nitro, const size_t num_is_nitro_desc);
is_nitro_device_handlers* is_nitro_libusb_serial_reconnection(const is_nitro_usb_device* usb_device_desc, CaptureDevice* device, int& curr_serial_extra_id);
void is_nitro_libusb_end_connection(is_nitro_device_handlers* handlers, const is_nitro_usb_device* device_desc, bool interface_claimed);
@ -19,4 +13,7 @@ int is_nitro_libusb_bulk_in(is_nitro_device_handlers* handlers, const is_nitro_u
void is_nitro_libusb_async_in_start(is_nitro_device_handlers* handlers, const is_nitro_usb_device* usb_device_desc, uint8_t* buf, int length, isn_async_callback_data* cb_data);
void is_nitro_libusb_cancell_callback(isn_async_callback_data* cb_data);
void is_nitro_libusb_start_thread(std::thread* thread_ptr, bool* usb_thread_run);
void is_nitro_libusb_close_thread(std::thread* thread_ptr, bool* usb_thread_run);
#endif

View File

@ -256,21 +256,21 @@ void wait_all_is_nitro_transfers_done(CaptureData* capture_data, ISNitroCaptureR
transfer_data = is_nitro_capture_recv_data[i].cb_data.transfer_data;
is_nitro_capture_recv_data[i].cb_data.transfer_data_access.unlock();
if(transfer_data)
SleepUntilFree((is_nitro_device_handlers*)capture_data->handle, is_nitro_capture_recv_data[i].cb_data.is_transfer_done_mutex, i);
is_nitro_capture_recv_data[i].cb_data.is_transfer_done_mutex->specific_lock(i);
} while(transfer_data);
}
}
void wait_all_is_nitro_buffers_free(CaptureData* capture_data, ISNitroCaptureReceivedData* is_nitro_capture_recv_data) {
if (is_nitro_capture_recv_data == NULL)
if(is_nitro_capture_recv_data == NULL)
return;
if (*is_nitro_capture_recv_data[0].status < 0) {
for (int i = 0; i < NUM_CAPTURE_RECEIVED_DATA_BUFFERS; i++)
if(*is_nitro_capture_recv_data[0].status < 0) {
for(int i = 0; i < NUM_CAPTURE_RECEIVED_DATA_BUFFERS; i++)
CloseAsyncRead((is_nitro_device_handlers*)capture_data->handle, &is_nitro_capture_recv_data[i].cb_data);
}
for (int i = 0; i < NUM_CAPTURE_RECEIVED_DATA_BUFFERS; i++)
while (is_nitro_capture_recv_data[i].in_use)
SleepUntilFree((is_nitro_device_handlers*)capture_data->handle, is_nitro_capture_recv_data[i].is_buffer_free_shared_mutex, i);
for(int i = 0; i < NUM_CAPTURE_RECEIVED_DATA_BUFFERS; i++)
while(is_nitro_capture_recv_data[i].in_use)
is_nitro_capture_recv_data[i].is_buffer_free_shared_mutex->specific_lock(i);
}
void wait_one_is_nitro_buffer_free(CaptureData* capture_data, ISNitroCaptureReceivedData* is_nitro_capture_recv_data) {
@ -283,7 +283,8 @@ void wait_one_is_nitro_buffer_free(CaptureData* capture_data, ISNitroCaptureRece
if(!done) {
if(*is_nitro_capture_recv_data[0].status < 0)
return;
SleepUntilOneFree((is_nitro_device_handlers*)capture_data->handle, is_nitro_capture_recv_data[0].is_buffer_free_shared_mutex);
int dummy = 0;
is_nitro_capture_recv_data[0].is_buffer_free_shared_mutex->general_timed_lock(&dummy);
}
}
}
@ -344,9 +345,6 @@ void is_nitro_acquisition_main_loop(CaptureData* capture_data) {
is_nitro_capture_recv_data[i].cb_data.internal_index = i;
is_nitro_capture_recv_data[i].cb_data.is_transfer_data_ready_mutex = &is_transfer_data_ready_shared_mutex;
is_nitro_capture_recv_data[i].cb_data.is_data_ready = false;
is_nitro_capture_recv_data[i].cb_data.cb_queue = cb_queue;
is_nitro_capture_recv_data[i].cb_data.queue_elems = &queue_elems;
is_nitro_capture_recv_data[i].cb_data.one_transfer_active = &one_transfer_active;
}
SetupISNitroAsyncThread((is_nitro_device_handlers*)capture_data->handle, is_nitro_capture_recv_data, &async_processing_thread, &is_done_thread, &has_data_been_processed);
capture_data->status.reset_hardware = false;

View File

@ -11,6 +11,7 @@
#define CAPTURE_SKIP_LID_REOPEN_FRAMES 32
#define RESET_TIMEOUT 4.0
#define SLEEP_CHECKS_TIME_MS 20
#define SLEEP_RESET_TIME_MS 2000
static int StartAcquisitionCapture(CaptureData* capture_data, ISNitroCaptureReceivedData* is_nitro_capture_recv_data, CaptureScreensType capture_type, CaptureSpeedsType capture_speed, bool* is_acquisition_off, uint32_t &index) {
is_nitro_device_handlers* handlers = (is_nitro_device_handlers*)capture_data->handle;
@ -76,6 +77,7 @@ static int CaptureResetHardware(CaptureData* capture_data, ISNitroCaptureReceive
if(ret < 0)
return ret;
if(!(*is_acquisition_off)) {
default_sleep(SLEEP_RESET_TIME_MS);
curr_capture_type = capture_data->status.capture_type;
curr_capture_speed = capture_data->status.capture_speed;
ret = StartAcquisitionCapture(capture_data, is_nitro_capture_recv_data, curr_capture_type, curr_capture_speed, is_acquisition_off, index);
@ -91,7 +93,7 @@ int initial_cleanup_capture(const is_nitro_usb_device* usb_device_desc, is_nitro
}
int EndAcquisitionCapture(CaptureData* capture_data, ISNitroCaptureReceivedData* is_nitro_capture_recv_data) {
wait_all_is_nitro_buffers_free(capture_data, is_nitro_capture_recv_data);
wait_all_is_nitro_transfers_done(capture_data, is_nitro_capture_recv_data);
return EndAcquisitionCapture((const is_nitro_usb_device*)capture_data->status.device.descriptor, (is_nitro_device_handlers*)capture_data->handle);
}
@ -120,7 +122,7 @@ void is_nitro_acquisition_capture_main_loop(CaptureData* capture_data, ISNitroCa
return;
}
if(is_acquisition_off) {
SleepBetweenTransfers(handlers, SLEEP_CHECKS_TIME_MS);
default_sleep(SLEEP_CHECKS_TIME_MS);
ret = LidReopenCaptureCheck(capture_data, is_nitro_capture_recv_data, curr_capture_type, curr_capture_speed, &is_acquisition_off, index);
if(ret < 0) {
capture_error_print(true, capture_data, "Lid Reopen: Failed");

View File

@ -166,13 +166,13 @@ static bool do_sleep(float single_frame_time, std::chrono::time_point<std::chron
return result;
}
static void frame_wait(is_nitro_device_handlers* handlers, float single_frame_time, std::chrono::time_point<std::chrono::high_resolution_clock> clock_last_reset, CaptureScreensType capture_type, CaptureSpeedsType capture_speed, int curr_frame_counter, int last_frame_counter) {
static void frame_wait(float single_frame_time, std::chrono::time_point<std::chrono::high_resolution_clock> clock_last_reset, CaptureScreensType capture_type, CaptureSpeedsType capture_speed, int curr_frame_counter, int last_frame_counter) {
if(curr_frame_counter == FRAME_BUFFER_SIZE)
return;
float sleep_time = 0;
int sleep_counter = 0;
while(do_sleep(single_frame_time, clock_last_reset, capture_type, capture_speed, curr_frame_counter, last_frame_counter, &sleep_time)) {
SleepBetweenTransfers(handlers, sleep_time * 1000.0 / SLEEP_TIME_DIVISOR);
default_sleep(sleep_time * 1000.0 / SLEEP_TIME_DIVISOR);
sleep_counter++;
}
}
@ -185,7 +185,7 @@ static int reset_acquisition_frames(CaptureData* capture_data, uint16_t &curr_fr
is_nitro_device_handlers* handlers = (is_nitro_device_handlers*)capture_data->handle;
const is_nitro_usb_device* usb_device_desc = (const is_nitro_usb_device*)capture_data->status.device.descriptor;
wait_all_is_nitro_buffers_free(capture_data, is_nitro_capture_recv_data);
wait_all_is_nitro_transfers_done(capture_data, is_nitro_capture_recv_data);
int ret = get_is_nitro_status(is_nitro_capture_recv_data);
if (ret < 0)
return ret;
@ -228,7 +228,7 @@ static int reset_acquisition_frames(CaptureData* capture_data, uint16_t &curr_fr
if((frame_diff > 0) && (((internalFrameCount & (FRAME_BUFFER_SIZE - 1)) < (FRAME_BUFFER_SIZE - 1)))) {
float expected_time = single_frame_time * FRAME_BUFFER_SIZE;
if(diff.count() < expected_time)
SleepBetweenTransfers(handlers, single_frame_time * 1000.0 / SLEEP_TIME_DIVISOR);
default_sleep(single_frame_time * 1000.0 / SLEEP_TIME_DIVISOR);
}
// Check how many frames have passed...
ret = GetFrameCounter(handlers, &internalFrameCount, usb_device_desc);
@ -300,7 +300,7 @@ int initial_cleanup_emulator(const is_nitro_usb_device* usb_device_desc, is_nitr
}
int EndAcquisitionEmulator(CaptureData* capture_data, ISNitroCaptureReceivedData* is_nitro_capture_recv_data, bool do_drain_frames, int start_frames, CaptureScreensType capture_type) {
wait_all_is_nitro_buffers_free(capture_data, is_nitro_capture_recv_data);
wait_all_is_nitro_transfers_done(capture_data, is_nitro_capture_recv_data);
return EndAcquisitionEmulator((const is_nitro_usb_device*)capture_data->status.device.descriptor, (is_nitro_device_handlers*)capture_data->handle, do_drain_frames, start_frames, capture_type);
}
@ -340,12 +340,12 @@ void is_nitro_acquisition_emulator_main_loop(CaptureData* capture_data, ISNitroC
}
if(single_frame_time > 0) {
is_nitro_read_frame_request(capture_data, is_nitro_get_free_buffer(capture_data, is_nitro_capture_recv_data), curr_capture_type, index++);
frame_wait(handlers, single_frame_time, clock_last_reset, curr_capture_type, curr_capture_speed, curr_frame_counter + 1, last_frame_counter);
frame_wait(single_frame_time, clock_last_reset, curr_capture_type, curr_capture_speed, curr_frame_counter + 1, last_frame_counter);
}
else {
capture_data->status.cooldown_curr_in = FIX_PARTIAL_FIRST_FRAME_NUM;
clock_last_reset = std::chrono::high_resolution_clock::now();
SleepBetweenTransfers(handlers, SLEEP_CHECKS_TIME_MS);
default_sleep(SLEEP_CHECKS_TIME_MS);
}
capture_data->status.curr_delay = last_frame_counter % FRAME_BUFFER_SIZE;
ret = reset_acquisition_frames(capture_data, curr_frame_counter, last_frame_counter, single_frame_time, clock_last_reset, curr_capture_type, capture_data->status.capture_type, curr_capture_speed, capture_data->status.capture_speed, is_nitro_capture_recv_data);

View File

@ -553,22 +553,4 @@ void EndISNitroAsyncThread(is_nitro_device_handlers* handlers, void* user_data,
if(handlers->usb_handle)
return is_nitro_libusb_close_thread(thread_ptr, keep_going);
return is_nitro_is_driver_close_thread(thread_ptr, keep_going, (ISNitroCaptureReceivedData*)user_data);
}
void SleepBetweenTransfers(is_nitro_device_handlers* handlers, float ms) {
if (handlers->usb_handle)
return is_nitro_libusb_sleep_between_transfers(ms);
return is_nitro_is_driver_sleep_between_transfers(ms);
}
void SleepUntilOneFree(is_nitro_device_handlers* handlers, SharedConsumerMutex* mutex) {
if (handlers->usb_handle)
return is_nitro_libusb_sleep_until_one_free(mutex);
return is_nitro_is_driver_sleep_until_one_free(mutex);
}
void SleepUntilFree(is_nitro_device_handlers* handlers, SharedConsumerMutex* mutex, int index) {
if (handlers->usb_handle)
return is_nitro_libusb_sleep_until_free(mutex, index);
return is_nitro_is_driver_sleep_until_free(mutex, index);
}

View File

@ -29,10 +29,6 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//#define USE_QUEUED_TRANSFERS
static int SubmitRead(isn_async_callback_data* cb_data);
const GUID is_nitro_driver_guid = { .Data1 = 0xB78D7ADA, .Data2 = 0xDDF4, .Data3 = 0x418F, .Data4 = {0x8C, 0x7C, 0x4A, 0xC8, 0x80, 0x30, 0xF5, 0x42} };
static void is_nitro_is_driver_function(bool* usb_thread_run, ISNitroCaptureReceivedData* is_nitro_capture_recv_data, is_nitro_device_handlers* handlers) {
@ -150,34 +146,10 @@ static int wait_result_io_operation(HANDLE handle, OVERLAPPED* overlapped_var, i
return LIBUSB_SUCCESS;
}
static void ClearAllQueueElements(isn_async_callback_data* cb_data) {
int queue_elems_curr = *cb_data->queue_elems;
for (int i = 0; i < queue_elems_curr; i++) {
cb_data->cb_queue[i]->transfer_data = NULL;
ISNitroCaptureReceivedData* user_data = (ISNitroCaptureReceivedData*)cb_data->cb_queue[i]->actual_user_data;
user_data->in_use = false;
}
*cb_data->queue_elems = 0;
}
static void BasicCompletionOutputRoutine(isn_async_callback_data* cb_data, int num_bytes, int error) {
cb_data->transfer_data_access.lock();
if ((error == LIBUSB_SUCCESS) && (num_bytes != cb_data->requested_length))
error = LIBUSB_ERROR_INTERRUPTED;
if (error == LIBUSB_SUCCESS) {
if (*cb_data->queue_elems) {
isn_async_callback_data* cb_data_next = (isn_async_callback_data*)cb_data->cb_queue[--(*cb_data->queue_elems)];
int retval = SubmitRead(cb_data_next);
if (retval == 0)
error = LIBUSB_ERROR_BUSY;
}
else
*cb_data->one_transfer_active = false;
}
if (error != LIBUSB_SUCCESS) {
ClearAllQueueElements(cb_data);
*cb_data->one_transfer_active = false;
}
cb_data->transfer_data = NULL;
cb_data->actual_length = num_bytes;
cb_data->status_value = error;
@ -191,30 +163,6 @@ static void OverlappedCompletionNothingRoutine(DWORD dwErrorCode, DWORD dwNumber
return;
}
static void OverlappedCompletionOutputRoutine(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, OVERLAPPED* overlapped_var) {
isn_async_callback_data* cb_data = (isn_async_callback_data*)overlapped_var->hEvent;
DWORD num_bytes = 0;
bool retval = false;
int error = LIBUSB_ERROR_OTHER;
if (!dwErrorCode) {
retval = GetOverlappedResult(cb_data->handle, overlapped_var, &num_bytes, false);
error = GetLastError();
}
error = retval ? LIBUSB_SUCCESS : LIBUSB_ERROR_OTHER;
BasicCompletionOutputRoutine(cb_data, num_bytes, error);
}
static int SubmitRead(isn_async_callback_data* cb_data) {
#ifdef USE_QUEUED_TRANSFERS
int retval = ReadFileEx(cb_data->handle, cb_data->buffer, cb_data->requested_length, (OVERLAPPED*)cb_data->transfer_data, OverlappedCompletionOutputRoutine);
#else
int retval = ReadFileEx(cb_data->handle, cb_data->buffer, cb_data->requested_length, (OVERLAPPED*)cb_data->transfer_data, OverlappedCompletionNothingRoutine);
#endif
if (retval)
cb_data->cb_active_transfer = cb_data;
return retval;
}
#endif
is_nitro_device_handlers* is_driver_serial_reconnection(CaptureDevice* device) {
@ -325,27 +273,16 @@ int is_drive_async_in_start(is_nitro_device_handlers* handlers, const is_nitro_u
cb_data->buffer = buf;
OVERLAPPED* overlap_data = (OVERLAPPED*)cb_data->transfer_data;
memset(overlap_data, 0, sizeof(OVERLAPPED));
#ifdef USE_QUEUED_TRANSFERS
overlap_data->hEvent = cb_data;
#endif
cb_data->is_transfer_done_mutex->specific_try_lock(cb_data->internal_index);
cb_data->is_transfer_data_ready_mutex->specific_try_lock(cb_data->internal_index);
int retval = 1;
if (!(*cb_data->one_transfer_active))
retval = SubmitRead(cb_data);
else
cb_data->cb_queue[(*cb_data->queue_elems)++] = cb_data;
if(retval == 1)
*cb_data->one_transfer_active = true;
int retval = ReadFileEx(cb_data->handle, cb_data->buffer, cb_data->requested_length, (OVERLAPPED*)cb_data->transfer_data, OverlappedCompletionNothingRoutine);
cb_data->transfer_data_access.unlock();
if (retval == 0)
return LIBUSB_ERROR_BUSY;
#ifndef USE_QUEUED_TRANSFERS
int num_bytes = 0;
int error = wait_result_io_operation(handlers->read_handle, (OVERLAPPED*)overlap_data, &num_bytes, usb_device_desc);
BasicCompletionOutputRoutine(cb_data, num_bytes, error);
#endif
#endif
return LIBUSB_SUCCESS;
}
@ -370,45 +307,6 @@ void is_nitro_is_driver_close_thread(std::thread* thread_ptr, bool* usb_thread_r
void is_nitro_is_driver_cancel_callback(isn_async_callback_data* cb_data) {
#ifdef _WIN32
cb_data->transfer_data_access.lock();
ClearAllQueueElements(cb_data);
if(*cb_data->one_transfer_active) {
CancelIoEx(cb_data->cb_active_transfer->handle, (OVERLAPPED*)cb_data->cb_active_transfer->transfer_data);
*cb_data->one_transfer_active = false;
}
cb_data->transfer_data_access.unlock();
#endif
}
void is_nitro_is_driver_sleep_between_transfers(float ms) {
#ifdef _WIN32
#ifdef USE_QUEUED_TRANSFERS
SleepEx(ms, true);
#else
default_sleep(ms);
#endif
#endif
}
void is_nitro_is_driver_sleep_until_one_free(SharedConsumerMutex* mutex) {
#ifdef _WIN32
int dummy = 0;
#ifdef USE_QUEUED_TRANSFERS
SleepEx(mutex->get_time_s() * 100, true);
mutex->general_try_lock(&dummy);
#else
mutex->general_timed_lock(&dummy);
#endif
#endif
}
void is_nitro_is_driver_sleep_until_free(SharedConsumerMutex* mutex, int index) {
#ifdef _WIN32
#ifdef USE_QUEUED_TRANSFERS
while (!(mutex->specific_try_lock(index)))
SleepEx(mutex->get_time_s() * 100, true);
#else
mutex->specific_lock(index);
#endif
// Nothing
#endif
}

View File

@ -190,17 +190,4 @@ void is_nitro_libusb_async_in_start(is_nitro_device_handlers* handlers, const is
transfer_in->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
libusb_submit_transfer(transfer_in);
cb_data->transfer_data_access.unlock();
}
void is_nitro_libusb_sleep_between_transfers(float ms) {
default_sleep(ms);
}
void is_nitro_libusb_sleep_until_one_free(SharedConsumerMutex* mutex) {
int dummy = 0;
mutex->general_timed_lock(&dummy);
}
void is_nitro_libusb_sleep_until_free(SharedConsumerMutex* mutex, int index) {
mutex->specific_lock(index);
}
}