summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Bruguier <nicolas.bruguier@supersonicimagine.fr>2008-11-29 14:12:22 +0100
committerNicolas Bruguier <nicolas.bruguier@supersonicimagine.fr>2008-11-29 14:12:22 +0100
commit7158d52edec1c717602ea6843e3378c8fdc7d8d5 (patch)
tree2e10a99fd41db3c0aa3fae893c295bf1e34198e9
parentb69e9cff9325413326e4b04b6c33f245cd6ea933 (diff)
[glitz/glx] Add offscreen pixmap support.
Add offscreen pixmap support, on glitz side it works like pbuffer. You can create an offscreen pixmap from an another drawable with glitz_create_pixmap_drawable and you can bind its contents into surface with glitz_surface_bind_tex_image/glitz_surface_release_tex_image. For now only glx backend implement offscreen pixmap, its allow to create directly an offscreen pixmap or to create from XPixmap. This patch add also glx accessor to get XDrawable, XDisplay and XScreen of glx drawable.
-rw-r--r--src/agl/glitz_agl_context.c10
-rw-r--r--src/agl/glitz_agl_format.c4
-rw-r--r--src/cgl/glitz_cgl_context.m6
-rw-r--r--src/cgl/glitz_cgl_format.m10
-rw-r--r--src/egl/glitz_egl_context.c6
-rw-r--r--src/glitz.h21
-rw-r--r--src/glitz_drawable.c28
-rw-r--r--src/glitz_format.c27
-rw-r--r--src/glitz_gl.h9
-rw-r--r--src/glitz_surface.c91
-rw-r--r--src/glitzint.h24
-rw-r--r--src/glx/Makefile.am3
-rw-r--r--src/glx/glitz-glx.h23
-rw-r--r--src/glx/glitz_glx_context.c11
-rw-r--r--src/glx/glitz_glx_drawable.c356
-rw-r--r--src/glx/glitz_glx_extension.c18
-rw-r--r--src/glx/glitz_glx_format.c86
-rw-r--r--src/glx/glitz_glx_info.c74
-rw-r--r--src/glx/glitz_glx_pixmap.c96
-rw-r--r--src/glx/glitz_glxext.h4
-rw-r--r--src/glx/glitz_glxint.h33
-rw-r--r--src/wgl/glitz_wgl_context.c8
-rw-r--r--src/wgl/glitz_wgl_format.c10
23 files changed, 919 insertions, 39 deletions
diff --git a/src/agl/glitz_agl_context.c b/src/agl/glitz_agl_context.c
index 01708f1..e13fa66 100644
--- a/src/agl/glitz_agl_context.c
+++ b/src/agl/glitz_agl_context.c
@@ -296,6 +296,7 @@ glitz_agl_context_get (glitz_agl_thread_info_t *thread_info,
context->backend.gl = &_glitz_agl_gl_proc_address;
context->backend.create_pbuffer = glitz_agl_create_pbuffer;
+ context->backend.create_pixmap = NULL;
context->backend.destroy = glitz_agl_destroy;
context->backend.push_current = glitz_agl_push_current;
context->backend.pop_current = glitz_agl_pop_current;
@@ -309,10 +310,15 @@ glitz_agl_context_get (glitz_agl_thread_info_t *thread_info,
context->backend.copy_context = _glitz_agl_copy_context;
context->backend.make_current = _glitz_agl_make_current;
context->backend.get_proc_address = _glitz_agl_context_get_proc_address;
-
+
context->backend.draw_buffer = _glitz_drawable_draw_buffer;
context->backend.read_buffer = _glitz_drawable_read_buffer;
-
+
+ context->backend.bind_tex_image = NULL;
+ context->backend.release_tex_image = NULL;
+
+ context->backend.query_drawable = NULL;
+
context->backend.drawable_formats = NULL;
context->backend.n_drawable_formats = 0;
diff --git a/src/agl/glitz_agl_format.c b/src/agl/glitz_agl_format.c
index 0375490..00c4440 100644
--- a/src/agl/glitz_agl_format.c
+++ b/src/agl/glitz_agl_format.c
@@ -246,7 +246,8 @@ glitz_agl_query_formats (glitz_agl_thread_info_t *thread_info)
aglDestroyPixelFormat (pixel_format);
continue;
}
-
+
+ format.d.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN;
aglDescribePixelFormat (pixel_format, AGL_DOUBLEBUFFER, &value);
format.d.doublebuffer = (value)? 1: 0;
@@ -260,6 +261,7 @@ glitz_agl_query_formats (glitz_agl_thread_info_t *thread_info)
format.d.color.alpha_size = (unsigned short) value;
aglDescribePixelFormat (pixel_format, AGL_DEPTH_SIZE, &value);
format.d.depth_size = (unsigned short) value;
+ format.d.depth = (unsigned short) value;
aglDescribePixelFormat (pixel_format, AGL_STENCIL_SIZE, &value);
format.d.stencil_size = (unsigned short) value;
diff --git a/src/cgl/glitz_cgl_context.m b/src/cgl/glitz_cgl_context.m
index d1413b2..783ad17 100644
--- a/src/cgl/glitz_cgl_context.m
+++ b/src/cgl/glitz_cgl_context.m
@@ -293,6 +293,7 @@ glitz_cgl_context_get (glitz_cgl_thread_info_t *thread_info,
context->backend.gl = &_glitz_cgl_gl_proc_address;
context->backend.create_pbuffer = glitz_cgl_create_pbuffer;
+ context->backend.create_pixmap = NULL;
context->backend.destroy = glitz_cgl_destroy;
context->backend.push_current = glitz_cgl_push_current;
context->backend.pop_current = glitz_cgl_pop_current;
@@ -310,6 +311,11 @@ glitz_cgl_context_get (glitz_cgl_thread_info_t *thread_info,
context->backend.draw_buffer = _glitz_drawable_draw_buffer;
context->backend.read_buffer = _glitz_drawable_read_buffer;
+ context->backend.bind_tex_image = NULL;
+ context->backend.release_tex_image = NULL;
+
+ context->backend.query_drawable = NULL;
+
context->backend.drawable_formats = NULL;
context->backend.n_drawable_formats = 0;
diff --git a/src/cgl/glitz_cgl_format.m b/src/cgl/glitz_cgl_format.m
index 0eb5622..cec3f18 100644
--- a/src/cgl/glitz_cgl_format.m
+++ b/src/cgl/glitz_cgl_format.m
@@ -163,10 +163,11 @@ glitz_cgl_query_formats (glitz_cgl_thread_info_t *thread_info)
NSOpenGLPFAAlphaSize, (color_size <= 16) ? 1 : 8,
NSOpenGLPFAColorSize, (color_size <= 16) ? 16 : 32 };
- format.types = GLITZ_DRAWABLE_TYPE_WINDOW_MASK;
- format.d.id = 0;
- format.d.color.fourcc = GLITZ_FOURCC_RGB;
-
+ format.types = GLITZ_DRAWABLE_TYPE_WINDOW_MASK;
+ format.d.id = 0;
+ format.d.color.fourcc = GLITZ_FOURCC_RGB;
+ format.d.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN;
+
n_attribs_list = sizeof (_attribs_list) / sizeof (GLint *);
for (i = 0; i < n_attribs_list; i++) {
@@ -223,6 +224,7 @@ glitz_cgl_query_formats (glitz_cgl_thread_info_t *thread_info)
format.d.color.blue_size = (unsigned short) value / 3;
value = glitz_cgl_describe_format (pixel_format, NSOpenGLPFADepthSize);
format.d.depth_size = (unsigned short) value;
+ format.d.depth = (unsigned short) value;
value = glitz_cgl_describe_format (pixel_format, NSOpenGLPFAStencilSize);
format.d.stencil_size = (unsigned short) value;
diff --git a/src/egl/glitz_egl_context.c b/src/egl/glitz_egl_context.c
index 407b068..d6e2da7 100644
--- a/src/egl/glitz_egl_context.c
+++ b/src/egl/glitz_egl_context.c
@@ -193,6 +193,7 @@ glitz_egl_context_get (glitz_egl_screen_info_t *screen_info,
context->backend.gl = &_glitz_egl_gl_proc_address;
context->backend.create_pbuffer = glitz_egl_create_pbuffer;
+ context->backend.create_pixmap = NULL;
context->backend.destroy = glitz_egl_destroy;
context->backend.push_current = glitz_egl_push_current;
context->backend.pop_current = glitz_egl_pop_current;
@@ -210,6 +211,11 @@ glitz_egl_context_get (glitz_egl_screen_info_t *screen_info,
context->backend.draw_buffer = _glitz_drawable_draw_buffer;
context->backend.read_buffer = _glitz_drawable_read_buffer;
+ context->backend.bind_tex_image = NULL;
+ context->backend.release_tex_image = NULL;
+
+ context->backend.query_drawable = NULL;
+
context->backend.drawable_formats = NULL;
context->backend.n_drawable_formats = 0;
diff --git a/src/glitz.h b/src/glitz.h
index 9947e5f..04f1e5c 100644
--- a/src/glitz.h
+++ b/src/glitz.h
@@ -136,7 +136,7 @@ typedef enum {
#define GLITZ_FEATURE_FRAMEBUFFER_OBJECT_MASK (1L << 16)
#define GLITZ_FEATURE_COPY_SUB_BUFFER_MASK (1L << 17)
#define GLITZ_FEATURE_DIRECT_RENDERING_MASK (1L << 18)
-
+#define GLITZ_FEATURE_TEXTURE_FROM_PIXMAP_MASK (1L << 19)
/* glitz_format.c */
@@ -219,6 +219,11 @@ glitz_find_pbuffer_format (glitz_drawable_t *other,
const glitz_drawable_format_t *templ,
int count);
+glitz_drawable_format_t *
+glitz_find_pixmap_format (glitz_drawable_t *other,
+ unsigned long mask,
+ const glitz_drawable_format_t *templ,
+ int count);
/* glitz_status.c */
@@ -253,6 +258,12 @@ glitz_create_pbuffer_drawable (glitz_drawable_t *other,
unsigned int width,
unsigned int height);
+glitz_drawable_t *
+glitz_create_pixmap_drawable (glitz_drawable_t *other,
+ glitz_drawable_format_t *format,
+ unsigned int width,
+ unsigned int height);
+
void
glitz_drawable_destroy (glitz_drawable_t *drawable);
@@ -399,6 +410,14 @@ glitz_surface_set_clip_region (glitz_surface_t *surface,
glitz_bool_t
glitz_surface_valid_target (glitz_surface_t *surface);
+glitz_bool_t
+glitz_surface_bind_tex_image (glitz_surface_t *surface,
+ glitz_drawable_t* drawable);
+
+glitz_bool_t
+glitz_surface_release_tex_image (glitz_surface_t *surface,
+ glitz_drawable_t* drawable);
+
/* glitz_texture.c */
diff --git a/src/glitz_drawable.c b/src/glitz_drawable.c
index f6ed856..de413b9 100644
--- a/src/glitz_drawable.c
+++ b/src/glitz_drawable.c
@@ -138,6 +138,34 @@ glitz_create_pbuffer_drawable (glitz_drawable_t *other,
}
slim_hidden_def(glitz_create_pbuffer_drawable);
+glitz_drawable_t *
+glitz_create_pixmap_drawable (glitz_drawable_t *other,
+ glitz_drawable_format_t *format,
+ unsigned int width,
+ unsigned int height)
+{
+ glitz_int_drawable_format_t *iformat;
+ glitz_drawable_t *drawable;
+
+ if (!other->backend->create_pixmap)
+ return NULL;
+
+ if (!_glitz_drawable_size_check (other, width, height))
+ return NULL;
+
+ if (format->id >= other->backend->n_drawable_formats)
+ return NULL;
+
+ iformat = &other->backend->drawable_formats[format->id];
+ if (!(iformat->types & GLITZ_DRAWABLE_TYPE_WINDOW_MASK))
+ return NULL;
+
+ drawable = other->backend->create_pixmap (other, format, width, height);
+
+ return drawable;
+}
+slim_hidden_def(glitz_create_pixmap_drawable);
+
void
glitz_drawable_destroy (glitz_drawable_t *drawable)
{
diff --git a/src/glitz_format.c b/src/glitz_format.c
index 029b553..0e4e020 100644
--- a/src/glitz_format.c
+++ b/src/glitz_format.c
@@ -179,10 +179,10 @@ _glitz_add_drawable_formats (glitz_gl_proc_address_list_t *gl,
{
glitz_int_drawable_format_t format;
glitz_drawable_format_t d[] = {
- { 0, { GLITZ_FOURCC_RGB, 8, 8, 8, 0 }, 0, 0, 1, 0 },
- { 0, { GLITZ_FOURCC_RGB, 8, 8, 8, 8 }, 0, 0, 1, 0 },
- { 0, { GLITZ_FOURCC_RGB, 8, 8, 8, 0 }, 24, 8, 1, 1 },
- { 0, { GLITZ_FOURCC_RGB, 8, 8, 8, 8 }, 24, 8, 1, 1 }
+ { 0, { GLITZ_FOURCC_RGB, 8, 8, 8, 0 }, 32, 0, 0, 1, 0, GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN },
+ { 0, { GLITZ_FOURCC_RGB, 8, 8, 8, 8 }, 32, 0, 0, 1, 0, GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN },
+ { 0, { GLITZ_FOURCC_RGB, 8, 8, 8, 0 }, 32, 24, 8, 1, 1, GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN },
+ { 0, { GLITZ_FOURCC_RGB, 8, 8, 8, 8 }, 32, 24, 8, 1, 1, GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN }
};
int i;
@@ -446,3 +446,22 @@ glitz_find_pbuffer_format (glitz_drawable_t *other,
mask, &itempl, count);
}
slim_hidden_def(glitz_find_pbuffer_format);
+
+glitz_drawable_format_t *
+glitz_find_pixmap_format (glitz_drawable_t *other,
+ unsigned long mask,
+ const glitz_drawable_format_t *templ,
+ int count)
+{
+ glitz_int_drawable_format_t itempl;
+
+ glitz_drawable_format_copy (templ, &itempl.d, mask);
+
+ itempl.types = GLITZ_DRAWABLE_TYPE_WINDOW_MASK;
+ mask |= GLITZ_DRAWABLE_TYPE_WINDOW_MASK;
+
+ return glitz_drawable_format_find (other->backend->drawable_formats,
+ other->backend->n_drawable_formats,
+ mask, &itempl, count);
+}
+slim_hidden_def(glitz_find_pixmap_format);
diff --git a/src/glitz_gl.h b/src/glitz_gl.h
index 3036bc6..7bba78d 100644
--- a/src/glitz_gl.h
+++ b/src/glitz_gl.h
@@ -276,6 +276,15 @@ typedef ptrdiff_t glitz_gl_sizeiptr_t;
#define GLITZ_GL_ACTIVE_TEXTURE 0x84E0
#define GLITZ_GL_MAX_TEXTURE_UNITS 0x84E2
+#define GLITZ_GL_TEXTURE_FORMAT_EXT 0x20D5
+#define GLITZ_GL_TEXTURE_TARGET_EXT 0x20D6
+#define GLITZ_GL_MIPMAP_TEXTURE_EXT 0x20D7
+#define GLITZ_GL_TEXTURE_FORMAT_RGB_EXT 0x20D9
+#define GLITZ_GL_TEXTURE_FORMAT_RGBA_EXT 0x20DA
+#define GLITZ_GL_TEXTURE_2D_EXT 0x20DC
+#define GLITZ_GL_TEXTURE_RECTANGLE_EXT 0x20DD
+#define GLITZ_GL_FRONT_LEFT_EXT 0x20DE
+
#define GLITZ_GL_MULTISAMPLE 0x809D
#define GLITZ_GL_MULTISAMPLE_FILTER_HINT 0x8534
diff --git a/src/glitz_surface.c b/src/glitz_surface.c
index 08a0254..0580650 100644
--- a/src/glitz_surface.c
+++ b/src/glitz_surface.c
@@ -1001,3 +1001,94 @@ glitz_surface_set_clip_region (glitz_surface_t *surface,
}
}
slim_hidden_def(glitz_surface_set_clip_region);
+
+glitz_bool_t
+glitz_surface_bind_tex_image(glitz_surface_t *surface,
+ glitz_drawable_t* drawable)
+{
+ glitz_bool_t ret = 0;
+ unsigned int target;
+
+ if (!drawable->backend->query_drawable)
+ return ret;
+
+ if (!drawable->backend->bind_tex_image)
+ return ret;
+
+ GLITZ_GL_SURFACE (surface);
+
+ if (!surface->texture.name)
+ gl->gen_textures (1, &surface->texture.name);
+
+ drawable->backend->query_drawable(drawable, GLITZ_GL_TEXTURE_TARGET_EXT,
+ &target);
+ switch (target)
+ {
+ case GLITZ_GL_TEXTURE_2D_EXT:
+ surface->texture.target = GLITZ_GL_TEXTURE_2D;
+ break;
+ case GLITZ_GL_TEXTURE_RECTANGLE_EXT:
+ surface->texture.target = GLITZ_GL_TEXTURE_RECTANGLE;
+ break;
+ default:
+ return 0;
+ }
+
+ surface->texture.flags |= GLITZ_TEXTURE_FLAG_ALLOCATED_MASK;
+
+ glitz_surface_push_current (surface, GLITZ_DRAWABLE_CURRENT);
+
+ gl->disable (GLITZ_GL_SCISSOR_TEST);
+
+ glitz_texture_bind (gl, &surface->texture);
+
+ gl->tex_parameter_i (surface->texture.target,
+ GLITZ_GL_TEXTURE_MAG_FILTER,
+ surface->texture.param.filter[0]);
+ gl->tex_parameter_i (surface->texture.target,
+ GLITZ_GL_TEXTURE_MIN_FILTER,
+ surface->texture.param.filter[1]);
+
+ ret = drawable->backend->bind_tex_image(drawable);
+
+ glitz_texture_unbind (gl, &surface->texture);
+
+ gl->enable (GLITZ_GL_SCISSOR_TEST);
+
+ glitz_surface_pop_current (surface);
+
+ return ret;
+}
+slim_hidden_def(glitz_surface_bind_tex_image);
+
+glitz_bool_t
+glitz_surface_release_tex_image(glitz_surface_t *surface,
+ glitz_drawable_t* drawable)
+{
+ glitz_bool_t ret = 0;
+
+ if (!drawable->backend->query_drawable)
+ return ret;
+
+ if (!drawable->backend->release_tex_image)
+ return ret;
+
+ GLITZ_GL_SURFACE (surface);
+
+ glitz_surface_push_current (surface, GLITZ_DRAWABLE_CURRENT);
+
+ gl->disable (GLITZ_GL_SCISSOR_TEST);
+
+ glitz_texture_bind (gl, &surface->texture);
+
+ ret = drawable->backend->release_tex_image(drawable);
+
+ gl->enable (GLITZ_GL_SCISSOR_TEST);
+
+ glitz_texture_unbind (gl, &surface->texture);
+
+ glitz_surface_pop_current (surface);
+
+ return ret;
+}
+slim_hidden_def(glitz_surface_release_tex_image);
diff --git a/src/glitzint.h b/src/glitzint.h
index 983ca3c..921de71 100644
--- a/src/glitzint.h
+++ b/src/glitzint.h
@@ -353,6 +353,11 @@ typedef struct _glitz_int_drawable_format_t {
glitz_drawable_format_t d;
unsigned int types;
int caveat;
+ glitz_bool_t y_invert;
+ unsigned short rgb_texture;
+ unsigned short texture_format;
+ unsigned short texture_target;
+ unsigned short mipmap;
union {
void *ptr;
long val;
@@ -368,6 +373,12 @@ typedef struct glitz_backend {
unsigned int width,
unsigned int height);
+ glitz_drawable_t *
+ (*create_pixmap) (void *drawable,
+ glitz_drawable_format_t *format,
+ unsigned int width,
+ unsigned int height);
+
void
(*destroy) (void *drawable);
@@ -422,6 +433,15 @@ typedef struct glitz_backend {
(*read_buffer) (void *drawable,
const glitz_gl_enum_t buffer);
+ glitz_bool_t
+ (*bind_tex_image) (void *drawable);
+
+ glitz_bool_t
+ (*release_tex_image) (void *drawable);
+
+ void
+ (*query_drawable) (void *drawable, int query, unsigned int* value);
+
glitz_function_pointer_t
(*get_proc_address) (void *context,
const char *name);
@@ -1068,8 +1088,10 @@ typedef glitz_fixed_16_16 glitz_fixed;
slim_hidden_proto(glitz_find_drawable_format)
slim_hidden_proto(glitz_find_pbuffer_format)
+slim_hidden_proto(glitz_find_pixmap_format)
slim_hidden_proto(glitz_create_drawable)
slim_hidden_proto(glitz_create_pbuffer_drawable)
+slim_hidden_proto(glitz_create_pixmap_drawable)
slim_hidden_proto(glitz_drawable_get_width)
slim_hidden_proto(glitz_drawable_get_height)
slim_hidden_proto(glitz_drawable_swap_buffers)
@@ -1092,6 +1114,8 @@ slim_hidden_proto(glitz_surface_get_drawable)
slim_hidden_proto(glitz_surface_get_attached_drawable)
slim_hidden_proto(glitz_surface_translate_point)
slim_hidden_proto(glitz_surface_set_clip_region)
+slim_hidden_proto(glitz_surface_bind_tex_image)
+slim_hidden_proto(glitz_surface_release_tex_image)
slim_hidden_proto(glitz_set_rectangle)
slim_hidden_proto(glitz_set_rectangles)
slim_hidden_proto(glitz_set_geometry)
diff --git a/src/glx/Makefile.am b/src/glx/Makefile.am
index f3fcf17..360e819 100644
--- a/src/glx/Makefile.am
+++ b/src/glx/Makefile.am
@@ -17,7 +17,8 @@ libglitz_glx_la_SOURCES = \
glitz_glx_context.c \
glitz_glx_pbuffer.c \
glitz_glxext.h \
- glitz_glxint.h
+ glitz_glxint.h \
+ glitz_glx_pixmap.c
libglitz_glx_la_LDFLAGS = -version-info @VERSION_INFO@ -no-undefined
libglitz_glx_la_LIBADD = $(GLITZ_LIB) $(GLX_LIBS)
diff --git a/src/glx/glitz-glx.h b/src/glx/glitz-glx.h
index adab13b..baf378e 100644
--- a/src/glx/glitz-glx.h
+++ b/src/glx/glitz-glx.h
@@ -74,6 +74,14 @@ glitz_glx_get_visual_info_from_format (Display *display,
int screen,
glitz_drawable_format_t *format);
+Display*
+glitz_glx_get_display_from_drawable (glitz_drawable_t* drawable);
+
+int
+glitz_glx_get_screen_from_drawable (glitz_drawable_t* drawable);
+
+Drawable
+glitz_glx_get_drawable_from_drawable (glitz_drawable_t* drawable);
/* glitz_glx_drawable.c */
@@ -86,6 +94,21 @@ glitz_glx_create_drawable_for_window (Display *display,
unsigned int height);
glitz_drawable_t *
+glitz_glx_create_drawable_for_pixmap (Display *display,
+ int screen,
+ glitz_drawable_format_t *format,
+ Pixmap pixmap,
+ unsigned int width,
+ unsigned int height);
+
+glitz_drawable_t *
+glitz_glx_create_pixmap_drawable (Display *display,
+ int screen,
+ glitz_drawable_format_t *format,
+ unsigned int width,
+ unsigned int height);
+
+glitz_drawable_t *
glitz_glx_create_pbuffer_drawable (Display *display,
int screen,
glitz_drawable_format_t *format,
diff --git a/src/glx/glitz_glx_context.c b/src/glx/glitz_glx_context.c
index 7fb2344..3c32576 100644
--- a/src/glx/glitz_glx_context.c
+++ b/src/glx/glitz_glx_context.c
@@ -279,6 +279,7 @@ glitz_glx_context_get (glitz_glx_screen_info_t *screen_info,
context->backend.gl = &_glitz_glx_gl_proc_address;
context->backend.create_pbuffer = glitz_glx_create_pbuffer;
+ context->backend.create_pixmap = glitz_glx_create_pixmap;
context->backend.destroy = glitz_glx_destroy;
context->backend.push_current = glitz_glx_push_current;
context->backend.pop_current = glitz_glx_pop_current;
@@ -295,7 +296,12 @@ glitz_glx_context_get (glitz_glx_screen_info_t *screen_info,
context->backend.draw_buffer = _glitz_drawable_draw_buffer;
context->backend.read_buffer = _glitz_drawable_read_buffer;
-
+
+ context->backend.bind_tex_image = glitz_glx_bind_tex_image;
+ context->backend.release_tex_image = glitz_glx_release_tex_image;
+
+ context->backend.query_drawable = glitz_glx_query_drawable;
+
context->backend.drawable_formats = NULL;
context->backend.n_drawable_formats = 0;
@@ -377,6 +383,9 @@ _glitz_glx_context_initialize (glitz_glx_screen_info_t *screen_info,
if (glXIsDirect (screen_info->display_info->display, context->context))
context->backend.feature_mask |= GLITZ_FEATURE_DIRECT_RENDERING_MASK;
+ if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_TEXTURE_FROM_PIXMAP_MASK)
+ context->backend.feature_mask |= GLITZ_FEATURE_TEXTURE_FROM_PIXMAP_MASK;
+
context->initialized = 1;
}
diff --git a/src/glx/glitz_glx_drawable.c b/src/glx/glitz_glx_drawable.c
index 02dd6e8..7affba7 100644
--- a/src/glx/glitz_glx_drawable.c
+++ b/src/glx/glitz_glx_drawable.c
@@ -35,6 +35,8 @@ _glitz_glx_create_drawable (glitz_glx_screen_info_t *screen_info,
glitz_drawable_format_t *format,
GLXDrawable glx_drawable,
GLXPbuffer glx_pbuffer,
+ GLXPixmap glx_pixmap,
+ glitz_bool_t owned,
int width,
int height)
{
@@ -48,6 +50,8 @@ _glitz_glx_create_drawable (glitz_glx_screen_info_t *screen_info,
drawable->context = context;
drawable->drawable = glx_drawable;
drawable->pbuffer = glx_pbuffer;
+ drawable->pixmap = glx_pixmap;
+ drawable->owned = owned;
drawable->width = width;
drawable->height = height;
@@ -91,14 +95,76 @@ _glitz_glx_drawable_update_size (glitz_glx_drawable_t *drawable,
if (!drawable->pbuffer)
return 0;
}
-
+
+ if (drawable->pixmap)
+ {
+ if (glXGetCurrentDrawable () == drawable->drawable)
+ glXMakeCurrent (drawable->screen_info->display_info->display,
+ None, NULL);
+
+ glitz_glx_release_tex_image(drawable);
+ glitz_glx_pixmap_destroy(drawable->screen_info, drawable->drawable);
+
+ if (drawable->owned)
+ {
+ Display* display = drawable->screen_info->display_info->display;
+ int screen = drawable->screen_info->screen;
+ XVisualInfo* vinfo;
+
+ XFreePixmap(drawable->screen_info->display_info->display,
+ drawable->pixmap);
+ vinfo = glitz_glx_get_visual_info_from_format (display, screen,
+ &drawable->base.format->d);
+ drawable->pixmap = XCreatePixmap (display, RootWindow(display, screen),
+ width, height, vinfo->depth);
+ }
+ drawable->drawable = glitz_glx_pixmap_create (drawable->screen_info,
+ drawable->pixmap,
+ &drawable->base.format->d,
+ width, height);
+ }
+
drawable->width = width;
drawable->height = height;
-
+
return 1;
}
static glitz_drawable_t *
+_glitz_glx_create_pixmap_drawable (glitz_glx_screen_info_t *screen_info,
+ glitz_drawable_format_t *format,
+ Pixmap pixmap,
+ glitz_bool_t owned,
+ unsigned int width,
+ unsigned int height)
+{
+ glitz_glx_drawable_t *drawable;
+ glitz_glx_context_t *context;
+ GLXPixmap glx_pixmap;
+
+ context = glitz_glx_context_get (screen_info, format);
+ if (!context)
+ return NULL;
+
+ glx_pixmap = glitz_glx_pixmap_create(screen_info, pixmap, format, width, height);
+ if (!glx_pixmap)
+ return NULL;
+
+ drawable = _glitz_glx_create_drawable (screen_info, context, format,
+ glx_pixmap, (GLXPbuffer) 0,
+ pixmap, owned,
+ width, height);
+
+ if (!drawable)
+ {
+ glitz_glx_pixmap_destroy (screen_info, glx_pixmap);
+ return NULL;
+ }
+
+ return &drawable->base;
+}
+
+static glitz_drawable_t *
_glitz_glx_create_pbuffer_drawable (glitz_glx_screen_info_t *screen_info,
glitz_drawable_format_t *format,
unsigned int width,
@@ -118,8 +184,8 @@ _glitz_glx_create_pbuffer_drawable (glitz_glx_screen_info_t *screen_info,
return NULL;
drawable = _glitz_glx_create_drawable (screen_info, context, format,
- pbuffer, pbuffer,
- width, height);
+ pbuffer, pbuffer, (GLXPixmap) 0,
+ None, width, height);
if (!drawable) {
glitz_glx_pbuffer_destroy (screen_info, pbuffer);
return NULL;
@@ -129,6 +195,34 @@ _glitz_glx_create_pbuffer_drawable (glitz_glx_screen_info_t *screen_info,
}
glitz_drawable_t *
+glitz_glx_create_pixmap (void *abstract_templ,
+ glitz_drawable_format_t *format,
+ unsigned int width,
+ unsigned int height)
+{
+ glitz_glx_screen_info_t *templ = (glitz_glx_screen_info_t *) abstract_templ;
+ glitz_drawable_t *drawable;
+ Display *display = templ->display_info->display;
+ int screen = templ->screen;
+ Pixmap pixmap;
+
+ pixmap = XCreatePixmap (display, RootWindow(display, screen),
+ width, height, format->depth);
+ if (!pixmap)
+ return NULL;
+
+ drawable = _glitz_glx_create_pixmap_drawable (templ, format,
+ pixmap, 1, width, height);
+ if (!drawable)
+ {
+ XFreePixmap (display, pixmap);
+ return NULL;
+ }
+
+ return drawable;
+}
+
+glitz_drawable_t *
glitz_glx_create_pbuffer (void *abstract_templ,
glitz_drawable_format_t *format,
unsigned int width,
@@ -140,6 +234,24 @@ glitz_glx_create_pbuffer (void *abstract_templ,
width, height);
}
+/**
+ * glitz_glx_create_drawable_for_window:
+ * @display: an X Display
+ * @screen: X Screen number associated with @window
+ * @format: format to use for drawing to @window. The format must be set by
+ * glitz_glx_find_window_format () or
+ * glitz_glx_find_drawable_format_for_visual () before call this
+ * function.
+ * @window: a X Xindow or a X Pixmap
+ * @width: the current width of @window
+ * @height: the current height of @window
+ *
+ * Create a glitz drawable that draws to the given window.
+ *
+ * Return value: the newly glitz drawable. The caller owns the drawable and
+ * should call glitz_drawable_destroy() when done with it. The
+ * function return nil if fail.
+ **/
glitz_drawable_t *
glitz_glx_create_drawable_for_window (Display *display,
int screen,
@@ -169,8 +281,8 @@ glitz_glx_create_drawable_for_window (Display *display,
return NULL;
drawable = _glitz_glx_create_drawable (screen_info, context, format,
- window, (GLXPbuffer) 0,
- width, height);
+ window, (GLXPbuffer) 0, (GLXPixmap)0,
+ None, width, height);
if (!drawable)
return NULL;
@@ -178,6 +290,65 @@ glitz_glx_create_drawable_for_window (Display *display,
}
slim_hidden_def(glitz_glx_create_drawable_for_window);
+/**
+ * glitz_glx_create_drawable_for_pixmap:
+ * @display: an X Display
+ * @screen: X Screen number associated with @pixmap
+ * @format: format to use for drawing to @pixmap. The format must be set by
+ * glitz_glx_find_window_format () or
+ * glitz_glx_find_drawable_format_for_visual () before call this
+ * function.
+ * @pixmap: a X Pixmap
+ * @width: the current width of @pixmap
+ * @height: the current height of @pixmap
+ *
+ * Create a glitz drawable that draws to the given pixmap. The main difference
+ * with glitz_glx_create_drawable_for_window () is this function associate a
+ * OpenGL offscreen pixmap with @pixmap which provide a shared drawing between
+ * the OpenGL offscreen pixmap and @pixmap.
+ *
+ * Return value: the newly glitz drawable. The caller owns the drawable and
+ * should call glitz_drawable_destroy() when done with it. The
+ * function return nil if fail.
+ **/
+glitz_drawable_t *
+glitz_glx_create_drawable_for_pixmap (Display *display,
+ int screen,
+ glitz_drawable_format_t *format,
+ Pixmap pixmap,
+ unsigned int width,
+ unsigned int height)
+{
+ glitz_glx_screen_info_t *screen_info;
+
+ screen_info = glitz_glx_screen_info_get (display, screen);
+ if (!screen_info)
+ return NULL;
+
+ if (format->id >= screen_info->n_formats)
+ return NULL;
+
+ return _glitz_glx_create_pixmap_drawable (screen_info, format, pixmap, 0,
+ width, height);
+}
+slim_hidden_def(glitz_glx_create_drawable_for_pixmap);
+
+/**
+ * glitz_glx_create_pbuffer_drawable:
+ * @display: an X Display
+ * @screen: X Screen number
+ * @format: format to use for drawing to pixel buffer object. The format must be
+ * set by glitz_glx_find_pbuffer_format () before call this function.
+ * @width: the width of pixel buffer object.
+ * @height: the height of pixel buffer object.
+ *
+ * Create an offscreen pixel buffer object and create a glitz drawable that
+ * draws onto it.
+ *
+ * Return value: the newly glitz drawable. The caller owns the drawable and
+ * should call glitz_drawable_destroy() when done with it. The
+ * function return nil if fail.
+ **/
glitz_drawable_t *
glitz_glx_create_pbuffer_drawable (Display *display,
int screen,
@@ -204,6 +375,116 @@ glitz_glx_create_pbuffer_drawable (Display *display,
}
slim_hidden_def(glitz_glx_create_pbuffer_drawable);
+/**
+ * glitz_glx_create_pixmap_drawable:
+ * @display: an X Display
+ * @screen: X Screen number
+ * @format: format to use for drawing to pixmap. The format must be set by
+ * glitz_glx_find_window_format () or
+ * glitz_glx_find_drawable_format_for_visual () before call this
+ * function.
+ * @width: the width of pixmap.
+ * @height: the height of pixmap.
+ *
+ * Create an offscreen OpenGL pixmap and create a glitz drawable that
+ * draws onto it. The X Pixmap associated to the OpenGL pixmap can be recover
+ * with glitz_glx_get_xdrawable (). This function is similar than
+ * glitz_glx_create_drawable_for_pixmap () except that this function create the
+ * X Pixmap associated at OpenGL offscreen pixmap.
+ *
+ * Return value: the newly glitz drawable. The caller owns the drawable and
+ * should call glitz_drawable_destroy() when done with it. The
+ * function return nil if fail.
+ **/
+glitz_drawable_t *
+glitz_glx_create_pixmap_drawable (Display *display,
+ int screen,
+ glitz_drawable_format_t *format,
+ unsigned int width,
+ unsigned int height)
+{
+ glitz_drawable_t *drawable;
+ glitz_glx_screen_info_t *screen_info;
+
+ screen_info = glitz_glx_screen_info_get (display, screen);
+ if (!screen_info)
+ return NULL;
+
+ if (format->id >= screen_info->n_formats)
+ return NULL;
+
+ drawable = glitz_glx_create_pixmap (screen_info, format, width, height);
+
+ return drawable;
+}
+slim_hidden_def(glitz_glx_create_pixmap_drawable);
+
+/**
+ * glitz_glx_get_display_from_drawable:
+ * @drawable: a glitz drawable
+ *
+ * Get the X Display for the underlying X Drawable.
+ *
+ * Return value: the display. The function return NULL if fail.
+ **/
+Display*
+glitz_glx_get_display_from_drawable(glitz_drawable_t* drawable)
+{
+ glitz_glx_drawable_t *glx_drawable = (glitz_glx_drawable_t *)drawable;
+
+ if (!glx_drawable)
+ return NULL;
+
+ return glx_drawable->screen_info->display_info->display;
+}
+slim_hidden_def(glitz_glx_get_display_from_drawable);
+
+/**
+ * glitz_glx_get_screen_from_drawable:
+ * @drawable: a glitz drawable
+ *
+ * Get the X Screen number for the underlying X Drawable.
+ *
+ * Return value: the screen number. The function return -1 if fail.
+ **/
+int
+glitz_glx_get_screen_from_drawable(glitz_drawable_t* drawable)
+{
+ glitz_glx_drawable_t *glx_drawable = (glitz_glx_drawable_t *)drawable;
+
+ if (!glx_drawable)
+ return -1;
+
+ return glx_drawable->screen_info->screen;
+}
+slim_hidden_def(glitz_glx_get_screen_from_drawable);
+
+/**
+ * glitz_glx_get_drawable_from_drawable:
+ * @drawable: a glitz drawable
+ *
+ * Get the underlying X Drawable assiocated to the glitz drawable.
+ *
+ * Return value: the drawable. The function return None if fail.
+ **/
+Drawable
+glitz_glx_get_drawable_from_drawable(glitz_drawable_t* drawable)
+{
+ glitz_glx_drawable_t *glx_drawable = (glitz_glx_drawable_t *)drawable;
+ Drawable xdrawable = None;
+
+ if (glx_drawable->pbuffer)
+ return None;
+
+ if (glx_drawable->pixmap)
+ xdrawable = (Drawable)glx_drawable->pixmap;
+ else
+ xdrawable = (Drawable)glx_drawable->drawable;
+
+ return xdrawable;
+}
+slim_hidden_def(glitz_glx_get_drawable_from_drawable);
+
void
glitz_glx_destroy (void *abstract_drawable)
{
@@ -227,7 +508,16 @@ glitz_glx_destroy (void *abstract_drawable)
if (glXGetCurrentDrawable () == drawable->drawable)
glXMakeCurrent (drawable->screen_info->display_info->display,
None, NULL);
-
+
+ if (drawable->pixmap)
+ {
+ glitz_glx_release_tex_image(drawable);
+ glitz_glx_pixmap_destroy(drawable->screen_info, drawable->drawable);
+ if (drawable->owned)
+ XFreePixmap(drawable->screen_info->display_info->display,
+ drawable->pixmap);
+ }
+
if (drawable->pbuffer)
glitz_glx_pbuffer_destroy (drawable->screen_info, drawable->pbuffer);
@@ -267,3 +557,55 @@ glitz_glx_copy_sub_buffer (void *abstract_drawable,
return 0;
}
+
+glitz_bool_t
+glitz_glx_bind_tex_image (void *abstract_drawable)
+{
+ glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *)
+ abstract_drawable;
+ glitz_glx_screen_info_t *screen_info = drawable->screen_info;
+
+ if (!(screen_info->glx_feature_mask &
+ GLITZ_GLX_FEATURE_TEXTURE_FROM_PIXMAP_MASK))
+ return 0;
+
+ if (!drawable->pixmap)
+ return 0;
+
+ screen_info->glx.bind_tex_image (screen_info->display_info->display,
+ drawable->drawable,
+ GLITZ_GL_FRONT_LEFT_EXT, NULL);
+
+ return 1;
+}
+
+glitz_bool_t
+glitz_glx_release_tex_image (void *abstract_drawable)
+{
+ glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *)
+ abstract_drawable;
+ glitz_glx_screen_info_t *screen_info = drawable->screen_info;
+
+ if (!(screen_info->glx_feature_mask &
+ GLITZ_GLX_FEATURE_TEXTURE_FROM_PIXMAP_MASK))
+ return 0;
+
+ if (drawable->pixmap)
+ screen_info->glx.release_tex_image (screen_info->display_info->display,
+ drawable->drawable,
+ GLITZ_GL_FRONT_LEFT_EXT);
+
+ return 1;
+}
+
+void
+glitz_glx_query_drawable(void *abstract_drawable, int query,
+ unsigned int* value)
+{
+ glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *)
+ abstract_drawable;
+ glitz_glx_screen_info_t *screen_info = drawable->screen_info;
+
+ screen_info->glx.query_drawable (screen_info->display_info->display,
+ drawable->drawable, query, value);
+}
diff --git a/src/glx/glitz_glx_extension.c b/src/glx/glitz_glx_extension.c
index d741d12..8fe494a 100644
--- a/src/glx/glitz_glx_extension.c
+++ b/src/glx/glitz_glx_extension.c
@@ -42,6 +42,13 @@ static glitz_extension_map glx_extensions[] = {
/* XXX: only checking for client side support right now */
static glitz_extension_map glx_client_extensions[] = {
{ 0.0, "GLX_MESA_copy_sub_buffer", GLITZ_GLX_FEATURE_COPY_SUB_BUFFER_MASK },
+ { 0.0, "GLX_EXT_texture_from_pixmap", GLITZ_GLX_FEATURE_TEXTURE_FROM_PIXMAP_MASK },
+ { 0.0, NULL, 0 }
+};
+
+/* XXX: only checking for client side support right now */
+static glitz_extension_map glx_server_extensions[] = {
+ { 0.0, "GLX_EXT_texture_from_pixmap", GLITZ_GLX_FEATURE_TEXTURE_FROM_PIXMAP_MASK },
{ 0.0, NULL, 0 }
};
@@ -51,6 +58,7 @@ glitz_glx_query_extensions (glitz_glx_screen_info_t *screen_info,
{
const char *glx_extensions_string;
const char *glx_client_extensions_string;
+ const char *glx_server_extensions_string;
const char *vendor;
glx_extensions_string =
@@ -61,6 +69,11 @@ glitz_glx_query_extensions (glitz_glx_screen_info_t *screen_info,
glXGetClientString (screen_info->display_info->display,
GLX_EXTENSIONS);
+ glx_server_extensions_string =
+ glXQueryServerString (screen_info->display_info->display,
+ screen_info->screen,
+ GLX_EXTENSIONS);
+
vendor = glXGetClientString (screen_info->display_info->display,
GLX_VENDOR);
@@ -84,6 +97,11 @@ glitz_glx_query_extensions (glitz_glx_screen_info_t *screen_info,
glx_client_extensions_string,
glx_client_extensions);
+ screen_info->glx_feature_mask |=
+ glitz_extensions_query (glx_version,
+ glx_server_extensions_string,
+ glx_server_extensions);
+
if (vendor)
{
if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_MULTISAMPLE_MASK)
diff --git a/src/glx/glitz_glx_format.c b/src/glx/glitz_glx_format.c
index a179ee8..326d0b6 100644
--- a/src/glx/glitz_glx_format.c
+++ b/src/glx/glitz_glx_format.c
@@ -68,7 +68,7 @@ _glitz_glx_format_compare (const void *elem1,
score[i] += 5;
if (format[i]->d.depth_size)
- score[i] -= 5;
+ score[i] -= 10;
if (format[i]->d.doublebuffer)
score[i] -= 10;
@@ -125,7 +125,8 @@ _glitz_glx_query_formats (glitz_glx_screen_info_t *screen_info)
format.types = GLITZ_DRAWABLE_TYPE_WINDOW_MASK;
format.d.id = 0;
format.d.color.fourcc = GLITZ_FOURCC_RGB;
-
+ format.rgb_texture = 0;
+
for (i = 0; i < num_visuals; i++)
{
int value;
@@ -262,11 +263,38 @@ _glitz_glx_query_formats_using_fbconfigs (glitz_glx_screen_info_t *screen_info)
format.d.id = 0;
format.d.color.fourcc = GLITZ_FOURCC_RGB;
-
+ format.rgb_texture = 0;
+
glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_FBCONFIG_ID,
&value);
format.u.uval = value;
+ glx->get_fbconfig_attrib (display, fbconfigs[i],
+ GLX_BIND_TO_TEXTURE_RGBA_EXT, &value);
+ if (value)
+ {
+ format.texture_format = GLITZ_GL_TEXTURE_FORMAT_RGBA_EXT;
+ format.rgb_texture = 1;
+ }
+ else
+ {
+ glx->get_fbconfig_attrib (display, fbconfigs[i],
+ GLX_BIND_TO_TEXTURE_RGB_EXT, &value);
+ if (value)
+ {
+ format.texture_format = GLITZ_GL_TEXTURE_FORMAT_RGB_EXT;
+ format.rgb_texture = 1;
+ }
+ }
+
+ glx->get_fbconfig_attrib (display, fbconfigs[i],
+ GLX_BIND_TO_TEXTURE_TARGETS_EXT, &value);
+ format.texture_target = value;
+
+ glx->get_fbconfig_attrib (display, fbconfigs[i],
+ GLX_BIND_TO_MIPMAP_TEXTURE_EXT, &value);
+ format.mipmap = value;
+
glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_RED_SIZE, &value);
format.d.color.red_size = (unsigned short) value;
glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_GREEN_SIZE,
@@ -357,6 +385,21 @@ glitz_glx_query_formats (glitz_glx_screen_info_t *screen_info)
screen_info->formats[i].d.id = i;
}
+/**
+ * glitz_glx_find_window_format:
+ * @display: an X Display
+ * @screen: X Screen number where the window will be displayed
+ * @mask: Format mask value
+ * @templ: Format template which is be used in matching the drawable format
+ * @count: Index number of found matching drawable format
+ *
+ * This function return the drawable format for a window or a pixmap that best
+ * meets template format. The sort order of founds format follow GLX 1.3
+ * specification, you can safely choose the first format found (0).
+ *
+ * Return value: The @count index format drawable which matches template or nil
+ * if no format matches.
+ **/
glitz_drawable_format_t *
glitz_glx_find_window_format (Display *display,
int screen,
@@ -379,6 +422,21 @@ glitz_glx_find_window_format (Display *display,
}
slim_hidden_def(glitz_glx_find_window_format);
+/**
+ * glitz_glx_find_pbuffer_format:
+ * @display: an X Display
+ * @screen: X Screen number where the window will be displayed
+ * @mask: Format mask value
+ * @templ: Format template which is be used in matching the drawable format
+ * @count: Index number of found matching drawable format
+ *
+ * This function return the drawable format for a pixel buffer object that best
+ * meets template format. The sort order of founds format follow GLX 1.3
+ * specification, you can safely choose the first format found (0).
+ *
+ * Return value: The @count index format drawable which matches template or nil
+ * if no format matches.
+ **/
glitz_drawable_format_t *
glitz_glx_find_pbuffer_format (Display *display,
int screen,
@@ -401,6 +459,17 @@ glitz_glx_find_pbuffer_format (Display *display,
}
slim_hidden_def(glitz_glx_find_pbuffer_format);
+/**
+ * glitz_glx_find_drawable_format_for_visual:
+ * @display: an X Display
+ * @screen: X Screen number where the window will be displayed
+ * @visual_id: X Visual ID which is be used in matching drawable format
+ *
+ * This function return the drawable format for a X Visual ID.
+ *
+ * Return value: The format drawable which correspond to the Visual ID. If no
+ * format is found the function return nil.
+ **/
glitz_drawable_format_t *
glitz_glx_find_drawable_format_for_visual (Display *display,
int screen,
@@ -472,6 +541,17 @@ glitz_glx_find_drawable_format_for_visual (Display *display,
}
slim_hidden_def(glitz_glx_find_drawable_format_for_visual);
+/**
+ * glitz_glx_get_visual_info_from_format:
+ * @display: an X Display
+ * @screen: X Screen number where the window will be displayed
+ * @format: Drawable format which is be used in matching Visual
+ *
+ * This function return the X Visual Info corresponding to drawable format.
+ *
+ * Return value: The matching X Visual Info, the function return nil if no
+ * X Visual found.
+ **/
XVisualInfo *
glitz_glx_get_visual_info_from_format (Display *display,
int screen,
diff --git a/src/glx/glitz_glx_info.c b/src/glx/glitz_glx_info.c
index 928fd7b..05ce844 100644
--- a/src/glx/glitz_glx_info.c
+++ b/src/glx/glitz_glx_info.c
@@ -151,7 +151,11 @@ glitz_glx_get_proc_address (const char *name,
address = NULL;
}
}
-
+
+ if (!address) {
+ address = glXGetProcAddress ((glitz_gl_ubyte_t *) name);
+ }
+
return address;
}
@@ -236,7 +240,22 @@ _glitz_glx_proc_address_lookup (glitz_glx_screen_info_t *screen_info)
}
} else
screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_PBUFFER_MASK;
-
+
+ if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_TEXTURE_FROM_PIXMAP_MASK)
+ {
+ screen_info->glx.bind_tex_image = (glitz_glx_bind_tex_image_t)
+ glitz_glx_get_proc_address ("glXBindTexImageEXT",
+ (void *) screen_info);
+
+ screen_info->glx.release_tex_image = (glitz_glx_release_tex_image_t)
+ glitz_glx_get_proc_address ("glXReleaseTexImageEXT",
+ (void *) screen_info);
+
+ if (!screen_info->glx.bind_tex_image || !screen_info->glx.release_tex_image)
+ screen_info->glx_feature_mask &=
+ ~GLITZ_GLX_FEATURE_TEXTURE_FROM_PIXMAP_MASK;
+ }
+
if (screen_info->glx_feature_mask &
GLITZ_GLX_FEATURE_MAKE_CURRENT_READ_MASK) {
if (screen_info->glx_version >= 1.3f) {
@@ -521,15 +540,20 @@ glitz_glx_screen_info_get (Display *display,
screen_info->glx_feature_mask = 0;
if (glXQueryExtension (display, &error_base, &event_base)) {
- int major, minor;
-
- if (glXQueryVersion (display, &major, &minor)) {
- screen_info->glx_version = major + minor / 10.0f;
- if (major > 1 || (major > 0 || minor >= 2)) {
- glitz_glx_query_extensions (screen_info,
- screen_info->glx_version);
- _glitz_glx_proc_address_lookup (screen_info);
- glitz_glx_query_formats (screen_info);
+ const char* version = glXGetClientString(display, GLX_VERSION);
+ if (version) {
+ int major, minor;
+ char* dot = strstr (version, ".");
+ if (dot) {
+ minor = atoi(dot + 1);
+ major = atoi(version);
+ screen_info->glx_version = major + minor / 10.0f;
+ if (major > 1 || (major > 0 || minor >= 2)) {
+ glitz_glx_query_extensions (screen_info,
+ screen_info->glx_version);
+ _glitz_glx_proc_address_lookup (screen_info);
+ glitz_glx_query_formats (screen_info);
+ }
}
}
}
@@ -563,6 +587,18 @@ _glitz_glx_screen_destroy (glitz_glx_screen_info_t *screen_info)
free (screen_info);
}
+/**
+ * glitz_glx_init:
+ * @gl_library: OpenGL library file location.
+ *
+ * This function provide the possibility to use an alternate OpenGL library
+ * instead the system default. The call of this function is necessary only in
+ * this case, if you want to use the default OpenGL system library you can
+ * ignore it.
+ * This function must be called before any operations with glitz, generally in
+ * the beginning of the application. In more glitz_fini() must be called when
+ * all glitz operations are terminated.
+ **/
void
glitz_glx_init (const char *gl_library)
{
@@ -570,6 +606,12 @@ glitz_glx_init (const char *gl_library)
}
slim_hidden_def(glitz_glx_init);
+/**
+ * glitz_glx_fini:
+ *
+ * This function determine the end of use of specific opengl library specified
+ * with glitz_glx_init () or the end of use of system default library.
+ **/
void
glitz_glx_fini (void)
{
@@ -579,6 +621,16 @@ glitz_glx_fini (void)
}
slim_hidden_def(glitz_glx_fini);
+/**
+ * glitz_glx_set_render_type:
+ * @display: an X Display
+ * @screen: X Screen number which we want the rendering type.
+ * @direct: Indicate if we use direct (TRUE) or indirect (FALSE) rendering
+ *
+ * Specifies whether rendering is to be done with a direct connection to the
+ * graphics system if possible or through the X server.
+ * If this function is omitted glitz use by default the direct rendering.
+ **/
void
glitz_glx_set_render_type (Display *display,
int screen,
diff --git a/src/glx/glitz_glx_pixmap.c b/src/glx/glitz_glx_pixmap.c
new file mode 100644
index 0000000..ecbc7fe
--- /dev/null
+++ b/src/glx/glitz_glx_pixmap.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright © 2004 David Reveman
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * David Reveman not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior permission.
+ * David Reveman makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: David Reveman <davidr@novell.com>
+ * Nicolas Bruguier <nicolas.bruguier@supersonicimagine.fr>
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "../config.h"
+#endif
+
+#include "glitz_glxint.h"
+
+GLXPixmap
+glitz_glx_pixmap_create (glitz_glx_screen_info_t *screen_info,
+ Pixmap pixmap,
+ glitz_drawable_format_t *format,
+ unsigned int width,
+ unsigned int height)
+{
+ Display *dpy = screen_info->display_info->display;
+ glitz_glx_context_t* ctx;
+ GLXPixmap glx_pixmap;
+ glitz_int_drawable_format_t* iformat = &screen_info->formats[format->id];
+
+ if (!pixmap)
+ return (GLXPixmap) 0;
+
+ ctx = glitz_glx_context_get(screen_info, format);
+ if (ctx)
+ {
+ unsigned int target = 0;
+ int attribs[7];
+ int cpt = 0;
+
+ if ((iformat->texture_target & GLX_TEXTURE_2D_BIT_EXT) &&
+ ((ctx->backend.feature_mask & GLITZ_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK) ||
+ (POWER_OF_TWO (width) && POWER_OF_TWO (height))))
+ target = GLITZ_GL_TEXTURE_2D_EXT;
+ else if (iformat->texture_target & GLX_TEXTURE_RECTANGLE_BIT_EXT)
+ target = GLITZ_GL_TEXTURE_RECTANGLE_EXT;
+
+ if (!target)
+ {
+ if (!(iformat->texture_target & GLX_TEXTURE_2D_BIT_EXT))
+ target = GLITZ_GL_TEXTURE_RECTANGLE_EXT;
+ else if (!(iformat->texture_target & GLX_TEXTURE_RECTANGLE_BIT_EXT))
+ target = GLITZ_GL_TEXTURE_2D_EXT;
+ }
+
+ if (target)
+ {
+ attribs[cpt++] = GLITZ_GL_TEXTURE_TARGET_EXT;
+ attribs[cpt++] = target;
+ }
+ attribs[cpt++] = GLITZ_GL_TEXTURE_FORMAT_EXT;
+ attribs[cpt++] = iformat->texture_format;
+ attribs[cpt++] = GLITZ_GL_MIPMAP_TEXTURE_EXT,
+ attribs[cpt++] = iformat->mipmap;
+
+ attribs[cpt++] = 0;
+
+ glx_pixmap = glXCreatePixmap (dpy, ctx->fbconfig, pixmap, attribs);
+
+ return glx_pixmap;
+ } else
+ return (GLXPixmap) 0;
+}
+
+void
+glitz_glx_pixmap_destroy (glitz_glx_screen_info_t *screen_info,
+ GLXPixmap pixmap)
+{
+ Display *dpy = screen_info->display_info->display;
+
+ glXDestroyGLXPixmap (dpy, pixmap);
+}
diff --git a/src/glx/glitz_glxext.h b/src/glx/glitz_glxext.h
index 49a5f0d..312c0a9 100644
--- a/src/glx/glitz_glxext.h
+++ b/src/glx/glitz_glxext.h
@@ -114,6 +114,10 @@ typedef Bool (* glitz_glx_make_context_current_t)
typedef GLXContext (* glitz_glx_create_new_context_t)
(Display *display, GLXFBConfig config, int render_type,
GLXContext share_list, Bool direct);
+typedef void *(* glitz_glx_bind_tex_image_t)
+ (Display *display, GLXDrawable draw, int buffer, int *attribList);
+typedef void *(* glitz_glx_release_tex_image_t)
+ (Display *display, GLXDrawable draw, int buffer);
#ifndef GLX_ARB_multisample
#define GLX_SAMPLE_BUFFERS_ARB 0x186a0
diff --git a/src/glx/glitz_glxint.h b/src/glx/glitz_glxint.h
index 3f2240e..72fda88 100644
--- a/src/glx/glitz_glxint.h
+++ b/src/glx/glitz_glxint.h
@@ -44,6 +44,7 @@
#define GLITZ_GLX_FEATURE_MULTISAMPLE_MASK (1L << 5)
#define GLITZ_GLX_FEATURE_PBUFFER_MULTISAMPLE_MASK (1L << 6)
#define GLITZ_GLX_FEATURE_COPY_SUB_BUFFER_MASK (1L << 7)
+#define GLITZ_GLX_FEATURE_TEXTURE_FROM_PIXMAP_MASK (1L << 8)
typedef struct _glitz_glx_drawable glitz_glx_drawable_t;
typedef struct _glitz_glx_screen_info_t glitz_glx_screen_info_t;
@@ -60,6 +61,8 @@ typedef struct _glitz_glx_static_proc_address_list_t {
glitz_glx_make_context_current_t make_context_current;
glitz_glx_create_new_context_t create_new_context;
glitz_glx_copy_sub_buffer_t copy_sub_buffer;
+ glitz_glx_bind_tex_image_t bind_tex_image;
+ glitz_glx_release_tex_image_t release_tex_image;
} glitz_glx_static_proc_address_list_t;
typedef struct _glitz_glx_thread_info_t {
@@ -117,6 +120,8 @@ struct _glitz_glx_drawable {
glitz_glx_context_t *context;
GLXDrawable drawable;
GLXDrawable pbuffer;
+ GLXPixmap pixmap;
+ glitz_bool_t owned;
int width;
int height;
};
@@ -165,6 +170,12 @@ glitz_glx_create_pbuffer (void *abstract_templ,
unsigned int width,
unsigned int height);
+extern glitz_drawable_t __internal_linkage *
+glitz_glx_create_pixmap (void *abstract_templ,
+ glitz_drawable_format_t *format,
+ unsigned int width,
+ unsigned int height);
+
extern glitz_bool_t __internal_linkage
glitz_glx_push_current (void *abstract_drawable,
glitz_surface_t *surface,
@@ -194,6 +205,27 @@ glitz_glx_copy_sub_buffer (void *abstract_drawable,
int width,
int height);
+extern glitz_bool_t __internal_linkage
+glitz_glx_bind_tex_image (void *abstract_drawable);
+
+extern glitz_bool_t __internal_linkage
+glitz_glx_release_tex_image (void *abstract_drawable);
+
+extern void __internal_linkage
+glitz_glx_query_drawable (void *abstract_drawable, int query,
+ unsigned int* value);
+
+extern GLXPixmap __internal_linkage
+glitz_glx_pixmap_create (glitz_glx_screen_info_t *screen_info,
+ Pixmap pixmap,
+ glitz_drawable_format_t *format,
+ unsigned int width,
+ unsigned int height);
+
+extern void __internal_linkage
+glitz_glx_pixmap_destroy (glitz_glx_screen_info_t *screen_info,
+ GLXPixmap pixmap);
+
/* Avoid unnecessary PLT entries. */
slim_hidden_proto(glitz_glx_init)
@@ -204,6 +236,7 @@ slim_hidden_proto(glitz_glx_find_pbuffer_format)
slim_hidden_proto(glitz_glx_find_drawable_format_for_visual)
slim_hidden_proto(glitz_glx_get_visual_info_from_format)
slim_hidden_proto(glitz_glx_create_drawable_for_window)
+slim_hidden_proto(glitz_glx_create_drawable_for_pixmap)
slim_hidden_proto(glitz_glx_create_pbuffer_drawable)
#endif /* GLITZ_GLXINT_H_INCLUDED */
diff --git a/src/wgl/glitz_wgl_context.c b/src/wgl/glitz_wgl_context.c
index da0b44f..d89061d 100644
--- a/src/wgl/glitz_wgl_context.c
+++ b/src/wgl/glitz_wgl_context.c
@@ -180,6 +180,7 @@ glitz_wgl_context_get (glitz_wgl_screen_info_t *screen_info,
context->backend.gl = &_glitz_wgl_gl_proc_address;
context->backend.create_pbuffer = glitz_wgl_create_pbuffer;
+ context->backend.create_pixmap = NULL;
context->backend.destroy = glitz_wgl_destroy;
context->backend.push_current = glitz_wgl_push_current;
context->backend.pop_current = glitz_wgl_pop_current;
@@ -196,7 +197,12 @@ glitz_wgl_context_get (glitz_wgl_screen_info_t *screen_info,
context->backend.draw_buffer = _glitz_drawable_draw_buffer;
context->backend.read_buffer = _glitz_drawable_read_buffer;
-
+
+ context->backend.bind_tex_image = NULL;
+ context->backend.release_tex_image = NULL;
+
+ context->backend.query_drawable = NULL;
+
context->backend.drawable_formats = screen_info->formats;
context->backend.n_drawable_formats = screen_info->n_formats;
diff --git a/src/wgl/glitz_wgl_format.c b/src/wgl/glitz_wgl_format.c
index e15d992..dcc6ded 100644
--- a/src/wgl/glitz_wgl_format.c
+++ b/src/wgl/glitz_wgl_format.c
@@ -138,7 +138,8 @@ _glitz_wgl_query_formats (glitz_wgl_screen_info_t *screen_info)
format.d.id = 0;
format.caveat = 0;
format.types = 0;
-
+ format.d.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN;
+
if (!DescribePixelFormat (screen_info->root_dc, i,
sizeof (PIXELFORMATDESCRIPTOR), &pfd))
{
@@ -178,6 +179,7 @@ _glitz_wgl_query_formats (glitz_wgl_screen_info_t *screen_info)
format.d.color.fourcc = GLITZ_FOURCC_RGB;
format.d.depth_size = pfd.cDepthBits;
+ format.d.depth = format.d.depth_size;
format.d.stencil_size = pfd.cStencilBits;
format.d.doublebuffer = (pfd.dwFlags & PFD_DOUBLEBUFFER) != 0;
@@ -212,7 +214,8 @@ _glitz_wgl_query_formats_using_pixel_format (glitz_wgl_screen_info_t *screen_inf
format.d.id = 0;
format.types = 0;
format.d.color.fourcc = GLITZ_FOURCC_RGB;
-
+ format.d.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN;
+
#define ASK_QUESTION(q,a) (question=(q),wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1, &question,(a)))
if (!ASK_QUESTION(WGL_SUPPORT_OPENGL_ARB, &answer)
@@ -268,7 +271,8 @@ _glitz_wgl_query_formats_using_pixel_format (glitz_wgl_screen_info_t *screen_inf
if (!ASK_QUESTION(WGL_DEPTH_BITS_ARB, &answer))
continue;
format.d.depth_size = (unsigned short) answer;
-
+ format.d.depth = format.d.depth_size;
+
if (!ASK_QUESTION(WGL_STENCIL_BITS_ARB, &answer))
continue;
format.d.stencil_size = (unsigned short) answer;