mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-09-20 04:42:18 +02:00
libobs: WinRT and dispatcher init on graphics thread
Suspected necessary for WGC stability.
This commit is contained in:
parent
49bc89f2b2
commit
5734ab7a9b
@ -539,7 +539,7 @@ static const uint8_t *set_gpu_converted_plane(uint32_t width, uint32_t height,
|
||||
const uint8_t *in, uint8_t *out)
|
||||
{
|
||||
if ((width == linesize_input) && (width == linesize_output)) {
|
||||
size_t total = width * height;
|
||||
size_t total = (size_t)width * (size_t)height;
|
||||
memcpy(out, in, total);
|
||||
in += total;
|
||||
} else {
|
||||
@ -672,10 +672,12 @@ static inline void copy_rgbx_frame(struct video_frame *output,
|
||||
|
||||
/* if the line sizes match, do a single copy */
|
||||
if (input->linesize[0] == output->linesize[0]) {
|
||||
memcpy(out_ptr, in_ptr, input->linesize[0] * info->height);
|
||||
memcpy(out_ptr, in_ptr,
|
||||
(size_t)input->linesize[0] * (size_t)info->height);
|
||||
} else {
|
||||
const size_t copy_size = (size_t)info->width * 4;
|
||||
for (size_t y = 0; y < info->height; y++) {
|
||||
memcpy(out_ptr, in_ptr, info->width * 4);
|
||||
memcpy(out_ptr, in_ptr, copy_size);
|
||||
in_ptr += input->linesize[0];
|
||||
out_ptr += output->linesize[0];
|
||||
}
|
||||
@ -835,11 +837,97 @@ static void execute_graphics_tasks(void)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
struct winrt_exports {
|
||||
void (*winrt_initialize)();
|
||||
void (*winrt_uninitialize)();
|
||||
struct winrt_disaptcher *(*winrt_dispatcher_init)();
|
||||
void (*winrt_dispatcher_free)(struct winrt_disaptcher *dispatcher);
|
||||
void (*winrt_capture_thread_start)();
|
||||
void (*winrt_capture_thread_stop)();
|
||||
};
|
||||
|
||||
#define WINRT_IMPORT(func) \
|
||||
do { \
|
||||
exports->func = os_dlsym(module, #func); \
|
||||
if (!exports->func) { \
|
||||
success = false; \
|
||||
blog(LOG_ERROR, \
|
||||
"Could not load function '%s' from " \
|
||||
"module '%s'", \
|
||||
#func, module_name); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
static bool load_winrt_imports(struct winrt_exports *exports, void *module,
|
||||
const char *module_name)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
WINRT_IMPORT(winrt_initialize);
|
||||
WINRT_IMPORT(winrt_uninitialize);
|
||||
WINRT_IMPORT(winrt_dispatcher_init);
|
||||
WINRT_IMPORT(winrt_dispatcher_free);
|
||||
WINRT_IMPORT(winrt_capture_thread_start);
|
||||
WINRT_IMPORT(winrt_capture_thread_stop);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
struct winrt_state {
|
||||
bool loaded;
|
||||
void *winrt_module;
|
||||
struct winrt_exports exports;
|
||||
struct winrt_disaptcher *dispatcher;
|
||||
};
|
||||
|
||||
static void init_winrt_state(struct winrt_state *winrt)
|
||||
{
|
||||
static const char *const module_name = "libobs-winrt";
|
||||
|
||||
winrt->winrt_module = os_dlopen(module_name);
|
||||
winrt->loaded = winrt->winrt_module &&
|
||||
load_winrt_imports(&winrt->exports, winrt->winrt_module,
|
||||
module_name);
|
||||
winrt->dispatcher = NULL;
|
||||
if (winrt->loaded) {
|
||||
winrt->exports.winrt_initialize();
|
||||
winrt->dispatcher = winrt->exports.winrt_dispatcher_init();
|
||||
|
||||
gs_enter_context(obs->video.graphics);
|
||||
winrt->exports.winrt_capture_thread_start();
|
||||
gs_leave_context();
|
||||
}
|
||||
}
|
||||
|
||||
static void uninit_winrt_state(struct winrt_state *winrt)
|
||||
{
|
||||
if (winrt->winrt_module) {
|
||||
if (winrt->loaded) {
|
||||
winrt->exports.winrt_capture_thread_stop();
|
||||
if (winrt->dispatcher)
|
||||
winrt->exports.winrt_dispatcher_free(
|
||||
winrt->dispatcher);
|
||||
winrt->exports.winrt_uninitialize();
|
||||
}
|
||||
|
||||
os_dlclose(winrt->winrt_module);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #ifdef _WIN32
|
||||
|
||||
static const char *tick_sources_name = "tick_sources";
|
||||
static const char *render_displays_name = "render_displays";
|
||||
static const char *output_frame_name = "output_frame";
|
||||
void *obs_graphics_thread(void *param)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
struct winrt_state winrt;
|
||||
init_winrt_state(&winrt);
|
||||
#endif // #ifdef _WIN32
|
||||
|
||||
uint64_t last_time = 0;
|
||||
uint64_t interval = video_output_get_frame_time(obs->video.video);
|
||||
uint64_t frame_time_total_ns = 0;
|
||||
@ -952,6 +1040,10 @@ void *obs_graphics_thread(void *param)
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
uninit_winrt_state(&winrt);
|
||||
#endif
|
||||
|
||||
UNUSED_PARAMETER(param);
|
||||
return NULL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user