From c00d9e3b4e08640d23f18b9b2e82f4deb10719d0 Mon Sep 17 00:00:00 2001 From: fryshorts Date: Mon, 10 Feb 2014 19:09:44 +0100 Subject: [PATCH] Moved screen grabber code to _tick function Moved the screen grabbing and texture generation to the _tick function in order to keep _render fast. Migrated xshm video source to the new plugin api. --- test/linux/CMakeLists.txt | 2 - test/linux/linux.c | 26 ++----- test/linux/linux.h | 15 ---- test/linux/xcursor.c | 19 +++-- test/linux/xcursor.h | 15 +++- test/linux/xshm-input.c | 146 ++++++++++++++++++++++---------------- test/linux/xshm-input.h | 27 ------- 7 files changed, 119 insertions(+), 131 deletions(-) delete mode 100644 test/linux/linux.h delete mode 100644 test/linux/xshm-input.h diff --git a/test/linux/CMakeLists.txt b/test/linux/CMakeLists.txt index 20f8be146..42656540b 100644 --- a/test/linux/CMakeLists.txt +++ b/test/linux/CMakeLists.txt @@ -10,9 +10,7 @@ set(linux_SOURCES xshm-input.c ) set(linux_HEADERS - linux.h xcursor.h - xshm-input.h ) add_library(linux MODULE diff --git a/test/linux/linux.c b/test/linux/linux.c index 78c11c366..94ce14fb7 100644 --- a/test/linux/linux.c +++ b/test/linux/linux.c @@ -1,25 +1,11 @@ -#include -#include "linux.h" +#include -const char *inputs[] = { - "xshm_input" -}; +OBS_DECLARE_MODULE() -uint32_t module_version(uint32_t in_version) +extern struct obs_source_info xshm_input; + +bool obs_module_load(uint32_t obs_version) { - return LIBOBS_API_VER; -} - -bool enum_inputs(size_t idx, const char **name) -{ - if (idx >= (sizeof(inputs)/sizeof(const char*))) - return false; - - *name = inputs[idx]; + obs_register_source(&xshm_input); return true; } - -bool enum_filters(size_t idx, const char **name) -{ - return false; -} \ No newline at end of file diff --git a/test/linux/linux.h b/test/linux/linux.h deleted file mode 100644 index b64a7f5c0..000000000 --- a/test/linux/linux.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -EXPORT uint32_t module_version(uint32_t in_version); -EXPORT bool enum_inputs(size_t idx, const char **name); -EXPORT bool enum_filters(size_t idx, const char **name); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/test/linux/xcursor.c b/test/linux/xcursor.c index b3f012854..4e04588cf 100644 --- a/test/linux/xcursor.c +++ b/test/linux/xcursor.c @@ -50,6 +50,9 @@ xcursor_t *xcursor_init(Display *dpy) { data->dpy = dpy; + // initialize texture so we don't crash + xcursor_tick(data); + return data; } @@ -59,7 +62,7 @@ void xcursor_destroy(xcursor_t *data) { bfree(data); } -void xcursor_render(xcursor_t *data) { +void xcursor_tick(xcursor_t *data) { // get cursor data XFixesCursorImage *xc = XFixesGetCursorImage(data->dpy); @@ -67,6 +70,14 @@ void xcursor_render(xcursor_t *data) { if (!data->tex || data->last_serial != xc->cursor_serial) xcursor_create(data, xc); + // update cursor position + data->pos_x = -1.0 * (xc->x - xc->xhot); + data->pos_y = -1.0 * (xc->y - xc->yhot); + + XFree(xc); +} + +void xcursor_render(xcursor_t *data) { // TODO: why do i need effects ? effect_t effect = gs_geteffect(); eparam_t diffuse = effect_getparambyname(effect, "diffuse"); @@ -77,8 +88,8 @@ void xcursor_render(xcursor_t *data) { // move cursor to the right position gs_matrix_translate3f( - -1.0 * (xc->x - xc->xhot), - -1.0 * (xc->y - xc->yhot), + data->pos_x, + data->pos_y, 0 ); @@ -89,6 +100,4 @@ void xcursor_render(xcursor_t *data) { gs_enable_blending(False); gs_matrix_pop(); - - XFree(xc); } \ No newline at end of file diff --git a/test/linux/xcursor.h b/test/linux/xcursor.h index 110067362..b7850b551 100644 --- a/test/linux/xcursor.h +++ b/test/linux/xcursor.h @@ -8,14 +8,18 @@ extern "C" { typedef struct { Display *dpy; + float pos_x; + float pos_y; unsigned long last_serial; - short unsigned int last_width; - short unsigned int last_height; + unsigned short int last_width; + unsigned short int last_height; texture_t tex; } xcursor_t; /** * Initializes the xcursor object + * + * This needs to be executed within a valid render context */ xcursor_t *xcursor_init(Display *dpy); @@ -24,6 +28,13 @@ xcursor_t *xcursor_init(Display *dpy); */ void xcursor_destroy(xcursor_t *data); +/** + * Update the cursor texture + * + * This needs to be executed within a valid render context + */ +void xcursor_tick(xcursor_t *data); + /** * Draw the cursor * diff --git a/test/linux/xshm-input.c b/test/linux/xshm-input.c index ee7e12f27..f8dca2869 100644 --- a/test/linux/xshm-input.c +++ b/test/linux/xshm-input.c @@ -4,15 +4,14 @@ #include #include #include +#include #include "xcursor.h" -#include "xshm-input.h" + +#define XSHM_DATA(voidptr) struct xshm_data *data = voidptr; struct xshm_data { Display *dpy; - Screen *screen; Window root_window; - Visual *visual; - int depth; uint32_t width, height; int shm_attached; XShmSegmentInfo shm_info; @@ -21,12 +20,50 @@ struct xshm_data { xcursor_t *cursor; }; -const char* xshm_input_getname(const char* locale) +static const char* xshm_input_getname(const char* locale) { return "X11 Shared Memory Screen Input"; } -struct xshm_data *xshm_input_create(const char *settings, obs_source_t source) +static void xshm_input_destroy(void *vptr) +{ + XSHM_DATA(vptr); + + if (data) { + gs_entercontext(obs_graphics()); + + texture_destroy(data->texture); + xcursor_destroy(data->cursor); + + gs_leavecontext(); + + // detach xshm + if (data->shm_attached) + XShmDetach(data->dpy, &data->shm_info); + + // detach shared memory + if (data->shm_info.shmaddr != (char *) -1) { + shmdt(data->shm_info.shmaddr); + data->shm_info.shmaddr = (char *) -1; + } + + // remove shared memory + if (data->shm_info.shmid != -1) + shmctl(data->shm_info.shmid, IPC_RMID, NULL); + + // destroy image + if (data->image) + XDestroyImage(data->image); + + // close display + if (data->dpy) + XCloseDisplay(data->dpy); + + bfree(data); + } +} + +static void *xshm_input_create(obs_data_t settings, obs_source_t source) { // create data structure struct xshm_data *data = bmalloc(sizeof(struct xshm_data)); @@ -37,19 +74,19 @@ struct xshm_data *xshm_input_create(const char *settings, obs_source_t source) if (!data->dpy) goto fail; - data->screen = XDefaultScreenOfDisplay(data->dpy); - data->width = WidthOfScreen(data->screen); - data->height = HeightOfScreen(data->screen); - data->root_window = XRootWindowOfScreen(data->screen); - data->visual = DefaultVisualOfScreen(data->screen); - data->depth = DefaultDepthOfScreen(data->screen); + Screen *screen = XDefaultScreenOfDisplay(data->dpy); + data->width = WidthOfScreen(screen); + data->height = HeightOfScreen(screen); + data->root_window = XRootWindowOfScreen(screen); + Visual *visual = DefaultVisualOfScreen(screen); + int depth = DefaultDepthOfScreen(screen); // query for shm extension if (!XShmQueryExtension(data->dpy)) goto fail; // create xshm image - data->image = XShmCreateImage(data->dpy, data->visual, data->depth, + data->image = XShmCreateImage(data->dpy, visual, depth, ZPixmap, NULL, &data->shm_info, data->width, data->height); if (!data->image) @@ -98,70 +135,59 @@ fail: return NULL; } -void xshm_input_destroy(struct xshm_data *data) +static void xshm_input_video_tick(void *vptr, float seconds) { - if (data) { - gs_entercontext(obs_graphics()); - - texture_destroy(data->texture); - xcursor_destroy(data->cursor); - - gs_leavecontext(); - - // detach xshm - if (data->shm_attached) - XShmDetach(data->dpy, &data->shm_info); - - // detach shared memory - if (data->shm_info.shmaddr != (char *) -1) { - shmdt(data->shm_info.shmaddr); - data->shm_info.shmaddr = (char *) -1; - } - - // remove shared memory - if (data->shm_info.shmid != -1) - shmctl(data->shm_info.shmid, IPC_RMID, NULL); - - // destroy image - if (data->image) - XDestroyImage(data->image); - - // close display - if (data->dpy) - XCloseDisplay(data->dpy); - - bfree(data); - } -} - -uint32_t xshm_input_get_output_flags(struct xshm_data *data) -{ - return SOURCE_VIDEO | SOURCE_DEFAULT_EFFECT; -} - -void xshm_input_video_render(struct xshm_data *data, obs_source_t filter_target) -{ - // update texture + XSHM_DATA(vptr); + + gs_entercontext(obs_graphics()); + + // update screen texture XShmGetImage(data->dpy, data->root_window, data->image, 0, 0, AllPlanes); texture_setimage(data->texture, (void *) data->image->data, data->width * 4, False); - effect_t effect = gs_geteffect(); - eparam_t diffuse = effect_getparambyname(effect, "diffuse"); + // update mouse cursor + xcursor_tick(data->cursor); + + gs_leavecontext(); +} +static void xshm_input_video_render(void *vptr, effect_t effect) +{ + XSHM_DATA(vptr); + + eparam_t diffuse = effect_getparambyname(effect, "diffuse"); effect_settexture(effect, diffuse, data->texture); + gs_draw_sprite(data->texture, 0, 0, 0); // render the cursor xcursor_render(data->cursor); } -uint32_t xshm_input_getwidth(struct xshm_data *data) +static uint32_t xshm_input_getwidth(void *vptr) { + XSHM_DATA(vptr); + return texture_getwidth(data->texture); } -uint32_t xshm_input_getheight(struct xshm_data *data) +static uint32_t xshm_input_getheight(void *vptr) { + XSHM_DATA(vptr); + return texture_getheight(data->texture); } + +struct obs_source_info xshm_input = { + .id = "xshm_input", + .type = OBS_SOURCE_TYPE_INPUT, + .output_flags = OBS_SOURCE_VIDEO, + .getname = xshm_input_getname, + .create = xshm_input_create, + .destroy = xshm_input_destroy, + .video_tick = xshm_input_video_tick, + .video_render = xshm_input_video_render, + .getwidth = xshm_input_getwidth, + .getheight = xshm_input_getheight +}; diff --git a/test/linux/xshm-input.h b/test/linux/xshm-input.h deleted file mode 100644 index 9bf19d579..000000000 --- a/test/linux/xshm-input.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -// forward declare struct, so we don't have to include X11 headers here -struct xshm_data; - -EXPORT const char *xshm_input_getname(const char *locale); - -EXPORT struct xshm_data *xshm_input_create(const char *settings, - obs_source_t source); -EXPORT void xshm_input_destroy(struct xshm_data *data); -EXPORT uint32_t xshm_input_get_output_flags(struct xshm_data *data); - -EXPORT void xshm_input_video_render(struct xshm_data *data, - obs_source_t filter_target); - -EXPORT uint32_t xshm_input_getwidth(struct xshm_data *data); -EXPORT uint32_t xshm_input_getheight(struct xshm_data *data); - -#ifdef __cplusplus -} -#endif \ No newline at end of file