mirror of
https://github.com/outbackdingo/UltraGrid.git
synced 2026-03-21 09:40:18 +00:00
Finished compression on Linux
* TODO: figure it out on Mac X OS, add deinterlace shader and maybe other shaders for decoding other codecs (v210 etc.)
This commit is contained in:
@@ -71,7 +71,8 @@
|
||||
*/
|
||||
enum dxt_format {
|
||||
DXT_FORMAT_RGB = 0,
|
||||
DXT_FORMAT_YUV = 1
|
||||
DXT_FORMAT_YUV = 1,
|
||||
DXT_FORMAT_YUV422 = 2
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -150,4 +151,4 @@ dxt_image_destroy(DXT_IMAGE_TYPE* image);
|
||||
int
|
||||
dxt_image_compressed_destroy(unsigned char* image_compressed);
|
||||
|
||||
#endif // DXT_COMMON_H
|
||||
#endif // DXT_COMMON_H
|
||||
|
||||
@@ -51,15 +51,60 @@ struct dxt_encoder
|
||||
// Compressed texture
|
||||
GLuint texture_compressed_id;
|
||||
|
||||
GLuint texture_yuv422;
|
||||
|
||||
// Framebuffer
|
||||
GLuint fbo_id;
|
||||
|
||||
// Program and shader handles
|
||||
GLhandleARB program_compress;
|
||||
GLhandleARB shader_fragment_compress;
|
||||
GLhandleARB shader_vertex_compress;
|
||||
GLhandleARB shader_vertex_compress;
|
||||
|
||||
GLhandleARB yuv422_to_444_program;
|
||||
GLhandleARB yuv422_to_444_fp;
|
||||
GLuint fbo444_id;
|
||||
};
|
||||
|
||||
int dxt_prepare_yuv422_shader(struct dxt_encoder *encoder);
|
||||
|
||||
int dxt_prepare_yuv422_shader(struct dxt_encoder *encoder) {
|
||||
encoder->yuv422_to_444_fp = 0;
|
||||
encoder->yuv422_to_444_fp = dxt_shader_create_from_source(fp_yuv422_to_yuv_444, GL_FRAGMENT_SHADER_ARB);
|
||||
if ( encoder->yuv422_to_444_fp == 0) {
|
||||
printf("Failed to compile YUV422->YUV444 fragment program!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
encoder->yuv422_to_444_program = glCreateProgramObjectARB();
|
||||
glAttachObjectARB(encoder->yuv422_to_444_program, encoder->shader_vertex_compress);
|
||||
glAttachObjectARB(encoder->yuv422_to_444_program, encoder->yuv422_to_444_fp);
|
||||
glLinkProgramARB(encoder->yuv422_to_444_program);
|
||||
|
||||
char log[32768];
|
||||
glGetInfoLogARB(encoder->yuv422_to_444_program, 32768, NULL, (GLchar*)log);
|
||||
if ( strlen(log) > 0 )
|
||||
printf("Link Log: %s\n", log);
|
||||
|
||||
glGenTextures(1, &encoder->texture_yuv422);
|
||||
glBindTexture(GL_TEXTURE_2D, encoder->texture_yuv422);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, encoder->width / 2, encoder->height,
|
||||
0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
||||
|
||||
glUseProgramObjectARB(encoder->yuv422_to_444_program);
|
||||
glUniform1i(glGetUniformLocation(encoder->yuv422_to_444_program, "image"), 0);
|
||||
glUniform2f(glGetUniformLocation(encoder->yuv422_to_444_program, "imageSize"), encoder->width, encoder->height);
|
||||
|
||||
// Create fbo
|
||||
glGenFramebuffersEXT(1, &encoder->fbo444_id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/** Documented at declaration */
|
||||
struct dxt_encoder*
|
||||
dxt_encoder_create(enum dxt_type type, int width, int height, enum dxt_format format)
|
||||
@@ -73,7 +118,7 @@ dxt_encoder_create(enum dxt_type type, int width, int height, enum dxt_format fo
|
||||
encoder->format = format;
|
||||
|
||||
// Create empty data
|
||||
GLubyte * data = NULL;
|
||||
/*GLubyte * data = NULL;
|
||||
int data_size = 0;
|
||||
dxt_encoder_buffer_allocate(encoder, &data, &data_size);
|
||||
// Create empty compressed texture
|
||||
@@ -88,7 +133,7 @@ dxt_encoder_create(enum dxt_type type, int width, int height, enum dxt_format fo
|
||||
else
|
||||
glCompressedTexImage2DARB(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, encoder->width, encoder->height, 0, data_size, data);
|
||||
// Free empty data
|
||||
dxt_encoder_buffer_free(data);
|
||||
dxt_encoder_buffer_free(data);*/
|
||||
|
||||
// Create fbo
|
||||
glGenFramebuffersEXT(1, &encoder->fbo_id);
|
||||
@@ -134,29 +179,43 @@ dxt_encoder_create(enum dxt_type type, int width, int height, enum dxt_format fo
|
||||
glGetInfoLogARB(encoder->program_compress, 32768, NULL, (GLchar*)log);
|
||||
if ( strlen(log) > 0 )
|
||||
printf("Link Log: %s\n", log);
|
||||
|
||||
|
||||
|
||||
glGenTextures(1, &encoder->texture_id);
|
||||
glBindTexture(GL_TEXTURE_2D, encoder->texture_id);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, DXT_IMAGE_GL_FORMAT, encoder->width, encoder->height, 0, GL_RGBA, DXT_IMAGE_GL_TYPE, NULL);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, DXT_IMAGE_GL_FORMAT, encoder->width, encoder->height, 0, GL_RGBA, GL_BYTE, NULL);
|
||||
|
||||
glViewport(0, 0, encoder->width / 4, encoder->height / 4);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
//glActiveTexture(GL_TEXTURE0);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
if(format == DXT_FORMAT_YUV422) {
|
||||
if(!dxt_prepare_yuv422_shader(encoder))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, encoder->texture_id);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glViewport(0, 0, encoder->width / 4, encoder->height / 4);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
// User compress program and set image size parameters
|
||||
glUseProgramObjectARB(encoder->program_compress);
|
||||
glUniform1i(glGetUniformLocation(encoder->program_compress, "imageFormat"), encoder->format);
|
||||
glUniform1i(glGetUniformLocation(encoder->program_compress, "image"), 0);
|
||||
if(format == DXT_FORMAT_YUV422) {
|
||||
glUniform1i(glGetUniformLocation(encoder->program_compress, "imageFormat"), DXT_FORMAT_YUV);
|
||||
} else {
|
||||
glUniform1i(glGetUniformLocation(encoder->program_compress, "imageFormat"), encoder->format);
|
||||
}
|
||||
glUniform2f(glGetUniformLocation(encoder->program_compress, "imageSize"), encoder->width, encoder->height);
|
||||
|
||||
// Render to framebuffer
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, encoder->fbo_id);
|
||||
|
||||
|
||||
return encoder;
|
||||
}
|
||||
|
||||
@@ -187,9 +246,41 @@ int
|
||||
dxt_encoder_compress(struct dxt_encoder* encoder, DXT_IMAGE_TYPE* image, unsigned char* image_compressed)
|
||||
{
|
||||
TIMER_INIT();
|
||||
|
||||
|
||||
TIMER_START();
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, encoder->width, encoder->height, GL_RGBA, DXT_IMAGE_GL_TYPE, image);
|
||||
if(encoder->format == DXT_FORMAT_YUV422) {
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, encoder->fbo444_id);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, encoder->texture_id, 0);
|
||||
//assert(GL_FRAMEBUFFER_COMPLETE_EXT == glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
|
||||
glBindTexture(GL_TEXTURE_2D, encoder->texture_yuv422);
|
||||
|
||||
glPushAttrib(GL_VIEWPORT_BIT);
|
||||
glViewport( 0, 0, encoder->width, encoder->height);
|
||||
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, encoder->width / 2, encoder->height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, image);
|
||||
glUseProgramObjectARB(encoder->yuv422_to_444_program);
|
||||
|
||||
//glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, -1.0);
|
||||
glTexCoord2f(1.0, 0.0); glVertex2f(1.0, -1.0);
|
||||
glTexCoord2f(1.0, 1.0); glVertex2f(1.0, 1.0);
|
||||
glTexCoord2f(0.0, 1.0); glVertex2f(-1.0, 1.0);
|
||||
glEnd();
|
||||
|
||||
glPopAttrib();
|
||||
|
||||
//glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
|
||||
glUseProgramObjectARB(encoder->program_compress);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, encoder->fbo_id);
|
||||
glBindTexture(GL_TEXTURE_2D, encoder->texture_id);
|
||||
|
||||
//gl_check_error();
|
||||
} else {
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, encoder->width, encoder->height, GL_RGBA, DXT_IMAGE_GL_TYPE, image);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
glFinish();
|
||||
#endif
|
||||
|
||||
17
dxt_compress/yuv422_to_yuv444.glsl
Normal file
17
dxt_compress/yuv422_to_yuv444.glsl
Normal file
@@ -0,0 +1,17 @@
|
||||
#version 130
|
||||
|
||||
#extension GL_EXT_gpu_shader4 : enable
|
||||
|
||||
#define lerp mix
|
||||
|
||||
in vec4 TEX0;
|
||||
uniform sampler2D image;
|
||||
uniform vec2 imageSize;
|
||||
out vec4 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
color.rgba = texture(image, TEX0.xy).grba; // store Y0UVY1 ro rgba
|
||||
if(TEX0.x * imageSize.x / 2 - floor(TEX0.x * imageSize.x / 2) > 0.25)
|
||||
color.r = color.a; // use Y1 instead of Y0
|
||||
}
|
||||
@@ -107,7 +107,8 @@ src/video_display/sage_wrapper.o: src/video_display/sage_wrapper.cxx
|
||||
|
||||
../dxt_compress/dxt_glsl.h:../dxt_compress/compress_vp.glsl \
|
||||
../dxt_compress/compress_dxt1_fp.glsl ../dxt_compress/compress_dxt5ycocg_fp.glsl \
|
||||
../dxt_compress/display_fp.glsl ../dxt_compress/display_dxt5ycocg_fp.glsl
|
||||
../dxt_compress/display_fp.glsl ../dxt_compress/display_dxt5ycocg_fp.glsl \
|
||||
../dxt_compress/yuv422_to_yuv444.glsl
|
||||
echo "/**" > $@
|
||||
echo " * GLSL source codes for DXT compressions" >> $@
|
||||
echo " *" >> $@
|
||||
@@ -133,6 +134,10 @@ src/video_display/sage_wrapper.o: src/video_display/sage_wrapper.cxx
|
||||
echo "static const char fp_display_dxt5ycocg[] = " >> $@
|
||||
cat ../dxt_compress/display_dxt5ycocg_fp.glsl | sed 's/\(.*\)/ \"\1\\n\"/' >> $@
|
||||
echo ";" >> $@
|
||||
# yuv 422 to yuv 444 shader
|
||||
echo "static const char fp_yuv422_to_yuv_444[] = " >> $@
|
||||
cat ../dxt_compress/yuv422_to_yuv444.glsl | sed 's/\(.*\)/ \"\1\\n\"/' >> $@
|
||||
echo ";" >> $@
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -203,6 +203,7 @@ if test ! $no_x ; then
|
||||
fi
|
||||
fi
|
||||
X_LIBS+=" -lX11"
|
||||
X_OBJ="src/x11_common.o"
|
||||
CFLAGS+=""
|
||||
HAVE_X11=yes
|
||||
fi
|
||||
@@ -688,7 +689,7 @@ AC_CHECK_HEADER(GL/glx.h, FOUND_GLX_H=yes)
|
||||
AC_CHECK_LIB(GL, glXCreateNewContext, FOUND_GLX_L=yes)
|
||||
|
||||
if test "$HAVE_X11" = yes -a "$FOUND_GLEW_L" = yes -a "$FOUND_GLEW_H" = yes -a "$FOUND_GLX_L" = yes -a "$FOUND_GLX_H" = yes \
|
||||
-a ! expr "$host_os" : ".*darwin.*" > /dev/null # not mac, just for now
|
||||
-a `expr "$host_os" : ".*darwin.*"` -eq 0 # not mac, just for now
|
||||
then
|
||||
LIBS+=" -lGLEW -lGL -lX11"
|
||||
AC_DEFINE([HAVE_DXT_GLSL], [1], [Build with DXT_GLSL support])
|
||||
|
||||
@@ -54,8 +54,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <GL/glew.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glx.h>
|
||||
#include "x11_common.h"
|
||||
|
||||
/*
|
||||
* GLX context creation overtaken from:
|
||||
@@ -66,8 +68,9 @@ struct video_compress {
|
||||
struct dxt_encoder *encoder;
|
||||
|
||||
struct video_frame out;
|
||||
char *decoded, *repacked;
|
||||
char *decoded;
|
||||
unsigned int configured:1;
|
||||
unsigned int interlaced_input:1;
|
||||
};
|
||||
|
||||
static void configure_with(struct video_compress *s, struct video_frame *frame);
|
||||
@@ -338,6 +341,8 @@ static void configure_with(struct video_compress *s, struct video_frame *frame)
|
||||
codec_t tmp = s->out.color_spec;
|
||||
enum dxt_format format;
|
||||
|
||||
assert(frame->width % 4 == 0 && frame->height % 4 == 0);
|
||||
|
||||
glx_init();
|
||||
|
||||
memcpy(&s->out, frame, sizeof(struct video_frame));
|
||||
@@ -358,19 +363,23 @@ static void configure_with(struct video_compress *s, struct video_frame *frame)
|
||||
case Vuy2:
|
||||
case DVS8:
|
||||
s->out.decoder = (decoder_t) memcpy;
|
||||
format = DXT_FORMAT_YUV;
|
||||
format = DXT_FORMAT_YUV422;
|
||||
break;
|
||||
case v210:
|
||||
s->out.decoder = (decoder_t) vc_copylinev210;
|
||||
format = DXT_FORMAT_YUV;
|
||||
format = DXT_FORMAT_YUV422;
|
||||
break;
|
||||
case DVS10:
|
||||
s->out.decoder = (decoder_t) vc_copylineDVS10;
|
||||
format = DXT_FORMAT_YUV;
|
||||
format = DXT_FORMAT_YUV422;
|
||||
break;
|
||||
/*case DXT1:
|
||||
case DXT1:
|
||||
case DXT5:
|
||||
fprintf(stderr, "Input frame is already comperssed!");
|
||||
exit(128);*/
|
||||
exit(128);
|
||||
default:
|
||||
fprintf(stderr, "Unknown codec: %d\n", s->out.color_spec);
|
||||
exit(128);
|
||||
}
|
||||
s->out.src_bpp = get_bpp(s->out.color_spec);
|
||||
s->out.src_linesize = s->out.width * s->out.src_bpp;
|
||||
@@ -378,11 +387,14 @@ static void configure_with(struct video_compress *s, struct video_frame *frame)
|
||||
(format == DXT_FORMAT_RGB ? 4 /*RGBA*/: 2/*YUV 422*/);
|
||||
|
||||
/* We will deinterlace the output frame */
|
||||
if(s->out.aux & AUX_INTERLACED)
|
||||
s->interlaced_input = TRUE;
|
||||
else
|
||||
s->interlaced_input = FALSE;
|
||||
s->out.aux &= ~AUX_INTERLACED;
|
||||
|
||||
s->out.color_spec = tmp;
|
||||
|
||||
|
||||
if(s->out.color_spec == DXT1) {
|
||||
s->encoder = dxt_encoder_create(DXT_TYPE_DXT1, frame->width, frame->height, format);
|
||||
s->out.aux |= AUX_RGB;
|
||||
@@ -393,9 +405,13 @@ static void configure_with(struct video_compress *s, struct video_frame *frame)
|
||||
s->out.data_len = frame->width * frame->height;
|
||||
}
|
||||
|
||||
if(!s->encoder) {
|
||||
fprintf(stderr, "[DXT GLSL] Failed to create encoder.\n");
|
||||
exit(128);
|
||||
}
|
||||
|
||||
s->out.data = (char *) malloc(s->out.data_len);
|
||||
s->decoded = malloc(4 * frame->width * frame->height);
|
||||
s->repacked = malloc(4 * frame->width * frame->height);
|
||||
|
||||
s->configured = TRUE;
|
||||
}
|
||||
@@ -407,7 +423,17 @@ struct video_compress * dxt_glsl_init(char * opts)
|
||||
s = (struct video_compress *) malloc(sizeof(struct video_compress));
|
||||
s->out.data = NULL;
|
||||
s->decoded = NULL;
|
||||
s->repacked = NULL;
|
||||
|
||||
x11_enter_thread();
|
||||
|
||||
if(opts && strcmp(opts, "help") == 0) {
|
||||
printf("DXT GLSL comperssion usage:\n");
|
||||
printf("\t-cg:DXT1\n");
|
||||
printf("\t\tcompress with DXT1\n");
|
||||
printf("\t-cg:DXT5_YCoCg\n");
|
||||
printf("\t\tcompress with DXT5_YCoCg\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(opts) {
|
||||
if(strcasecmp(opts, "DXT5_YCoCg") == 0) {
|
||||
@@ -437,35 +463,22 @@ struct video_frame * dxt_glsl_compress(void *arg, struct video_frame * tx)
|
||||
configure_with(s, tx);
|
||||
|
||||
|
||||
line1 = (unsigned char *)tx->data;
|
||||
line2 = s->decoded;
|
||||
line1 = (unsigned char *) tx->data;
|
||||
line2 = (unsigned char *) s->decoded;
|
||||
|
||||
for (x = 0; x < tx->height; ++x) {
|
||||
for (x = 0; x < (int) tx->height; ++x) {
|
||||
s->out.decoder(line2, line1, s->out.src_linesize,
|
||||
s->out.rshift, s->out.gshift, s->out.bshift);
|
||||
line1 += s->out.src_linesize;
|
||||
line2 += s->out.dst_linesize;
|
||||
}
|
||||
|
||||
if(tx->color_spec == RGBA ||
|
||||
tx->color_spec == R10k) {
|
||||
dxt_encoder_compress(s->encoder, s->decoded, s->out.data);
|
||||
} else {
|
||||
const count = s->out.width * s->out.height;
|
||||
/* Repack the data to YUV 4:4:4 Format */
|
||||
for (x = 0; x < count; x += 2) {
|
||||
s->repacked[4 * x] = s->decoded[2 * x + 1]; //Y1
|
||||
s->repacked[4 * x + 1] = s->decoded[2 * x]; //U1
|
||||
s->repacked[4 * x + 2] = s->decoded[2 * x + 2]; //V1
|
||||
//s->repacked[4 * x + 3] = 255; //Alpha
|
||||
if(s->interlaced_input)
|
||||
vc_deinterlace((unsigned char *) s->decoded, s->out.dst_linesize, tx->height);
|
||||
|
||||
s->repacked[4 * x + 4] = s->decoded[2 * x + 3]; //Y2
|
||||
s->repacked[4 * x + 5] = s->decoded[2 * x]; //U1
|
||||
s->repacked[4 * x + 6] = s->decoded[2 * x + 2]; //V1
|
||||
//s->repacked[4 * x + 7] = 255; //Alpha
|
||||
}
|
||||
dxt_encoder_compress(s->encoder, s->repacked, s->out.data);
|
||||
}
|
||||
dxt_encoder_compress(s->encoder,
|
||||
(unsigned char *) s->decoded,
|
||||
(unsigned char *) s->out.data);
|
||||
|
||||
return &s->out;
|
||||
}
|
||||
|
||||
@@ -164,6 +164,8 @@ static void usage(void)
|
||||
printf("\n");
|
||||
printf("\t-c \tcompress video\n");
|
||||
printf("\n");
|
||||
printf("\t-cg \tcompress video with OpenGL (see -cg:help for more options)\n");
|
||||
printf("\n");
|
||||
printf("\t-i \tiHDTV compatibility mode\n");
|
||||
printf("\n");
|
||||
printf("\taddress(es) \tdestination address\n");
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
#include <GL/glut.h>
|
||||
|
||||
#include "x11_common.h"
|
||||
#ifdef FREEGLUT
|
||||
#include <GL/freeglut_ext.h>
|
||||
#endif /* FREEGLUT */
|
||||
@@ -219,6 +219,10 @@ void gl_check_error()
|
||||
void * display_gl_init(char *fmt, unsigned int flags) {
|
||||
UNUSED(flags);
|
||||
struct state_gl *s;
|
||||
|
||||
#ifndef HAVE_MACOSX
|
||||
x11_enter_thread();
|
||||
#endif
|
||||
|
||||
glutInit(&uv_argc, uv_argv);
|
||||
s = (struct state_gl *) calloc(1,sizeof(struct state_gl));
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
void NSApplicationLoad();
|
||||
#else /* HAVE_MACOSX */
|
||||
#include <sys/io.h>
|
||||
#include "x11_common.h"
|
||||
#endif /* HAVE_MACOSX */
|
||||
#include <sys/time.h>
|
||||
|
||||
@@ -611,6 +612,10 @@ void *display_sdl_init(char *fmt, unsigned int flags)
|
||||
s = (struct state_sdl *)calloc(1, sizeof(struct state_sdl));
|
||||
s->magic = MAGIC_SDL;
|
||||
|
||||
#ifndef HAVE_MACOSX
|
||||
x11_enter_thread();
|
||||
#endif
|
||||
|
||||
if (fmt != NULL) {
|
||||
if (strcmp(fmt, "help") == 0) {
|
||||
show_help();
|
||||
|
||||
58
ultragrid/src/x11_common.c
Normal file
58
ultragrid/src/x11_common.c
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* FILE: x11_common.c
|
||||
* AUTHORS: Martin Benes <martinbenesh@gmail.com>
|
||||
* Lukas Hejtmanek <xhejtman@ics.muni.cz>
|
||||
* Petr Holub <hopet@ics.muni.cz>
|
||||
* Milos Liska <xliska@fi.muni.cz>
|
||||
* Jiri Matela <matela@ics.muni.cz>
|
||||
* Dalibor Matura <255899@mail.muni.cz>
|
||||
* Ian Wesley-Smith <iwsmith@cct.lsu.edu>
|
||||
*
|
||||
* Copyright (c) 2005-2010 CESNET z.s.p.o.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, is permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
*
|
||||
* This product includes software developed by CESNET z.s.p.o.
|
||||
*
|
||||
* 4. Neither the name of the CESNET nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <pthread.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
static pthread_once_t XInitThreadsHasRun = PTHREAD_ONCE_INIT;
|
||||
|
||||
void x11_enter_thread(void)
|
||||
{
|
||||
pthread_once(&XInitThreadsHasRun, XInitThreads);
|
||||
}
|
||||
48
ultragrid/src/x11_common.h
Normal file
48
ultragrid/src/x11_common.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* FILE: x11_common.h
|
||||
* AUTHORS: Martin Benes <martinbenesh@gmail.com>
|
||||
* Lukas Hejtmanek <xhejtman@ics.muni.cz>
|
||||
* Petr Holub <hopet@ics.muni.cz>
|
||||
* Milos Liska <xliska@fi.muni.cz>
|
||||
* Jiri Matela <matela@ics.muni.cz>
|
||||
* Dalibor Matura <255899@mail.muni.cz>
|
||||
* Ian Wesley-Smith <iwsmith@cct.lsu.edu>
|
||||
*
|
||||
* Copyright (c) 2005-2010 CESNET z.s.p.o.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, is permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
*
|
||||
* This product includes software developed by CESNET z.s.p.o.
|
||||
*
|
||||
* 4. Neither the name of the CESNET nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
void x11_enter_thread(void);
|
||||
Reference in New Issue
Block a user