summaryrefslogtreecommitdiff
path: root/src/video_out/video_out_opengl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_out/video_out_opengl.c')
-rw-r--r--src/video_out/video_out_opengl.c199
1 files changed, 127 insertions, 72 deletions
diff --git a/src/video_out/video_out_opengl.c b/src/video_out/video_out_opengl.c
index 54696f452..1904fe6af 100644
--- a/src/video_out/video_out_opengl.c
+++ b/src/video_out/video_out_opengl.c
@@ -1,13 +1,13 @@
/*
* Copyright (C) 2000-2003 the xine project
- *
+ *
* This file is part of xine, a free video player.
- *
+ *
* xine is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* xine is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@@ -142,7 +142,7 @@ typedef struct {
uint8_t *chunk[4]; /* mem alloc by xmalloc_aligned */
uint8_t *rgb, *rgb_dst;
-
+
yuv2rgb_t *yuv2rgb; /* yuv2rgb converter set up for this frame */
} opengl_frame_t;
@@ -198,7 +198,7 @@ typedef struct {
PFNMYGLPROGRAMENVPARAMETER4FARBPROC glProgramEnvParameter4fARB;
PFNMYGLGENTEXTURESEXTPROC glGenTexturesEXT;
PFNMYGLBINDTEXTUREEXTPROC glBindTextureEXT;
-
+
int yuv2rgb_brightness;
int yuv2rgb_contrast;
int yuv2rgb_saturation;
@@ -233,7 +233,7 @@ typedef struct {
int (*setup)(opengl_driver_t *);
/* Flag: needs output converted to rgb (is able to do YUV otherwise) */
int needsrgb;
- /* Default action: what to do if there's no new image
+ /* Default action: what to do if there's no new image
* typically either RENDER_NONE or RENDER_DRAW (for animated render's) */
enum render_e defaction;
/* Fallback: change to following render backend if this one doesn't work */
@@ -327,7 +327,7 @@ static void render_cyl (opengl_driver_t *this, opengl_frame_t *frame) {
float off;
float tx, ty;
struct timeval curtime;
-
+
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
/* Calc timing + texture coords */
@@ -341,10 +341,10 @@ static void render_cyl (opengl_driver_t *this, opengl_frame_t *frame) {
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glTranslatef (0, 0, -10);
- glRotatef (off * CYCLE_FACTOR1, 1, 0, 0);
- glRotatef (off, 0, 0, 1);
- glRotatef (off * CYCLE_FACTOR2, 0, 1, 0);
-
+ glRotatef (off * CYCLE_FACTOR1, 1, 0, 0);
+ glRotatef (off, 0, 0, 1);
+ glRotatef (off * CYCLE_FACTOR2, 0, 1, 0);
+
/* Note that this is not aspect ratio corrected */
glBegin (GL_QUADS);
for (i = 0; i < CYL_TESSELATION; i++) {
@@ -363,7 +363,7 @@ static void render_cyl (opengl_driver_t *this, opengl_frame_t *frame) {
}
/* Animated spinning environment mapped torus */
-#define DIST_FACTOR 16.568542 /* 2 * (sqrt(2)-1) * 20 */
+#define DIST_FACTOR 16.568542 /* 2 * (sqrt(2)-1) * 20 */
static void render_env_tor (opengl_driver_t *this, opengl_frame_t *frame) {
float off;
float x1, y1, x2, y2, tx, ty;
@@ -397,7 +397,7 @@ static void render_env_tor (opengl_driver_t *this, opengl_frame_t *frame) {
glLoadIdentity ();
glDepthFunc (GL_ALWAYS);
glDepthMask (GL_FALSE);
-
+
glBegin (GL_QUADS);
glColor3f (1, 1, 1);
glTexCoord2f (tx, 0); glVertex3f (x2, y2, -20);
@@ -405,7 +405,7 @@ static void render_env_tor (opengl_driver_t *this, opengl_frame_t *frame) {
glTexCoord2f (0, ty); glVertex3f (x1, y1, -20);
glTexCoord2f (tx, ty); glVertex3f (x2, y1, -20);
glEnd ();
-
+
glPopMatrix ();
glDepthFunc (GL_LEQUAL);
glDepthMask (GL_TRUE);
@@ -442,7 +442,7 @@ static int render_help_image_tex (opengl_driver_t *this, int new_w, int new_h,
tex_w <<= 1;
while (tex_h < new_h)
tex_h <<= 1;
-
+
if (tex_w != this->tex_width || tex_h != this->tex_height) {
char *tmp = calloc (tex_w * tex_h, 4); /* 4 enough until RGBA */
if (this->glBindTextureEXT)
@@ -458,7 +458,7 @@ static int render_help_image_tex (opengl_driver_t *this, int new_w, int new_h,
this->tex_width = tex_w;
this->tex_height = tex_h;
lprintf ("* new texsize: %dx%d\n", tex_w, tex_h);
- }
+ }
this->last_width = new_w;
this->last_height = new_h;
return 1;
@@ -481,7 +481,7 @@ static int render_help_image_tiledtex (opengl_driver_t *this,
tex_w <<= 1;
while (tex_h < new_h)
tex_h <<= 1;
-
+
if (tex_w != this->tex_width || tex_h != this->tex_height) {
char *tmp = calloc (tex_w * tex_h, 4); /* 4 enough until RGBA */
if (this->glBindTextureEXT)
@@ -521,7 +521,7 @@ static int render_help_image_tiledtex (opengl_driver_t *this,
this->tex_width = tex_w;
this->tex_height = tex_h;
lprintf ("* new texsize: %dx%d on %d tiles\n", tex_w, tex_h, num);
- }
+ }
this->last_width = new_w;
this->last_height = new_h;
return 1;
@@ -669,8 +669,8 @@ static int render_image_envtex (opengl_driver_t *this, opengl_frame_t *frame) {
* Render setup functions
*/
static int render_help_verify_ext (opengl_driver_t *this, char *ext) {
- int ret = 0;
- int l = strlen (ext);
+ int ret = 0;
+ const size_t l = strlen (ext);
const char *e;
for (e = (char *) this->gl_exts; e && *e; e = strchr (e, ' ')) {
while (isspace (*e))
@@ -694,10 +694,9 @@ static void *getdladdr (const GLubyte *_funcName) {
return NULL;
#elif defined(__APPLE__)
- char *temp = xine_xmalloc (strlen (funcName) + 2);
+ char *temp;
+ asprintf(&temp, "_%s", funcName);
void *res = NULL;
- temp[0] = '_'; /* Mac OS X prepends an underscore on function names */
- strcpy (temp+1, funcName);
if (NSIsSymbolNameDefined (temp)) {
NSSymbol symbol = NSLookupAndBindSymbol (temp);
res = NSAddressOfSymbol (symbol);
@@ -711,7 +710,7 @@ static void *getdladdr (const GLubyte *_funcName) {
handle = dlopen (NULL, RTLD_LAZY);
}
return dlsym (handle, funcName);
-
+
#else /* all other Un*xes */
return dlsym (0, funcName);
@@ -884,7 +883,7 @@ static int render_setup_cyl (opengl_driver_t *this) {
static int render_setup_torus (opengl_driver_t *this) {
int i, j, k;
int ret;
-
+
ret = render_setup_3d (this);
ret &= render_help_setup_tex (this);
@@ -938,7 +937,7 @@ static int render_setup_fp_yuv (opengl_driver_t *this) {
"MAD res, { 0, -.391, 2.018 }, tmp.xxxw, res;"
"MAD result.color, { 1.596, -.813, 0 }, tmp.yyyw, res;"
"END";
-
+
ret = render_setup_tex2d (this);
if (! this->has_fragprog)
return 0;
@@ -964,7 +963,7 @@ static int render_setup_fp_yuv (opengl_driver_t *this) {
*/
/* name, display, image, setup, needsrgb, defaction, fallback */
static const opengl_render_t opengl_rb[] = {
- { "2D_Tex_Fragprog", render_tex2d, render_image_fp_yuv,
+ { "2D_Tex_Fragprog", render_tex2d, render_image_fp_yuv,
render_setup_fp_yuv, 0, RENDER_NONE, 1 },
{ "2D_Tex", render_tex2d, render_image_tex,
render_setup_tex2d, 1, RENDER_NONE, 2 },
@@ -1005,10 +1004,10 @@ static void *render_run (opengl_driver_t *this) {
struct timeval curtime;
struct timespec timeout;
const opengl_render_t *render;
-
+
lprintf ("* render thread created\n");
while (1) {
-
+
/* Wait for render action */
pthread_mutex_lock (&this->render_action_mutex);
if (! this->render_action) {
@@ -1212,28 +1211,28 @@ static uint32_t opengl_get_capabilities (vo_driver_t *this_gen) {
static void opengl_frame_proc_slice (vo_frame_t *vo_img, uint8_t **src) {
opengl_frame_t *frame = (opengl_frame_t *) vo_img ;
/* opengl_driver_t *this = (opengl_driver_t *) vo_img->driver; */
-
+
vo_img->proc_called = 1;
if (! frame->rgb_dst)
return;
/* lprintf ("%p: frame_copy src %p=%p to %p\n", frame, src[0], frame->chunk[0], frame->rgb_dst); */
- if( frame->vo_frame.crop_left || frame->vo_frame.crop_top ||
+ if( frame->vo_frame.crop_left || frame->vo_frame.crop_top ||
frame->vo_frame.crop_right || frame->vo_frame.crop_bottom )
{
/* TODO: opengl *could* support this?!? */
/* cropping will be performed by video_out.c */
return;
}
-
+
if (frame->format == XINE_IMGFMT_YV12)
frame->yuv2rgb->yuv2rgb_fun (frame->yuv2rgb, frame->rgb_dst,
src[0], src[1], src[2]);
else
frame->yuv2rgb->yuy22rgb_fun (frame->yuv2rgb, frame->rgb_dst,
src[0]);
-
+
/* lprintf ("frame_copy...done\n"); */
}
@@ -1244,7 +1243,7 @@ static void opengl_frame_field (vo_frame_t *vo_img, int which_field) {
/* lprintf ("%p: frame_field rgb %p which_field %x\n", frame, frame->rgb, which_field); */
if (! opengl_rb[this->render_fun_id].needsrgb) {
- frame->rgb_dst = NULL;
+ frame->rgb_dst = NULL;
return;
}
@@ -1281,7 +1280,7 @@ static vo_frame_t *opengl_alloc_frame (vo_driver_t *this_gen) {
opengl_frame_t *frame;
opengl_driver_t *this = (opengl_driver_t *) this_gen;
- frame = (opengl_frame_t *) xine_xmalloc (sizeof (opengl_frame_t));
+ frame = (opengl_frame_t *) calloc(1, sizeof(opengl_frame_t));
if (!frame)
return NULL;
@@ -1292,7 +1291,7 @@ static vo_frame_t *opengl_alloc_frame (vo_driver_t *this_gen) {
*/
frame->vo_frame.proc_slice = opengl_frame_proc_slice;
frame->vo_frame.proc_frame = NULL;
- frame->vo_frame.field = opengl_frame_field;
+ frame->vo_frame.field = opengl_frame_field;
frame->vo_frame.dispose = opengl_frame_dispose;
frame->vo_frame.driver = this_gen;
@@ -1346,7 +1345,7 @@ static void opengl_update_frame_format (vo_driver_t *this_gen,
/* lprintf ("updating frame to %d x %d (ratio=%g, format=%08x)\n", width, height, ratio, format); */
flags &= VO_BOTH_FIELDS;
-
+
XLockDisplay (this->display);
/* (re-) allocate render space */
@@ -1400,7 +1399,7 @@ static void opengl_update_frame_format (vo_driver_t *this_gen,
frame->height = height;
frame->format = format;
- XUnlockDisplay (this->display);
+ XUnlockDisplay (this->display);
opengl_frame_field ((vo_frame_t *)frame, flags);
}
@@ -1434,7 +1433,7 @@ static void opengl_overlay_clut_yuv2rgb(opengl_driver_t *this, vo_overlay_t *ov
}
}
-static void opengl_overlay_begin (vo_driver_t *this_gen,
+static void opengl_overlay_begin (vo_driver_t *this_gen,
vo_frame_t *frame_gen, int changed) {
opengl_driver_t *this = (opengl_driver_t *) this_gen;
@@ -1442,10 +1441,10 @@ static void opengl_overlay_begin (vo_driver_t *this_gen,
if (this->ovl_changed && this->xoverlay) {
XLockDisplay (this->display);
- x11osd_clear(this->xoverlay);
+ x11osd_clear(this->xoverlay);
XUnlockDisplay (this->display);
}
-
+
this->alphablend_extra_data.offset_x = frame_gen->overlay_offset_x;
this->alphablend_extra_data.offset_y = frame_gen->overlay_offset_y;
}
@@ -1462,7 +1461,7 @@ static void opengl_overlay_end (vo_driver_t *this_gen, vo_frame_t *vo_img) {
this->ovl_changed = 0;
}
-static void opengl_overlay_blend (vo_driver_t *this_gen,
+static void opengl_overlay_blend (vo_driver_t *this_gen,
vo_frame_t *frame_gen, vo_overlay_t *overlay) {
opengl_driver_t *this = (opengl_driver_t *) this_gen;
opengl_frame_t *frame = (opengl_frame_t *) frame_gen;
@@ -1472,7 +1471,7 @@ static void opengl_overlay_blend (vo_driver_t *this_gen,
if (overlay->unscaled) {
if (this->ovl_changed && this->xoverlay) {
XLockDisplay (this->display);
- x11osd_blend (this->xoverlay, overlay);
+ x11osd_blend (this->xoverlay, overlay);
XUnlockDisplay (this->display);
}
} else {
@@ -1513,7 +1512,7 @@ static int opengl_redraw_needed (vo_driver_t *this_gen) {
opengl_compute_ideal_size(this);
- if( _x_vo_scale_redraw_needed( &this->sc ) ) {
+ if( _x_vo_scale_redraw_needed( &this->sc ) ) {
opengl_compute_rgb_size(this);
pthread_mutex_lock (&this->render_action_mutex);
if (this->render_action <= RENDER_CLEAN) {
@@ -1523,10 +1522,10 @@ static int opengl_redraw_needed (vo_driver_t *this_gen) {
pthread_mutex_unlock (&this->render_action_mutex);
ret = 1;
}
- }
+ }
else
ret = 1;
-
+
/* lprintf ("done...redraw_needed: %d\n", ret); */
return ret;
}
@@ -1546,7 +1545,7 @@ static void opengl_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
this->frame[0] = frame;
this->render_frame_changed = 1;
/* lprintf ("video_out_opengl: cur_frame updated to %d\n", frame->vo_frame.id); */
-
+
/*
* let's see if this frame is different in size / aspect
* ratio from the previous one
@@ -1557,7 +1556,7 @@ static void opengl_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
/* lprintf("frame format changed\n"); */
this->sc.force_redraw = 1; /* trigger re-calc of output size */
}
-
+
/*
* tell gui that we are about to display a frame,
* ask for offset and output size
@@ -1593,14 +1592,14 @@ static int opengl_get_property (vo_driver_t *this_gen, int property) {
case VO_PROP_WINDOW_HEIGHT:
return this->sc.gui_height;
default:
- xprintf(this->xine, XINE_VERBOSITY_DEBUG,
+ xprintf(this->xine, XINE_VERBOSITY_DEBUG,
"video_out_opengl: tried to get unsupported property %d\n", property);
}
return 0;
}
-static int opengl_set_property (vo_driver_t *this_gen,
+static int opengl_set_property (vo_driver_t *this_gen,
int property, int value) {
opengl_driver_t *this = (opengl_driver_t *) this_gen;
@@ -1612,7 +1611,7 @@ static int opengl_set_property (vo_driver_t *this_gen,
opengl_compute_ideal_size (this);
this->sc.force_redraw = 1; /* trigger re-calc of output size */
- xprintf(this->xine, XINE_VERBOSITY_DEBUG,
+ xprintf(this->xine, XINE_VERBOSITY_DEBUG,
"video_out_opengl: aspect ratio changed to %s\n", _x_vo_scale_aspect_ratio_name(value));
break;
case VO_PROP_BRIGHTNESS:
@@ -1640,7 +1639,7 @@ static int opengl_set_property (vo_driver_t *this_gen,
this->sc.force_redraw = 1;
break;
default:
- xprintf (this->xine, XINE_VERBOSITY_DEBUG,
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG,
"video_out_opengl: tried to set unsupported property %d\n", property);
}
@@ -1663,7 +1662,7 @@ static void opengl_get_property_min_max (vo_driver_t *this_gen,
}
}
-static int opengl_gui_data_exchange (vo_driver_t *this_gen,
+static int opengl_gui_data_exchange (vo_driver_t *this_gen,
int data_type, void *data) {
opengl_driver_t *this = (opengl_driver_t *) this_gen;
@@ -1678,7 +1677,7 @@ static int opengl_gui_data_exchange (vo_driver_t *this_gen,
/* lprintf ("expose event\n"); */
if (this->frame[0]) {
XExposeEvent * xev = (XExposeEvent *) data;
-
+
if (xev && xev->count == 0) {
pthread_mutex_lock (&this->render_action_mutex);
if (this->render_action <= RENDER_CLEAN) {
@@ -1715,9 +1714,9 @@ static int opengl_gui_data_exchange (vo_driver_t *this_gen,
&this->render_action_mutex);
pthread_mutex_unlock (&this->render_action_mutex);
break;
-
+
case XINE_GUI_SEND_DRAWABLE_CHANGED:
-
+
pthread_mutex_lock (&this->render_action_mutex);
this->render_action = RENDER_RELEASE;
pthread_cond_signal (&this->render_action_cond);
@@ -1745,7 +1744,7 @@ static int opengl_gui_data_exchange (vo_driver_t *this_gen,
if (this->frame[0]) {
x11_rectangle_t *rect = data;
int x1, y1, x2, y2;
-
+
_x_vo_scale_translate_gui2video(&this->sc,
rect->x, rect->y,
&x1, &y1);
@@ -1774,7 +1773,7 @@ static void opengl_dispose (vo_driver_t *this_gen) {
this->render_action = RENDER_EXIT;
pthread_cond_signal (&this->render_action_cond);
pthread_mutex_unlock (&this->render_action_mutex);
- pthread_join (this->render_thread, NULL);
+ pthread_join (this->render_thread, NULL);
pthread_mutex_destroy (&this->render_action_mutex);
pthread_cond_destroy (&this->render_action_cond);
pthread_cond_destroy (&this->render_return_cond);
@@ -1792,7 +1791,7 @@ static void opengl_dispose (vo_driver_t *this_gen) {
}
_x_alphablend_free(&this->alphablend_extra_data);
-
+
free (this);
}
@@ -1819,8 +1818,8 @@ static vo_driver_t *opengl_open_plugin (video_driver_class_t *class_gen, const v
opengl_driver_t *this;
char **render_fun_names;
int i;
-
- this = (opengl_driver_t *) xine_xmalloc (sizeof (opengl_driver_t));
+
+ this = (opengl_driver_t *) calloc(1, sizeof(opengl_driver_t));
if (!this)
return NULL;
@@ -1833,9 +1832,9 @@ static vo_driver_t *opengl_open_plugin (video_driver_class_t *class_gen, const v
this->sc.dest_size_cb = visual->dest_size_cb;
this->sc.user_data = visual->user_data;
this->sc.user_ratio = XINE_VO_ASPECT_AUTO;
-
+
_x_alphablend_init (&this->alphablend_extra_data, class->xine);
-
+
this->drawable = visual->d;
this->gui_width = this->gui_height = -1;
this->last_width = this->last_height = -1;
@@ -1845,7 +1844,7 @@ static vo_driver_t *opengl_open_plugin (video_driver_class_t *class_gen, const v
this->ovl_changed = 0;
this->xine = class->xine;
this->config = config;
-
+
this->vo_driver.get_capabilities = opengl_get_capabilities;
this->vo_driver.alloc_frame = opengl_alloc_frame;
this->vo_driver.update_frame_format = opengl_update_frame_format;
@@ -1863,8 +1862,8 @@ static vo_driver_t *opengl_open_plugin (video_driver_class_t *class_gen, const v
this->yuv2rgb_brightness = 0;
this->yuv2rgb_contrast = 128;
this->yuv2rgb_saturation = 128;
-
- this->yuv2rgb_factory = yuv2rgb_factory_init (YUV_FORMAT, YUV_SWAP_MODE,
+
+ this->yuv2rgb_factory = yuv2rgb_factory_init (YUV_FORMAT, YUV_SWAP_MODE,
NULL);
this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory,
this->yuv2rgb_brightness,
@@ -1876,8 +1875,7 @@ static vo_driver_t *opengl_open_plugin (video_driver_class_t *class_gen, const v
this->drawable, X11OSD_SHAPED);
XUnlockDisplay (this->display);
- render_fun_names = xine_xmalloc ((sizeof(opengl_rb)/sizeof(opengl_render_t)+1)
- * sizeof (const char *));
+ render_fun_names = calloc((sizeof(opengl_rb)/sizeof(opengl_render_t)+1), sizeof(const char*));
for (i = 0; i < sizeof (opengl_rb) / sizeof (opengl_render_t); i++)
render_fun_names[i] = opengl_rb[i].name;
render_fun_names[i] = NULL;
@@ -1917,7 +1915,7 @@ static vo_driver_t *opengl_open_plugin (video_driver_class_t *class_gen, const v
"it also reduces flickering a lot.\n"
"It should not have any performance impact."),
20, NULL, NULL);
-
+
pthread_mutex_init (&this->render_action_mutex, NULL);
pthread_cond_init (&this->render_action_cond, NULL);
pthread_cond_init (&this->render_return_cond, NULL);
@@ -1947,7 +1945,7 @@ static vo_driver_t *opengl_open_plugin (video_driver_class_t *class_gen, const v
xprintf (this->xine, XINE_VERBOSITY_LOG,
"video_out_opengl: default visual not OpenGL capable\n"
" plugin will only work with clients supporting XINE_GUI_SEND_SELECT_VISUAL.\n");
-
+
return &this->vo_driver;
}
@@ -1955,6 +1953,52 @@ static vo_driver_t *opengl_open_plugin (video_driver_class_t *class_gen, const v
* class functions
*/
+static int opengl_verify_direct (x11_visual_t *vis) {
+ int attribs[] = {
+ GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ None
+ };
+ Window root, win;
+ XVisualInfo *visinfo;
+ GLXContext ctx;
+ XSetWindowAttributes xattr;
+ int ret = 0;
+
+ if (!vis || !vis->display ||
+ ! (root = RootWindow (vis->display, vis->screen))) {
+ fprintf (stderr, "[videoout_opengl]: Don't have a root window to verify\n");
+ return 0;
+ }
+ if (! (visinfo = glXChooseVisual (vis->display, vis->screen, attribs)))
+ return 0;
+ if (! (ctx = glXCreateContext (vis->display, visinfo, NULL, 1)))
+ return 0;
+ memset (&xattr, 0, sizeof (xattr));
+ xattr.colormap = XCreateColormap(vis->display, root, visinfo->visual, AllocNone);
+ xattr.event_mask = StructureNotifyMask | ExposureMask;
+ if ( (win = XCreateWindow (vis->display, root, 0, 0, 1, 1, 0, visinfo->depth,
+ InputOutput, visinfo->visual,
+ CWBackPixel | CWBorderPixel | CWColormap | CWEventMask,
+ &xattr))) {
+ if (glXMakeCurrent (vis->display, win, ctx)) {
+ const char *renderer = (const char *) glGetString(GL_RENDERER);
+ if (glXIsDirect (vis->display, ctx) &&
+ ! strstr (renderer, "Software") &&
+ ! strstr (renderer, "Indirect"))
+ ret = 1;
+ glXMakeCurrent (vis->display, None, NULL);
+ }
+ XDestroyWindow (vis->display, win);
+ }
+ glXDestroyContext (vis->display, ctx);
+ XFreeColormap (vis->display, xattr.colormap);
+
+ return ret;
+}
+
static char* opengl_get_identifier (video_driver_class_t *this_gen) {
return "opengl";
}
@@ -1970,7 +2014,18 @@ static void opengl_dispose_class (video_driver_class_t *this_gen) {
}
static void *opengl_init_class (xine_t *xine, void *visual_gen) {
- opengl_class_t *this = (opengl_class_t *) xine_xmalloc (sizeof (opengl_class_t));
+
+ opengl_class_t *this;
+
+ xprintf (xine, XINE_VERBOSITY_LOG,
+ "video_out_opengl: Testing for hardware accelerated direct rendering visual\n");
+ if (! opengl_verify_direct ((x11_visual_t *)visual_gen)) {
+ xprintf (xine, XINE_VERBOSITY_LOG,
+ "video_out_opengl: Didn't find any\n");
+ return NULL;
+ }
+
+ this = (opengl_class_t *) calloc (1, sizeof(opengl_class_t));
this->driver_class.open_plugin = opengl_open_plugin;
this->driver_class.get_identifier = opengl_get_identifier;
@@ -1993,7 +2048,7 @@ static const vo_info_t vo_info_opengl = {
*/
const plugin_info_t xine_plugin_info[] EXPORTED = {
- /* type, API, "name", version, special_info, init_function */
+ /* type, API, "name", version, special_info, init_function */
{ PLUGIN_VIDEO_OUT, 21, "opengl", XINE_VERSION_CODE, &vo_info_opengl, opengl_init_class },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};