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.
This commit is contained in:
fryshorts 2014-02-10 19:09:44 +01:00
parent 820de55ae2
commit c00d9e3b4e
7 changed files with 119 additions and 131 deletions

View File

@ -10,9 +10,7 @@ set(linux_SOURCES
xshm-input.c
)
set(linux_HEADERS
linux.h
xcursor.h
xshm-input.h
)
add_library(linux MODULE

View File

@ -1,25 +1,11 @@
#include <obs.h>
#include "linux.h"
#include <obs-module.h>
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;
}

View File

@ -1,15 +0,0 @@
#pragma once
#include <util/c99defs.h>
#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

View File

@ -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);
}

View File

@ -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
*

View File

@ -4,15 +4,14 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/XShm.h>
#include <obs.h>
#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
};

View File

@ -1,27 +0,0 @@
#pragma once
#include <obs.h>
#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